summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSven Weidauer <sven@5sw.de>2017-12-23 10:55:59 +0100
committerSven Weidauer <sven@5sw.de>2017-12-23 10:55:59 +0100
commitcb452810b98273f1bf3275321386c8393d5c5134 (patch)
treeaf32263647bad0f8573c93fd9e426aeec2a57057
parentd0549e7a5b14959097a1e8696dce1b1f40c6ba54 (diff)
parent3c0ff81be45968e1c9d9b989243c975dfeab4cb0 (diff)
downloadnetsurf-cb452810b98273f1bf3275321386c8393d5c5134.tar.gz
netsurf-cb452810b98273f1bf3275321386c8393d5c5134.tar.bz2
Merge remote-tracking branch 'origin/master' into svenw/cocoa
-rw-r--r--!NetSurf/Resources/en/credits.html,faf2
-rw-r--r--!NetSurf/Resources/en/licence.html,faf18
-rw-r--r--!NetSurf/Resources/it/credits.html,faf2
-rw-r--r--!NetSurf/Resources/it/licence.html,faf14
-rw-r--r--!NetSurf/Resources/nl/credits.html,faf2
-rw-r--r--!NetSurf/Resources/nl/licence.html,faf14
-rw-r--r--.clang-format94
-rw-r--r--Makefile18
-rw-r--r--Makefile.defaults17
-rw-r--r--content/content.c83
-rw-r--r--content/content.h22
-rw-r--r--content/content_protected.h9
-rw-r--r--content/fetch.c85
-rw-r--r--content/fetchers/curl.c80
-rw-r--r--content/fetchers/data.c17
-rw-r--r--content/fetchers/resource.c6
-rw-r--r--content/fs_backing_store.c237
-rw-r--r--content/handlers/css/css.c32
-rw-r--r--content/handlers/css/dump.c7
-rw-r--r--content/handlers/css/hints.c4
-rw-r--r--content/handlers/css/select.c17
-rw-r--r--content/handlers/css/utils.h69
-rw-r--r--content/handlers/image/bmp.c13
-rw-r--r--content/handlers/image/gif.c17
-rw-r--r--content/handlers/image/ico.c19
-rw-r--r--content/handlers/image/image_cache.c125
-rw-r--r--content/handlers/image/jpeg.c6
-rw-r--r--content/handlers/image/nssprite.c27
-rw-r--r--content/handlers/image/png.c30
-rw-r--r--content/handlers/image/rsvg.c39
-rw-r--r--content/handlers/image/svg.c5
-rw-r--r--content/handlers/javascript/duktape/Console.bnd2
-rw-r--r--content/handlers/javascript/duktape/Document.bnd19
-rw-r--r--content/handlers/javascript/duktape/Element.bnd2
-rw-r--r--content/handlers/javascript/duktape/EventTarget.bnd3
-rw-r--r--content/handlers/javascript/duktape/Location.bnd8
-rw-r--r--content/handlers/javascript/duktape/Window.bnd7
-rw-r--r--content/handlers/javascript/duktape/duk_config.h165
-rw-r--r--content/handlers/javascript/duktape/dukky.c131
-rw-r--r--content/handlers/javascript/duktape/dukky.h4
-rw-r--r--content/handlers/javascript/duktape/duktape.c26480
-rw-r--r--content/handlers/javascript/duktape/duktape.h179
-rw-r--r--content/hlcache.c30
-rw-r--r--content/llcache.c164
-rw-r--r--content/urldb.c105
-rw-r--r--content/urldb.h10
-rw-r--r--desktop/browser.c113
-rw-r--r--desktop/browser_history.c255
-rw-r--r--desktop/browser_history.h26
-rw-r--r--desktop/browser_private.h17
-rw-r--r--desktop/cookie_manager.c19
-rw-r--r--desktop/font_haru.c24
-rw-r--r--desktop/frames.c6
-rw-r--r--desktop/global_history.c22
-rw-r--r--desktop/hotlist.c35
-rw-r--r--desktop/knockout.c8
-rw-r--r--desktop/local_history.c4
-rw-r--r--desktop/mouse.c2
-rw-r--r--desktop/netsurf.c30
-rw-r--r--desktop/options.h5
-rw-r--r--desktop/print.c6
-rw-r--r--desktop/save_complete.c26
-rw-r--r--desktop/save_pdf.c43
-rw-r--r--desktop/save_text.c8
-rw-r--r--desktop/searchweb.c20
-rw-r--r--desktop/sslcert_viewer.c8
-rw-r--r--desktop/textarea.c42
-rw-r--r--desktop/textarea.h10
-rw-r--r--desktop/treeview.c1274
-rw-r--r--desktop/treeview.h14
-rw-r--r--desktop/version.c4
-rw-r--r--docs/env.sh365
-rw-r--r--docs/logging.md90
-rw-r--r--docs/mainpage.md5
-rw-r--r--frontends/amiga/Makefile2
-rw-r--r--frontends/amiga/arexx.c2
-rw-r--r--frontends/amiga/bitmap.c23
-rw-r--r--frontends/amiga/cookies.c2
-rw-r--r--frontends/amiga/corewindow.c8
-rwxr-xr-xfrontends/amiga/dist/NetSurf.guide2
-rw-r--r--frontends/amiga/drag.c3
-rw-r--r--frontends/amiga/dt_anim.c16
-rw-r--r--frontends/amiga/dt_picture.c8
-rw-r--r--frontends/amiga/dt_sound.c17
-rw-r--r--frontends/amiga/filetype.c8
-rw-r--r--frontends/amiga/font.c14
-rw-r--r--frontends/amiga/font_bullet.c21
-rw-r--r--frontends/amiga/font_cache.c14
-rw-r--r--frontends/amiga/font_diskfont.c3
-rw-r--r--frontends/amiga/font_scan.c24
-rw-r--r--frontends/amiga/gui.c100
-rw-r--r--frontends/amiga/gui_menu.c3
-rwxr-xr-xfrontends/amiga/gui_options.c11
-rw-r--r--frontends/amiga/history.c2
-rw-r--r--frontends/amiga/history_local.c2
-rw-r--r--frontends/amiga/hotlist.c2
-rw-r--r--frontends/amiga/icon.c8
-rw-r--r--frontends/amiga/libs.c21
-rwxr-xr-xfrontends/amiga/memory.c73
-rw-r--r--frontends/amiga/menu.c4
-rwxr-xr-xfrontends/amiga/misc.c2
-rw-r--r--frontends/amiga/os3support.c21
-rw-r--r--frontends/amiga/plotters.c63
-rw-r--r--frontends/amiga/plugin_hack.c20
-rw-r--r--frontends/amiga/schedule.c19
-rw-r--r--frontends/amiga/selectmenu.c3
-rw-r--r--frontends/amiga/sslcert.c2
-rw-r--r--frontends/amiga/version.c2
-rw-r--r--frontends/atari/Makefile1
-rw-r--r--frontends/atari/bitmap.c32
-rw-r--r--frontends/atari/certview.c16
-rw-r--r--frontends/atari/cookies.c15
-rw-r--r--frontends/atari/ctxmenu.c7
-rw-r--r--frontends/atari/deskmenu.c66
-rw-r--r--frontends/atari/download.c14
-rw-r--r--frontends/atari/filetype.c4
-rw-r--r--frontends/atari/findfile.c18
-rw-r--r--frontends/atari/gui.c59
-rw-r--r--frontends/atari/history.c15
-rw-r--r--frontends/atari/hotlist.c21
-rw-r--r--frontends/atari/osspec.c6
-rw-r--r--frontends/atari/plot/font_freetype.c23
-rw-r--r--frontends/atari/plot/font_internal.c2
-rw-r--r--frontends/atari/plot/font_vdi.c2
-rw-r--r--frontends/atari/plot/plot.c5
-rw-r--r--frontends/atari/rootwin.c45
-rw-r--r--frontends/atari/schedule.c32
-rw-r--r--frontends/atari/search.c12
-rw-r--r--frontends/atari/settings.c34
-rw-r--r--frontends/atari/statusbar.c4
-rw-r--r--frontends/atari/toolbar.c15
-rw-r--r--frontends/atari/treeview.c6
-rw-r--r--frontends/atari/verify_ssl.c8
-rw-r--r--frontends/beos/bitmap.cpp7
-rw-r--r--frontends/beos/fetch_rsrc.cpp22
-rw-r--r--frontends/beos/font.cpp7
-rw-r--r--frontends/beos/gui.cpp39
-rw-r--r--frontends/beos/plotters.cpp4
-rw-r--r--frontends/beos/scaffolding.cpp16
-rw-r--r--frontends/beos/schedule.cpp27
-rw-r--r--frontends/beos/throbber.cpp18
-rw-r--r--frontends/beos/window.cpp28
-rw-r--r--frontends/framebuffer/bitmap.c21
-rw-r--r--frontends/framebuffer/clipboard.c4
-rw-r--r--frontends/framebuffer/fbtk.h6
-rw-r--r--frontends/framebuffer/fbtk/event.c4
-rw-r--r--frontends/framebuffer/fbtk/fbtk.c46
-rw-r--r--frontends/framebuffer/fbtk/scroll.c4
-rw-r--r--frontends/framebuffer/fbtk/text.c16
-rw-r--r--frontends/framebuffer/fetch.c2
-rw-r--r--frontends/framebuffer/font_freetype.c19
-rw-r--r--frontends/framebuffer/framebuffer.c15
-rw-r--r--frontends/framebuffer/gui.c42
-rw-r--r--frontends/framebuffer/schedule.c23
-rw-r--r--frontends/gtk/cookies.c7
-rw-r--r--frontends/gtk/corewindow.c14
-rw-r--r--frontends/gtk/download.c4
-rw-r--r--frontends/gtk/fetch.c3
-rw-r--r--frontends/gtk/gdk.c2
-rw-r--r--frontends/gtk/global_history.c7
-rw-r--r--frontends/gtk/gui.c80
-rw-r--r--frontends/gtk/hotlist.c7
-rw-r--r--frontends/gtk/layout_pango.c12
-rw-r--r--frontends/gtk/local_history.c2
-rw-r--r--frontends/gtk/login.c2
-rw-r--r--frontends/gtk/plotters.c4
-rw-r--r--frontends/gtk/preferences.c11
-rw-r--r--frontends/gtk/print.c28
-rw-r--r--frontends/gtk/res/options.gtk2.ui589
-rw-r--r--frontends/gtk/res/toolbar.gtk2.ui183
-rw-r--r--frontends/gtk/res/toolbar.gtk3.ui242
-rw-r--r--frontends/gtk/resources.c55
-rw-r--r--frontends/gtk/scaffolding.c41
-rw-r--r--frontends/gtk/schedule.c16
-rw-r--r--frontends/gtk/ssl_cert.c2
-rw-r--r--frontends/gtk/tabs.c8
-rw-r--r--frontends/gtk/throbber.c6
-rw-r--r--frontends/gtk/toolbar.c129
-rw-r--r--frontends/gtk/viewdata.c23
-rw-r--r--frontends/gtk/window.c29
-rw-r--r--frontends/monkey/browser.c2
-rw-r--r--frontends/monkey/dispatch.c2
-rw-r--r--frontends/monkey/filetype.c3
-rw-r--r--frontends/monkey/main.c11
-rw-r--r--frontends/monkey/schedule.c23
-rw-r--r--frontends/riscos/401login.c5
-rw-r--r--frontends/riscos/bitmap.c32
-rw-r--r--frontends/riscos/buffer.c36
-rw-r--r--frontends/riscos/configure.c32
-rw-r--r--frontends/riscos/configure/con_image.c5
-rw-r--r--frontends/riscos/configure/con_language.c6
-rw-r--r--frontends/riscos/configure/con_theme.c23
-rw-r--r--frontends/riscos/content-handlers/artworks.c46
-rw-r--r--frontends/riscos/content-handlers/draw.c8
-rw-r--r--frontends/riscos/content-handlers/sprite.c9
-rw-r--r--frontends/riscos/cookies.c4
-rw-r--r--frontends/riscos/corewindow.c97
-rw-r--r--frontends/riscos/dialog.c53
-rw-r--r--frontends/riscos/download.c152
-rw-r--r--frontends/riscos/filetype.c37
-rw-r--r--frontends/riscos/font.c75
-rw-r--r--frontends/riscos/global_history.c4
-rw-r--r--frontends/riscos/gui.c125
-rw-r--r--frontends/riscos/gui/button_bar.c30
-rw-r--r--frontends/riscos/gui/progress_bar.c18
-rw-r--r--frontends/riscos/gui/status_bar.c62
-rw-r--r--frontends/riscos/gui/throbber.c11
-rw-r--r--frontends/riscos/gui/url_bar.c48
-rw-r--r--frontends/riscos/help.c22
-rw-r--r--frontends/riscos/hotlist.c7
-rw-r--r--frontends/riscos/iconbar.c6
-rw-r--r--frontends/riscos/image.c20
-rw-r--r--frontends/riscos/local_history.c47
-rw-r--r--frontends/riscos/menus.c31
-rw-r--r--frontends/riscos/message.c8
-rw-r--r--frontends/riscos/mouse.c5
-rw-r--r--frontends/riscos/plotters.c104
-rw-r--r--frontends/riscos/print.c77
-rw-r--r--frontends/riscos/query.c21
-rw-r--r--frontends/riscos/save.c116
-rw-r--r--frontends/riscos/save_draw.c12
-rw-r--r--frontends/riscos/schedule.c2
-rw-r--r--frontends/riscos/sslcert.c36
-rw-r--r--frontends/riscos/textarea.c127
-rw-r--r--frontends/riscos/textselection.c40
-rw-r--r--frontends/riscos/theme.c55
-rw-r--r--frontends/riscos/theme_install.c5
-rw-r--r--frontends/riscos/toolbar.c48
-rw-r--r--frontends/riscos/ucstables.c7
-rw-r--r--frontends/riscos/uri.c6
-rw-r--r--frontends/riscos/url_complete.c66
-rw-r--r--frontends/riscos/url_protocol.c19
-rw-r--r--frontends/riscos/wimp.c135
-rw-r--r--frontends/riscos/wimp_event.c76
-rw-r--r--frontends/riscos/window.c193
-rw-r--r--frontends/windows/Makefile2
-rw-r--r--frontends/windows/about.c8
-rw-r--r--frontends/windows/bitmap.c34
-rw-r--r--frontends/windows/corewindow.c10
-rw-r--r--frontends/windows/download.c8
-rw-r--r--frontends/windows/drawable.c30
-rw-r--r--frontends/windows/filetype.c2
-rw-r--r--frontends/windows/findfile.c4
-rw-r--r--frontends/windows/font.c9
-rw-r--r--frontends/windows/gui.c4
-rw-r--r--frontends/windows/main.c16
-rw-r--r--frontends/windows/plot.c63
-rw-r--r--frontends/windows/prefs.c3
-rw-r--r--frontends/windows/schedule.c38
-rw-r--r--frontends/windows/ssl_cert.c11
-rw-r--r--frontends/windows/windbg.h14
-rw-r--r--frontends/windows/window.c113
-rw-r--r--include/netsurf/bitmap.h2
-rw-r--r--include/netsurf/browser_window.h5
-rw-r--r--include/netsurf/url_db.h9
-rw-r--r--render/box.c4
-rw-r--r--render/box_construct.c29
-rw-r--r--render/box_normalise.c27
-rw-r--r--render/box_textarea.c4
-rw-r--r--render/form.c142
-rw-r--r--render/html.c82
-rw-r--r--render/html_css.c43
-rw-r--r--render/html_css_fetcher.c11
-rw-r--r--render/html_interaction.c36
-rw-r--r--render/html_object.c35
-rw-r--r--render/html_script.c98
-rw-r--r--render/imagemap.c24
-rw-r--r--render/layout.c261
-rw-r--r--render/search.c4
-rw-r--r--render/table.c59
-rw-r--r--render/textplain.c16
-rw-r--r--resources/FatMessages209
-rw-r--r--test/Makefile2
-rw-r--r--test/data/Choices-all2
-rw-r--r--test/log.c12
-rw-r--r--test/messages.c1
-rw-r--r--test/nsoption.c3
-rw-r--r--test/urldbtest.c38
-rw-r--r--utils/errors.h75
-rw-r--r--utils/filename.c32
-rw-r--r--utils/hashtable.c10
-rw-r--r--utils/idna.c38
-rwxr-xr-xutils/jenkins-build.sh22
-rw-r--r--utils/log.c284
-rw-r--r--utils/log.h68
-rw-r--r--utils/messages.c89
-rw-r--r--utils/nsoption.c17
-rw-r--r--utils/nsurl/nsurl.c6
-rw-r--r--utils/nsurl/parse.c27
-rw-r--r--utils/nsurl/private.h32
-rw-r--r--utils/useragent.c3
-rw-r--r--utils/utf8.c5
292 files changed, 21560 insertions, 16708 deletions
diff --git a/!NetSurf/Resources/en/credits.html,faf b/!NetSurf/Resources/en/credits.html,faf
index b7098df44..7789bcdea 100644
--- a/!NetSurf/Resources/en/credits.html,faf
+++ b/!NetSurf/Resources/en/credits.html,faf
@@ -92,7 +92,7 @@ div#DevList ul {
</div>
<div class="footer">
-<p>Copyright 2003&ndash;2016 The NetSurf Developers</p>
+<p>Copyright 2003&ndash;2017 The NetSurf Developers</p>
</div>
</body>
diff --git a/!NetSurf/Resources/en/licence.html,faf b/!NetSurf/Resources/en/licence.html,faf
index da0df454e..515757cd7 100644
--- a/!NetSurf/Resources/en/licence.html,faf
+++ b/!NetSurf/Resources/en/licence.html,faf
@@ -60,25 +60,25 @@ version.</p>
<dl class="components">
<dt><a href="http://www.netsurf-browser.org/">NetSurf</a></dt>
<dd>
-<span>&copy; 2002&ndash;2016 The NetSurf Developers</span>
+<span>&copy; 2002&ndash;2017 The NetSurf Developers</span>
<span><a href="#gplv2">GPLv2</a></span>
</dd>
<dt><a href="http://www.netsurf-browser.org/projects/libcss/">LibCSS</a></dt>
<dd>
-<span>&copy; 2007&ndash;2016 John-Mark Bell</span>
+<span>&copy; 2007&ndash;2017 John-Mark Bell</span>
<span><a href="#mit">MIT</a></span>
</dd>
<dt><a href="http://www.netsurf-browser.org/projects/hubbub/">Hubbub</a></dt>
<dd>
-<span>&copy; 2007&ndash;2016 John-Mark Bell<br>&copy; 2008&ndash;2009 Andrew Sidwell</span>
+<span>&copy; 2007&ndash;2017 John-Mark Bell<br>&copy; 2008&ndash;2009 Andrew Sidwell</span>
<span><a href="#mit">MIT</a></span>
</dd>
<dt><a href="http://www.netsurf-browser.org/projects/libparserutils/">LibParserUtils</a></dt>
<dd>
-<span>&copy; 2007&ndash;2016 John-Mark Bell</span>
+<span>&copy; 2007&ndash;2017 John-Mark Bell</span>
<span><a href="#mit">MIT</a></span>
</dd>
@@ -102,19 +102,19 @@ version.</p>
<dt><a href="http://www.netsurf-browser.org/projects/libsvgtiny">Libsvgtiny</a></dt>
<dd>
-<span>&copy; 2008&ndash;2009 James Bursa<br>&copy; 2016 Michael Drake</span>
+<span>&copy; 2008&ndash;2009 James Bursa<br>&copy; 2017 Michael Drake</span>
<span><a href="#mit">MIT</a></span>
</dd>
<dt><a href="http://www.netsurf-browser.org/projects/libnsbmp/">Libnsbmp</a></dt>
<dd>
-<span>&copy; 2006 Richard Wilson<br>&copy; 2008 Sean Fox<br>&copy; 2016 Vincent Sanders</span>
+<span>&copy; 2006 Richard Wilson<br>&copy; 2008 Sean Fox<br>&copy; 2017 Vincent Sanders</span>
<span><a href="#mit">MIT</a></span>
</dd>
<dt><a href="http://www.netsurf-browser.org/projects/libnsfb/">Libnsfb</a></dt>
<dd>
-<span>&copy; 2009&ndash;2016 Vincent Sanders<br>&copy; 2009&ndash;2016 Michael Drake</span>
+<span>&copy; 2009&ndash;2017 Vincent Sanders<br>&copy; 2009&ndash;2017 Michael Drake</span>
<span><a href="#mit">MIT</a></span>
</dd>
@@ -126,7 +126,7 @@ version.</p>
<dt><a href="http://www.netsurf-browser.org/projects/libwapcaplet">LibWapcaplet</a></dt>
<dd>
-<span>&copy; 2009&ndash;2016 NetSurf Browser Project, Daniel Silverstone</span>
+<span>&copy; 2009&ndash;2017 NetSurf Browser Project, Daniel Silverstone</span>
<span><a href="#mit">MIT</a></span>
</dd>
</dl>
@@ -1865,7 +1865,7 @@ PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
</div>
<div class="footer">
-<p>Copyright 2003&ndash;2016 The NetSurf Developers</p>
+<p>Copyright 2003&ndash;2017 The NetSurf Developers</p>
</div>
</body>
diff --git a/!NetSurf/Resources/it/credits.html,faf b/!NetSurf/Resources/it/credits.html,faf
index fe654439e..cec1912a6 100644
--- a/!NetSurf/Resources/it/credits.html,faf
+++ b/!NetSurf/Resources/it/credits.html,faf
@@ -91,7 +91,7 @@ div#DevList ul {
</div>
<div class="footer">
-<p><br>Copyright 2003&ndash;2013 The NetSurf Developers</p>
+<p><br>Copyright 2003&ndash;2017 The NetSurf Developers</p>
</div>
</body>
diff --git a/!NetSurf/Resources/it/licence.html,faf b/!NetSurf/Resources/it/licence.html,faf
index b0a6c8ae3..8b9c4891f 100644
--- a/!NetSurf/Resources/it/licence.html,faf
+++ b/!NetSurf/Resources/it/licence.html,faf
@@ -52,25 +52,25 @@ dl.components > dd > span + span {
<dl class="components">
<dt><a href="http://www.netsurf-browser.org/">NetSurf</a></dt>
<dd>
-<span>&copy; 2002&ndash;2013 The NetSurf Developers</span>
+<span>&copy; 2002&ndash;2017 The NetSurf Developers</span>
<span><a href="#gplv2">GPLv2</a></span>
</dd>
<dt><a href="http://www.netsurf-browser.org/projects/libcss/">LibCSS</a></dt>
<dd>
-<span>&copy; 2007&ndash;2013 John-Mark Bell</span>
+<span>&copy; 2007&ndash;2017 John-Mark Bell</span>
<span><a href="#mit">MIT</a></span>
</dd>
<dt><a href="http://www.netsurf-browser.org/projects/hubbub/">Hubbub</a></dt>
<dd>
-<span>&copy; 2007&ndash;2013 John-Mark Bell<br>&copy; 2008&ndash;2009 Andrew Sidwell</span>
+<span>&copy; 2007&ndash;2017 John-Mark Bell<br>&copy; 2008&ndash;2009 Andrew Sidwell</span>
<span><a href="#mit">MIT</a></span>
</dd>
<dt><a href="http://www.netsurf-browser.org/projects/libparserutils/">LibParserUtils</a></dt>
<dd>
-<span>&copy; 2007&ndash;2013 John-Mark Bell</span>
+<span>&copy; 2007&ndash;2017 John-Mark Bell</span>
<span><a href="#mit">MIT</a></span>
</dd>
@@ -106,7 +106,7 @@ dl.components > dd > span + span {
<dt><a href="http://www.netsurf-browser.org/projects/libnsfb/">Libnsfb</a></dt>
<dd>
-<span>&copy; 2009&ndash;2013 Vincent Sanders<br>&copy; 2009&ndash;2013 Michael Drake</span>
+<span>&copy; 2009&ndash;2017 Vincent Sanders<br>&copy; 2009&ndash;2017 Michael Drake</span>
<span><a href="#mit">MIT</a></span>
</dd>
@@ -118,7 +118,7 @@ dl.components > dd > span + span {
<dt><a href="http://www.netsurf-browser.org/projects/libwapcaplet">LibWapcaplet</a></dt>
<dd>
-<span>&copy; 2009&ndash;2013 NetSurf Browser Project, Daniel Silverstone</span>
+<span>&copy; 2009&ndash;2017 NetSurf Browser Project, Daniel Silverstone</span>
<span><a href="#mit">MIT</a></span>
</dd>
</dl>
@@ -1853,7 +1853,7 @@ PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
</div>
<div class="footer">
-<p>Copyright 2003&ndash;2013 The NetSurf Developers</p>
+<p>Copyright 2003&ndash;2017 The NetSurf Developers</p>
</div>
</body>
diff --git a/!NetSurf/Resources/nl/credits.html,faf b/!NetSurf/Resources/nl/credits.html,faf
index 3cae27a54..f9e0932c5 100644
--- a/!NetSurf/Resources/nl/credits.html,faf
+++ b/!NetSurf/Resources/nl/credits.html,faf
@@ -96,7 +96,7 @@ div#DevList ul {
</div>
<div class="footer">
-<p>Auteursrecht 2003&ndash;2016 De NetSurf-ontwikkelaars</p>
+<p>Auteursrecht 2003&ndash;2017 De NetSurf-ontwikkelaars</p>
</div>
</body>
diff --git a/!NetSurf/Resources/nl/licence.html,faf b/!NetSurf/Resources/nl/licence.html,faf
index d3272c75c..89ce8564e 100644
--- a/!NetSurf/Resources/nl/licence.html,faf
+++ b/!NetSurf/Resources/nl/licence.html,faf
@@ -63,25 +63,25 @@ dan verwijder deze uitzonderingverklaring uit uw eigen versie.</p>
<dl class="components">
<dt><a href="http://www.netsurf-browser.org/">NetSurf</a></dt>
<dd>
-<span>&copy; 2002&ndash;2016 De NetSurf-ontwikkerlaars</span>
+<span>&copy; 2002&ndash;2017 De NetSurf-ontwikkerlaars</span>
<span><a href="#gplv2">GPLv2</a></span>
</dd>
<dt><a href="http://www.netsurf-browser.org/projects/libcss/">LibCSS</a></dt>
<dd>
-<span>&copy; 2007&ndash;2016 John-Mark Bell</span>
+<span>&copy; 2007&ndash;2017 John-Mark Bell</span>
<span><a href="#mit">MIT</a></span>
</dd>
<dt><a href="http://www.netsurf-browser.org/projects/hubbub/">Hubbub</a></dt>
<dd>
-<span>&copy; 2007&ndash;2016 John-Mark Bell<br>&copy; 2008&ndash;2009 Andrew Sidwell</span>
+<span>&copy; 2007&ndash;2017 John-Mark Bell<br>&copy; 2008&ndash;2009 Andrew Sidwell</span>
<span><a href="#mit">MIT</a></span>
</dd>
<dt><a href="http://www.netsurf-browser.org/projects/libparserutils/">LibParserUtils</a></dt>
<dd>
-<span>&copy; 2007&ndash;2016 John-Mark Bell</span>
+<span>&copy; 2007&ndash;2017 John-Mark Bell</span>
<span><a href="#mit">MIT</a></span>
</dd>
@@ -117,7 +117,7 @@ dan verwijder deze uitzonderingverklaring uit uw eigen versie.</p>
<dt><a href="http://www.netsurf-browser.org/projects/libnsfb/">Libnsfb</a></dt>
<dd>
-<span>&copy; 2009&ndash;2016 Vincent Sanders<br>&copy; 2009&ndash;2016 Michael Drake</span>
+<span>&copy; 2009&ndash;2017 Vincent Sanders<br>&copy; 2009&ndash;2017 Michael Drake</span>
<span><a href="#mit">MIT</a></span>
</dd>
@@ -129,7 +129,7 @@ dan verwijder deze uitzonderingverklaring uit uw eigen versie.</p>
<dt><a href="http://www.netsurf-browser.org/projects/libwapcaplet">LibWapcaplet</a></dt>
<dd>
-<span>&copy; 2009&ndash;2016 NetSurf Browser Project, Daniel Silverstone</span>
+<span>&copy; 2009&ndash;2017 NetSurf Browser Project, Daniel Silverstone</span>
<span><a href="#mit">MIT</a></span>
</dd>
</dl>
@@ -1872,7 +1872,7 @@ PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
</div>
<div class="footer">
-<p>Auteursrecht 2003&ndash;2016 De NetSurf-ontwikkelaars</p>
+<p>Auteursrecht 2003&ndash;2017 De NetSurf-ontwikkelaars</p>
</div>
</body>
diff --git a/.clang-format b/.clang-format
new file mode 100644
index 000000000..3cee69bd9
--- /dev/null
+++ b/.clang-format
@@ -0,0 +1,94 @@
+---
+Language: Cpp
+# BasedOnStyle: LLVM
+AccessModifierOffset: -2
+AlignAfterOpenBracket: Align
+AlignConsecutiveAssignments: false
+AlignConsecutiveDeclarations: false
+AlignEscapedNewlinesLeft: false
+AlignOperands: true
+AlignTrailingComments: true
+AllowAllParametersOfDeclarationOnNextLine: true
+AllowShortBlocksOnASingleLine: false
+AllowShortCaseLabelsOnASingleLine: false
+AllowShortFunctionsOnASingleLine: None
+AllowShortIfStatementsOnASingleLine: false
+AllowShortLoopsOnASingleLine: false
+AlwaysBreakAfterDefinitionReturnType: None
+AlwaysBreakAfterReturnType: All
+AlwaysBreakBeforeMultilineStrings: false
+AlwaysBreakTemplateDeclarations: false
+BinPackArguments: false
+BinPackParameters: false
+BraceWrapping:
+ AfterClass: false
+ AfterControlStatement: false
+ AfterEnum: true
+ AfterFunction: false
+ AfterNamespace: false
+ AfterObjCDeclaration: false
+ AfterStruct: false
+ AfterUnion: false
+ BeforeCatch: false
+ BeforeElse: false
+ IndentBraces: false
+BreakBeforeBinaryOperators: None
+BreakBeforeBraces: Linux
+BreakBeforeTernaryOperators: true
+BreakConstructorInitializersBeforeComma: false
+ColumnLimit: 80
+CommentPragmas: '^ IWYU pragma:'
+ConstructorInitializerAllOnOneLineOrOnePerLine: false
+ConstructorInitializerIndentWidth: 8
+ContinuationIndentWidth: 8
+Cpp11BracedListStyle: true
+DerivePointerAlignment: false
+DisableFormat: false
+ExperimentalAutoDetectBinPacking: false
+ForEachMacros: [ foreach, Q_FOREACH, BOOST_FOREACH ]
+IncludeCategories:
+ - Regex: '^(<.*/)'
+ Priority: 3
+ - Regex: '^(<(nsutils)/)'
+ Priority: 2
+ - Regex: '"utils/'
+ Priority: 4
+ - Regex: '"netsurf/'
+ Priority: 5
+ - Regex: '.*'
+ Priority: 6
+IndentCaseLabels: false
+IndentWidth: 8
+IndentWrappedFunctionNames: false
+KeepEmptyLinesAtTheStartOfBlocks: true
+MacroBlockBegin: ''
+MacroBlockEnd: ''
+MaxEmptyLinesToKeep: 1
+NamespaceIndentation: None
+ObjCBlockIndentWidth: 2
+ObjCSpaceAfterProperty: false
+ObjCSpaceBeforeProtocolList: true
+PenaltyBreakBeforeFirstCallParameter: 19
+PenaltyBreakComment: 300
+PenaltyBreakFirstLessLess: 120
+PenaltyBreakString: 1000
+PenaltyExcessCharacter: 1000000
+PenaltyReturnTypeOnItsOwnLine: 60
+PointerAlignment: Right
+ReflowComments: true
+SortIncludes: false
+SpaceAfterCStyleCast: false
+SpaceBeforeAssignmentOperators: true
+SpaceBeforeParens: ControlStatements
+SpaceInEmptyParentheses: false
+SpacesBeforeTrailingComments: 1
+SpacesInAngles: false
+SpacesInContainerLiterals: true
+SpacesInCStyleCastParentheses: false
+SpacesInParentheses: false
+SpacesInSquareBrackets: false
+Standard: Cpp11
+TabWidth: 8
+UseTab: Always
+...
+
diff --git a/Makefile b/Makefile
index fa1420b23..bd0f68899 100644
--- a/Makefile
+++ b/Makefile
@@ -516,9 +516,12 @@ CXXWARNFLAGS :=
# C default warning flags
CWARNFLAGS := -Wstrict-prototypes -Wmissing-prototypes -Wnested-externs
-# Pull in the configuration
+# Pull in the default configuration
include Makefile.defaults
+# Pull in the user configuration
+-include Makefile.config
+
# libraries enabled by feature switch without pkgconfig file
$(eval $(call feature_switch,JPEG,JPEG (libjpeg),-DWITH_JPEG,-ljpeg,-UWITH_JPEG,))
$(eval $(call feature_switch,HARU_PDF,PDF export (haru),-DWITH_PDF_EXPORT,-lhpdf -lpng,-UWITH_PDF_EXPORT,))
@@ -545,6 +548,7 @@ NETSURF_FEATURE_NSSVG_CFLAGS := -DWITH_NS_SVG
NETSURF_FEATURE_OPENSSL_CFLAGS := -DWITH_OPENSSL
NETSURF_FEATURE_ROSPRITE_CFLAGS := -DWITH_NSSPRITE
NETSURF_FEATURE_NSPSL_CFLAGS := -DWITH_NSPSL
+NETSURF_FEATURE_NSLOG_CFLAGS := -DWITH_NSLOG
# libcurl and openssl ordering matters as if libcurl requires ssl it
# needs to come first in link order to ensure its symbols can be
@@ -565,6 +569,7 @@ $(eval $(call pkg_config_find_and_add_enabled,GIF,libnsgif,GIF))
$(eval $(call pkg_config_find_and_add_enabled,NSSVG,libsvgtiny,SVG))
$(eval $(call pkg_config_find_and_add_enabled,ROSPRITE,librosprite,Sprite))
$(eval $(call pkg_config_find_and_add_enabled,NSPSL,libnspsl,PSL))
+$(eval $(call pkg_config_find_and_add_enabled,NSLOG,libnslog,LOG))
# List of directories in which headers are searched for
INCLUDE_DIRS :=. include $(OBJROOT)
@@ -577,6 +582,17 @@ CXXFLAGS += -DNETSURF_UA_FORMAT_STRING=\"$(NETSURF_UA_FORMAT_STRING)\"
CFLAGS += -DNETSURF_HOMEPAGE=\"$(NETSURF_HOMEPAGE)\"
CXXFLAGS += -DNETSURF_HOMEPAGE=\"$(NETSURF_HOMEPAGE)\"
+# set the logging level
+CFLAGS += -DNETSURF_LOG_LEVEL=$(NETSURF_LOG_LEVEL)
+CXXFLAGS += -DNETSURF_LOG_LEVEL=$(NETSURF_LOG_LEVEL)
+
+# and the logging filter
+CFLAGS += -DNETSURF_BUILTIN_LOG_FILTER=\"$(NETSURF_BUILTIN_LOG_FILTER)\"
+CXXFLAGS += -DNETSURF_BUILTIN_LOG_FILTER=\"$(NETSURF_BUILTIN_LOG_FILTER)\"
+# and the verbose logging filter
+CFLAGS += -DNETSURF_BUILTIN_VERBOSE_FILTER=\"$(NETSURF_BUILTIN_VERBOSE_FILTER)\"
+CXXFLAGS += -DNETSURF_BUILTIN_VERBOSE_FILTER=\"$(NETSURF_BUILTIN_VERBOSE_FILTER)\"
+
# ----------------------------------------------------------------------------
# General make rules
# ----------------------------------------------------------------------------
diff --git a/Makefile.defaults b/Makefile.defaults
index 619b8db08..1f9ce5fdf 100644
--- a/Makefile.defaults
+++ b/Makefile.defaults
@@ -70,8 +70,21 @@ NETSURF_USE_DUKTAPE := YES
NETSURF_USE_HARU_PDF := NO
# Enable the use of the Public suffix library to detect supercookies
+# Valid options: YES, NO, AUTO (highly recommended)
NETSURF_USE_NSPSL := AUTO
+# Enable use of filtered logging library
+# Valid options: YES, NO, AUTO (highly recommended)
+NETSURF_USE_NSLOG := AUTO
+# The minimum logging level *compiled* into netsurf
+# Valid options are: DEEPDEBUG, DEBUG, VERBOSE, INFO, WARNING, ERROR, CRITICAL
+NETSURF_LOG_LEVEL := INFO
+# The log filter set during log initialisation before options are available
+NETSURF_BUILTIN_LOG_FILTER := level:WARNING
+# The log filter set during log initialisation before options are available
+# if the logging level is set to verbose
+NETSURF_BUILTIN_VERBOSE_FILTER := level:VERBOSE
+
# Enable stripping the NetSurf binary
# Valid options: YES, NO
NETSURF_STRIP_BINARY := NO
@@ -136,11 +149,9 @@ endif
# ----------------------------------------------------------------------------
-# Include any local configuration
+# Detect double inclusion
# ----------------------------------------------------------------------------
ifneq ($(MAKEFILE_DEFAULTS_FINISHED),)
$(error Makefile.defaults has been double-included. If you did something utterly brain-dead such as copying Makefile.defaults to Makefile.config then you deserve all the pain you can imagine. Do NOT do that. Why not read the comments at the top of Makefile.defaults. They are there to help you, you numpty)
endif
MAKEFILE_DEFAULTS_FINISHED=yes
--include Makefile.config
-
diff --git a/content/content.c b/content/content.c
index 7a8bb013f..9a240417d 100644
--- a/content/content.c
+++ b/content/content.c
@@ -73,7 +73,8 @@ nserror content__init(struct content *c, const content_handler *handler,
struct content_user *user_sentinel;
nserror error;
- LOG("url "URL_FMT_SPC" -> %p", nsurl_access(llcache_handle_get_url(llcache)), c);
+ NSLOG(netsurf, INFO, "url "URL_FMT_SPC" -> %p",
+ nsurl_access(llcache_handle_get_url(llcache)), c);
user_sentinel = calloc(1, sizeof(struct content_user));
if (user_sentinel == NULL) {
@@ -163,7 +164,7 @@ nserror content_llcache_callback(llcache_handle *llcache,
content_set_status(c, messages_get("Processing"));
msg_data.explicit_status_text = NULL;
- content_broadcast(c, CONTENT_MSG_STATUS, msg_data);
+ content_broadcast(c, CONTENT_MSG_STATUS, &msg_data);
content_convert(c);
}
@@ -172,17 +173,17 @@ nserror content_llcache_callback(llcache_handle *llcache,
/** \todo Error page? */
c->status = CONTENT_STATUS_ERROR;
msg_data.error = event->data.msg;
- content_broadcast(c, CONTENT_MSG_ERROR, msg_data);
+ content_broadcast(c, CONTENT_MSG_ERROR, &msg_data);
break;
case LLCACHE_EVENT_PROGRESS:
content_set_status(c, event->data.msg);
msg_data.explicit_status_text = NULL;
- content_broadcast(c, CONTENT_MSG_STATUS, msg_data);
+ content_broadcast(c, CONTENT_MSG_STATUS, &msg_data);
break;
case LLCACHE_EVENT_REDIRECT:
msg_data.redirect.from = event->data.redirect.from;
msg_data.redirect.to = event->data.redirect.to;
- content_broadcast(c, CONTENT_MSG_REDIRECT, msg_data);
+ content_broadcast(c, CONTENT_MSG_REDIRECT, &msg_data);
break;
}
@@ -272,7 +273,8 @@ void content_convert(struct content *c)
if (c->locked == true)
return;
- LOG("content "URL_FMT_SPC" (%p)", nsurl_access(llcache_handle_get_url(c->llcache)), c);
+ NSLOG(netsurf, INFO, "content "URL_FMT_SPC" (%p)",
+ nsurl_access(llcache_handle_get_url(c->llcache)), c);
if (c->handler->data_complete != NULL) {
c->locked = true;
@@ -292,8 +294,6 @@ void content_convert(struct content *c)
void content_set_ready(struct content *c)
{
- union content_msg_data msg_data;
-
/* The content must be locked at this point, as it can only
* become READY after conversion. */
assert(c->locked);
@@ -301,7 +301,7 @@ void content_set_ready(struct content *c)
c->status = CONTENT_STATUS_READY;
content_update_status(c);
- content_broadcast(c, CONTENT_MSG_READY, msg_data);
+ content_broadcast(c, CONTENT_MSG_READY, NULL);
}
/**
@@ -310,7 +310,6 @@ void content_set_ready(struct content *c)
void content_set_done(struct content *c)
{
- union content_msg_data msg_data;
uint64_t now_ms;
nsu_getmonotonic_ms(&now_ms);
@@ -318,7 +317,7 @@ void content_set_done(struct content *c)
c->status = CONTENT_STATUS_DONE;
c->time = now_ms - c->time;
content_update_status(c);
- content_broadcast(c, CONTENT_MSG_DONE, msg_data);
+ content_broadcast(c, CONTENT_MSG_DONE, NULL);
}
/**
@@ -363,7 +362,7 @@ void content__reformat(struct content *c, bool background,
c->locked = false;
data.background = background;
- content_broadcast(c, CONTENT_MSG_REFORMAT, data);
+ content_broadcast(c, CONTENT_MSG_REFORMAT, &data);
}
}
@@ -379,7 +378,8 @@ void content_destroy(struct content *c)
struct content_rfc5988_link *link;
assert(c);
- LOG("content %p %s", c, nsurl_access(llcache_handle_get_url(c->llcache)));
+ NSLOG(netsurf, INFO, "content %p %s", c,
+ nsurl_access(llcache_handle_get_url(c->llcache)));
assert(c->locked == false);
if (c->handler->destroy != NULL)
@@ -436,7 +436,7 @@ void content_mouse_track(hlcache_handle *h, struct browser_window *bw,
} else {
union content_msg_data msg_data;
msg_data.pointer = BROWSER_POINTER_AUTO;
- content_broadcast(c, CONTENT_MSG_POINTER, msg_data);
+ content_broadcast(c, CONTENT_MSG_POINTER, &msg_data);
}
@@ -540,7 +540,7 @@ void content__request_redraw(struct content *c,
data.redraw.object_width = c->width;
data.redraw.object_height = c->height;
- content_broadcast(c, CONTENT_MSG_REDRAW, data);
+ content_broadcast(c, CONTENT_MSG_REDRAW, &data);
}
@@ -588,7 +588,7 @@ bool content_scaled_redraw(struct hlcache_handle *h,
return true;
}
- LOG("Content %p %dx%d ctx:%p", c, width, height, ctx);
+ NSLOG(netsurf, INFO, "Content %p %dx%d ctx:%p", c, width, height, ctx);
if (ctx->plot->option_knockout) {
knockout_plot_start(ctx, &new_ctx);
@@ -646,14 +646,20 @@ bool content_scaled_redraw(struct hlcache_handle *h,
* called with the content.
*/
-bool content_add_user(struct content *c,
- void (*callback)(struct content *c, content_msg msg,
- union content_msg_data data, void *pw),
+bool content_add_user(
+ struct content *c,
+ void (*callback)(
+ struct content *c,
+ content_msg msg,
+ const union content_msg_data *data,
+ void *pw),
void *pw)
{
struct content_user *user;
- LOG("content "URL_FMT_SPC" (%p), user %p %p", nsurl_access(llcache_handle_get_url(c->llcache)), c, callback, pw);
+ NSLOG(netsurf, INFO, "content "URL_FMT_SPC" (%p), user %p %p",
+ nsurl_access(llcache_handle_get_url(c->llcache)), c, callback,
+ pw);
user = malloc(sizeof(struct content_user));
if (!user)
return false;
@@ -676,13 +682,19 @@ bool content_add_user(struct content *c,
* content_add_user().
*/
-void content_remove_user(struct content *c,
- void (*callback)(struct content *c, content_msg msg,
- union content_msg_data data, void *pw),
+void content_remove_user(
+ struct content *c,
+ void (*callback)(
+ struct content *c,
+ content_msg msg,
+ const union content_msg_data *data,
+ void *pw),
void *pw)
{
struct content_user *user, *next;
- LOG("content "URL_FMT_SPC" (%p), user %p %p", nsurl_access(llcache_handle_get_url(c->llcache)), c, callback, pw);
+ NSLOG(netsurf, INFO, "content "URL_FMT_SPC" (%p), user %p %p",
+ nsurl_access(llcache_handle_get_url(c->llcache)), c, callback,
+ pw);
/* user_list starts with a sentinel */
for (user = c->user_list; user->next != 0 &&
@@ -690,7 +702,7 @@ void content_remove_user(struct content *c,
user->next->pw == pw); user = user->next)
;
if (user->next == 0) {
- LOG("user not found in list");
+ NSLOG(netsurf, INFO, "user not found in list");
assert(0);
return;
}
@@ -753,11 +765,12 @@ bool content_is_shareable(struct content *c)
*/
void content_broadcast(struct content *c, content_msg msg,
- union content_msg_data data)
+ const union content_msg_data *data)
{
struct content_user *user, *next;
assert(c);
-// LOG("%p -> msg:%d", c, msg);
+
+ NSLOG(netsurf, DEEPDEBUG, "%p -> msg:%d", c, msg);
for (user = c->user_list->next; user != 0; user = next) {
next = user->next; /* user may be destroyed during callback */
if (user->callback != 0)
@@ -777,8 +790,10 @@ void content_broadcast_errorcode(struct content *c, nserror errorcode)
for (user = c->user_list->next; user != 0; user = next) {
next = user->next; /* user may be destroyed during callback */
- if (user->callback != 0)
- user->callback(c, CONTENT_MSG_ERRORCODE, data, user->pw);
+ if (user->callback != 0) {
+ user->callback(c, CONTENT_MSG_ERRORCODE,
+ &data, user->pw);
+ }
}
}
@@ -800,7 +815,8 @@ void content_open(hlcache_handle *h, struct browser_window *bw,
{
struct content *c = hlcache_handle_get_content(h);
assert(c != 0);
- LOG("content %p %s", c, nsurl_access(llcache_handle_get_url(c->llcache)));
+ NSLOG(netsurf, INFO, "content %p %s", c,
+ nsurl_access(llcache_handle_get_url(c->llcache)));
if (c->handler->open != NULL)
c->handler->open(c, bw, page, params);
}
@@ -816,7 +832,8 @@ void content_close(hlcache_handle *h)
{
struct content *c = hlcache_handle_get_content(h);
assert(c != 0);
- LOG("content %p %s", c, nsurl_access(llcache_handle_get_url(c->llcache)));
+ NSLOG(netsurf, INFO, "content %p %s", c,
+ nsurl_access(llcache_handle_get_url(c->llcache)));
if (c->handler->close != NULL)
c->handler->close(c);
}
@@ -1040,7 +1057,7 @@ bool content__add_rfc5988_link(struct content *c,
/* broadcast the data */
msg_data.rfc5988_link = newlink;
- content_broadcast(c, CONTENT_MSG_LINK, msg_data);
+ content_broadcast(c, CONTENT_MSG_LINK, &msg_data);
return true;
}
@@ -1464,7 +1481,7 @@ nserror content__clone(const struct content *c, struct content *nc)
*/
nserror content_abort(struct content *c)
{
- LOG("Aborting %p", c);
+ NSLOG(netsurf, INFO, "Aborting %p", c);
if (c->handler->stop != NULL)
c->handler->stop(c);
diff --git a/content/content.h b/content/content.h
index 308b2113b..e555df269 100644
--- a/content/content.h
+++ b/content/content.h
@@ -200,10 +200,24 @@ union content_msg_data {
void content_destroy(struct content *c);
-bool content_add_user(struct content *h, void (*callback)(struct content *c, content_msg msg, union content_msg_data data, void *pw), void *pw);
-
-
-void content_remove_user(struct content *c, void (*callback)(struct content *c, content_msg msg, union content_msg_data data, void *pw), void *pw);
+bool content_add_user(
+ struct content *h,
+ void (*callback)(
+ struct content *c,
+ content_msg msg,
+ const union content_msg_data *data,
+ void *pw),
+ void *pw);
+
+
+void content_remove_user(
+ struct content *c,
+ void (*callback)(
+ struct content *c,
+ content_msg msg,
+ const union content_msg_data *data,
+ void *pw),
+ void *pw);
uint32_t content_count_users(struct content *c);
diff --git a/content/content_protected.h b/content/content_protected.h
index ef38cb12d..21b73a662 100644
--- a/content/content_protected.h
+++ b/content/content_protected.h
@@ -92,8 +92,11 @@ struct content_handler {
/** Linked list of users of a content. */
struct content_user
{
- void (*callback)(struct content *c, content_msg msg,
- union content_msg_data data, void *pw);
+ void (*callback)(
+ struct content *c,
+ content_msg msg,
+ const union content_msg_data *data,
+ void *pw);
void *pw;
struct content_user *next;
@@ -166,7 +169,7 @@ void content_set_error(struct content *c);
void content_set_status(struct content *c, const char *status_message);
void content_broadcast(struct content *c, content_msg msg,
- union content_msg_data data);
+ const union content_msg_data *data);
/**
* Send an errorcode message to all users.
*/
diff --git a/content/fetch.c b/content/fetch.c
index a69d3e4cf..766502941 100644
--- a/content/fetch.c
+++ b/content/fetch.c
@@ -60,16 +60,6 @@
#include "javascript/fetcher.h"
#include "content/urldb.h"
-/* Define this to turn on verbose fetch logging */
-#undef DEBUG_FETCH_VERBOSE
-
-/** Verbose fetcher logging */
-#ifdef DEBUG_FETCH_VERBOSE
-#define FETCH_LOG(x...) LOG(x...)
-#else
-#define FETCH_LOG(x...)
-#endif
-
/** The maximum number of fetchers that can be added */
#define MAX_FETCHERS 10
@@ -158,8 +148,10 @@ static int get_fetcher_for_scheme(lwc_string *scheme)
static bool fetch_dispatch_job(struct fetch *fetch)
{
RING_REMOVE(queue_ring, fetch);
- FETCH_LOG("Attempting to start fetch %p, fetcher %p, url %s", fetch,
- fetch->fetcher_handle, nsurl_access(fetch->url));
+ NSLOG(fetch, DEBUG,
+ "Attempting to start fetch %p, fetcher %p, url %s", fetch,
+ fetch->fetcher_handle,
+ nsurl_access(fetch->url));
if (!fetchers[fetch->fetcherd].ops.start(fetch->fetcher_handle)) {
RING_INSERT(queue_ring, fetch); /* Put it back on the end of the queue */
@@ -210,25 +202,25 @@ static bool fetch_choose_and_dispatch(void)
static void dump_rings(void)
{
-#ifdef DEBUG_FETCH_VERBOSE
struct fetch *q;
struct fetch *f;
q = queue_ring;
if (q) {
do {
- LOG("queue_ring: %s", nsurl_access(q->url));
+ NSLOG(fetch, DEBUG, "queue_ring: %s",
+ nsurl_access(q->url));
q = q->r_next;
} while (q != queue_ring);
}
f = fetch_ring;
if (f) {
do {
- LOG("fetch_ring: %s", nsurl_access(f->url));
+ NSLOG(fetch, DEBUG, "fetch_ring: %s",
+ nsurl_access(f->url));
f = f->r_next;
} while (f != fetch_ring);
}
-#endif
}
/**
@@ -244,7 +236,10 @@ static bool fetch_dispatch_jobs(void)
RING_GETSIZE(struct fetch, queue_ring, all_queued);
RING_GETSIZE(struct fetch, fetch_ring, all_active);
- FETCH_LOG("queue_ring %i, fetch_ring %i", all_queued, all_active);
+ NSLOG(fetch, DEBUG,
+ "queue_ring %i, fetch_ring %i",
+ all_queued,
+ all_active);
dump_rings();
while ((all_queued != 0) &&
@@ -252,12 +247,14 @@ static bool fetch_dispatch_jobs(void)
fetch_choose_and_dispatch()) {
all_queued--;
all_active++;
- FETCH_LOG("%d queued, %d fetching",
- all_queued, all_active);
+ NSLOG(fetch, DEBUG,
+ "%d queued, %d fetching",
+ all_queued,
+ all_active);
}
- FETCH_LOG("Fetch ring is now %d elements.", all_active);
- FETCH_LOG("Queue ring is now %d elements.", all_queued);
+ NSLOG(fetch, DEBUG, "Fetch ring is now %d elements.", all_active);
+ NSLOG(fetch, DEBUG, "Queue ring is now %d elements.", all_queued);
return (all_active > 0);
}
@@ -267,7 +264,7 @@ static void fetcher_poll(void *unused)
int fetcherd;
if (fetch_dispatch_jobs()) {
- FETCH_LOG("Polling fetchers");
+ NSLOG(fetch, DEBUG, "Polling fetchers");
for (fetcherd = 0; fetcherd < MAX_FETCHERS; fetcherd++) {
if (fetchers[fetcherd].refcount > 0) {
/* fetcher present */
@@ -341,7 +338,10 @@ void fetcher_quit(void)
* the reference count to allow the fetcher to
* be stopped.
*/
- LOG("Fetcher for scheme %s still has %d active users at quit.", lwc_string_data(fetchers[fetcherd].scheme), fetchers[fetcherd].refcount);
+ NSLOG(fetch, INFO,
+ "Fetcher for scheme %s still has %d active users at quit.",
+ lwc_string_data(fetchers[fetcherd].scheme),
+ fetchers[fetcherd].refcount);
fetchers[fetcherd].refcount = 1;
}
@@ -391,12 +391,12 @@ fetch_fdset(fd_set *read_fd_set,
int fetcherd; /* fetcher index */
if (!fetch_dispatch_jobs()) {
- FETCH_LOG("No jobs");
+ NSLOG(fetch, DEBUG, "No jobs");
*maxfd_out = -1;
return NSERROR_OK;
}
- FETCH_LOG("Polling fetchers");
+ NSLOG(fetch, DEBUG, "Polling fetchers");
for (fetcherd = 0; fetcherd < MAX_FETCHERS; fetcherd++) {
if (fetchers[fetcherd].refcount > 0) {
@@ -479,7 +479,7 @@ fetch_start(nsurl *url,
return NSERROR_NO_FETCH_HANDLER;
}
- FETCH_LOG("fetch %p, url '%s'", fetch, nsurl_access(url));
+ NSLOG(fetch, DEBUG, "fetch %p, url '%s'", fetch, nsurl_access(url));
/* construct a new fetch structure */
fetch->callback = callback;
@@ -571,7 +571,7 @@ fetch_start(nsurl *url,
/* Ask the queue to run. */
if (fetch_dispatch_jobs()) {
- FETCH_LOG("scheduling poll");
+ NSLOG(fetch, DEBUG, "scheduling poll");
/* schedule active fetchers to run again in 10ms */
guit->misc->schedule(10, fetcher_poll, NULL);
}
@@ -584,7 +584,8 @@ fetch_start(nsurl *url,
void fetch_abort(struct fetch *f)
{
assert(f);
- FETCH_LOG("fetch %p, fetcher %p, url '%s'", f, f->fetcher_handle,
+ NSLOG(fetch, DEBUG,
+ "fetch %p, fetcher %p, url '%s'", f, f->fetcher_handle,
nsurl_access(f->url));
fetchers[f->fetcherd].ops.abort(f->fetcher_handle);
}
@@ -592,7 +593,10 @@ void fetch_abort(struct fetch *f)
/* exported interface documented in content/fetch.h */
void fetch_free(struct fetch *f)
{
- FETCH_LOG("Freeing fetch %p, fetcher %p", f, f->fetcher_handle);
+ NSLOG(fetch, DEBUG,
+ "Freeing fetch %p, fetcher %p",
+ f,
+ f->fetcher_handle);
fetchers[f->fetcherd].ops.free(f->fetcher_handle);
@@ -718,7 +722,8 @@ void fetch_multipart_data_destroy(struct fetch_multipart_data *list)
free(list->name);
free(list->value);
if (list->file) {
- FETCH_LOG("Freeing rawfile: %s", list->rawfile);
+ NSLOG(fetch, DEBUG,
+ "Freeing rawfile: %s", list->rawfile);
free(list->rawfile);
}
free(list);
@@ -736,8 +741,13 @@ fetch_send_callback(const fetch_msg *msg, struct fetch *fetch)
/* exported interface documented in content/fetch.h */
void fetch_remove_from_queues(struct fetch *fetch)
{
- FETCH_LOG("Fetch %p, fetcher %p can be freed",
- fetch, fetch->fetcher_handle);
+ int all_active;
+ int all_queued;
+
+ NSLOG(fetch, DEBUG,
+ "Fetch %p, fetcher %p can be freed",
+ fetch,
+ fetch->fetcher_handle);
/* Go ahead and free the fetch properly now */
if (fetch->fetch_is_active) {
@@ -746,24 +756,19 @@ void fetch_remove_from_queues(struct fetch *fetch)
RING_REMOVE(queue_ring, fetch);
}
-#ifdef DEBUG_FETCH_VERBOSE
- int all_active;
- int all_queued;
RING_GETSIZE(struct fetch, fetch_ring, all_active);
RING_GETSIZE(struct fetch, queue_ring, all_queued);
- LOG("Fetch ring is now %d elements.", all_active);
-
- LOG("Queue ring is now %d elements.", all_queued);
-#endif
+ NSLOG(fetch, DEBUG, "Fetch ring is now %d elements.", all_active);
+ NSLOG(fetch, DEBUG, "Queue ring is now %d elements.", all_queued);
}
/* exported interface documented in content/fetch.h */
void fetch_set_http_code(struct fetch *fetch, long http_code)
{
- FETCH_LOG("Setting HTTP code to %ld", http_code);
+ NSLOG(fetch, DEBUG, "Setting HTTP code to %ld", http_code);
fetch->http_code = http_code;
}
diff --git a/content/fetchers/curl.c b/content/fetchers/curl.c
index 7d0e40c24..a6146edb3 100644
--- a/content/fetchers/curl.c
+++ b/content/fetchers/curl.c
@@ -155,7 +155,8 @@ static void ns_X509_free(X509 *cert)
*/
static bool fetch_curl_initialise(lwc_string *scheme)
{
- LOG("Initialise cURL fetcher for %s", lwc_string_data(scheme));
+ NSLOG(netsurf, INFO, "Initialise cURL fetcher for %s",
+ lwc_string_data(scheme));
curl_fetchers_registered++;
return true; /* Always succeeds */
}
@@ -171,17 +172,20 @@ static void fetch_curl_finalise(lwc_string *scheme)
struct cache_handle *h;
curl_fetchers_registered--;
- LOG("Finalise cURL fetcher %s", lwc_string_data(scheme));
+ NSLOG(netsurf, INFO, "Finalise cURL fetcher %s",
+ lwc_string_data(scheme));
if (curl_fetchers_registered == 0) {
CURLMcode codem;
/* All the fetchers have been finalised. */
- LOG("All cURL fetchers finalised, closing down cURL");
+ NSLOG(netsurf, INFO,
+ "All cURL fetchers finalised, closing down cURL");
curl_easy_cleanup(fetch_blank_curl);
codem = curl_multi_cleanup(fetch_curl_multi);
if (codem != CURLM_OK)
- LOG("curl_multi_cleanup failed: ignoring");
+ NSLOG(netsurf, INFO,
+ "curl_multi_cleanup failed: ignoring");
curl_global_cleanup();
}
@@ -251,7 +255,9 @@ fetch_curl_post_convert(const struct fetch_multipart_data *control)
"application/octet-stream",
CURLFORM_END);
if (code != CURL_FORMADD_OK)
- LOG("curl_formadd: %d (%s)", code, control->name);
+ NSLOG(netsurf, INFO,
+ "curl_formadd: %d (%s)", code,
+ control->name);
} else {
char *mimetype = guit->fetch->mimetype(control->value);
code = curl_formadd(&post, &last,
@@ -262,7 +268,11 @@ fetch_curl_post_convert(const struct fetch_multipart_data *control)
(mimetype != 0 ? mimetype : "text/plain"),
CURLFORM_END);
if (code != CURL_FORMADD_OK)
- LOG("curl_formadd: %d (%s=%s)", code, control->name, control->value);
+ NSLOG(netsurf, INFO,
+ "curl_formadd: %d (%s=%s)",
+ code,
+ control->name,
+ control->value);
free(mimetype);
}
free(leafname);
@@ -273,7 +283,9 @@ fetch_curl_post_convert(const struct fetch_multipart_data *control)
CURLFORM_COPYCONTENTS, control->value,
CURLFORM_END);
if (code != CURL_FORMADD_OK)
- LOG("curl_formadd: %d (%s=%s)", code, control->name, control->value);
+ NSLOG(netsurf, INFO,
+ "curl_formadd: %d (%s=%s)", code,
+ control->name, control->value);
}
}
@@ -321,7 +333,7 @@ fetch_curl_setup(struct fetch *parent_fetch,
fetch->fetch_handle = parent_fetch;
- LOG("fetch %p, url '%s'", fetch, nsurl_access(url));
+ NSLOG(netsurf, INFO, "fetch %p, url '%s'", fetch, nsurl_access(url));
/* construct a new fetch structure */
fetch->curl_handle = NULL;
@@ -776,7 +788,7 @@ static void fetch_curl_abort(void *vf)
{
struct curl_fetch_info *f = (struct curl_fetch_info *)vf;
assert(f);
- LOG("fetch %p, url '%s'", f, nsurl_access(f->url));
+ NSLOG(netsurf, INFO, "fetch %p, url '%s'", f, nsurl_access(f->url));
if (f->curl_handle) {
f->abort = true;
} else {
@@ -796,7 +808,7 @@ static void fetch_curl_stop(struct curl_fetch_info *f)
CURLMcode codem;
assert(f);
- LOG("fetch %p, url '%s'", f, nsurl_access(f->url));
+ NSLOG(netsurf, INFO, "fetch %p, url '%s'", f, nsurl_access(f->url));
if (f->curl_handle) {
/* remove from curl multi handle */
@@ -864,7 +876,7 @@ static bool fetch_curl_process_headers(struct curl_fetch_info *f)
assert(code == CURLE_OK);
}
http_code = f->http_code;
- LOG("HTTP status code %li", http_code);
+ NSLOG(netsurf, INFO, "HTTP status code %li", http_code);
if (http_code == 304 && !f->post_urlenc && !f->post_multipart) {
/* Not Modified && GET request */
@@ -875,7 +887,7 @@ static bool fetch_curl_process_headers(struct curl_fetch_info *f)
/* handle HTTP redirects (3xx response codes) */
if (300 <= http_code && http_code < 400 && f->location != 0) {
- LOG("FETCH_REDIRECT, '%s'", f->location);
+ NSLOG(netsurf, INFO, "FETCH_REDIRECT, '%s'", f->location);
msg.type = FETCH_REDIRECT;
msg.data.redirect = f->location;
fetch_send_callback(&msg, f->fetch_handle);
@@ -1037,7 +1049,7 @@ static void fetch_curl_done(CURL *curl_handle, CURLcode result)
assert(code == CURLE_OK);
abort_fetch = f->abort;
- LOG("done %s", nsurl_access(f->url));
+ NSLOG(netsurf, INFO, "done %s", nsurl_access(f->url));
if ((abort_fetch == false) &&
(result == CURLE_OK ||
@@ -1082,7 +1094,7 @@ static void fetch_curl_done(CURL *curl_handle, CURLcode result)
memset(f->cert_data, 0, sizeof(f->cert_data));
cert = true;
} else {
- LOG("Unknown cURL response code %d", result);
+ NSLOG(netsurf, INFO, "Unknown cURL response code %d", result);
error = true;
}
@@ -1146,7 +1158,8 @@ static void fetch_curl_poll(lwc_string *scheme_ignored)
&exc_fd_set, &max_fd);
assert(codem == CURLM_OK);
- LOG("Curl file descriptor states (maxfd=%i):", max_fd);
+ NSLOG(netsurf, INFO,
+ "Curl file descriptor states (maxfd=%i):", max_fd);
for (i = 0; i <= max_fd; i++) {
bool read = false;
bool write = false;
@@ -1162,10 +1175,10 @@ static void fetch_curl_poll(lwc_string *scheme_ignored)
error = true;
}
if (read || write || error) {
- LOG(" fd %i: %s %s %s", i,
- read ? "read" : " ",
- write ? "write" : " ",
- error ? "error" : " ");
+ NSLOG(netsurf, INFO, " fd %i: %s %s %s", i,
+ read ? "read" : " ",
+ write ? "write" : " ",
+ error ? "error" : " ");
}
}
}
@@ -1174,7 +1187,8 @@ static void fetch_curl_poll(lwc_string *scheme_ignored)
do {
codem = curl_multi_perform(fetch_curl_multi, &running);
if (codem != CURLM_OK && codem != CURLM_CALL_MULTI_PERFORM) {
- LOG("curl_multi_perform: %i %s", codem, curl_multi_strerror(codem));
+ NSLOG(netsurf, INFO, "curl_multi_perform: %i %s",
+ codem, curl_multi_strerror(codem));
guit->misc->warning("MiscError", curl_multi_strerror(codem));
return;
}
@@ -1336,7 +1350,7 @@ fetch_curl_header(char *data, size_t size, size_t nmemb, void *_f)
free(f->location);
f->location = malloc(size);
if (!f->location) {
- LOG("malloc failed");
+ NSLOG(netsurf, INFO, "malloc failed");
return size;
}
SKIP_ST(9);
@@ -1427,17 +1441,17 @@ nserror fetch_curl_register(void)
.finalise = fetch_curl_finalise
};
- LOG("curl_version %s", curl_version());
+ NSLOG(netsurf, INFO, "curl_version %s", curl_version());
code = curl_global_init(CURL_GLOBAL_ALL);
if (code != CURLE_OK) {
- LOG("curl_global_init failed.");
+ NSLOG(netsurf, INFO, "curl_global_init failed.");
return NSERROR_INIT_FAILED;
}
fetch_curl_multi = curl_multi_init();
if (!fetch_curl_multi) {
- LOG("curl_multi_init failed.");
+ NSLOG(netsurf, INFO, "curl_multi_init failed.");
return NSERROR_INIT_FAILED;
}
@@ -1465,7 +1479,7 @@ nserror fetch_curl_register(void)
*/
fetch_blank_curl = curl_easy_init();
if (!fetch_blank_curl) {
- LOG("curl_easy_init failed");
+ NSLOG(netsurf, INFO, "curl_easy_init failed");
return NSERROR_INIT_FAILED;
}
@@ -1497,11 +1511,12 @@ nserror fetch_curl_register(void)
if (nsoption_charp(ca_bundle) &&
strcmp(nsoption_charp(ca_bundle), "")) {
- LOG("ca_bundle: '%s'", nsoption_charp(ca_bundle));
+ NSLOG(netsurf, INFO, "ca_bundle: '%s'",
+ nsoption_charp(ca_bundle));
SETOPT(CURLOPT_CAINFO, nsoption_charp(ca_bundle));
}
if (nsoption_charp(ca_path) && strcmp(nsoption_charp(ca_path), "")) {
- LOG("ca_path: '%s'", nsoption_charp(ca_path));
+ NSLOG(netsurf, INFO, "ca_path: '%s'", nsoption_charp(ca_path));
SETOPT(CURLOPT_CAPATH, nsoption_charp(ca_path));
}
@@ -1513,7 +1528,8 @@ nserror fetch_curl_register(void)
curl_with_openssl = false;
}
- LOG("cURL %slinked against openssl", curl_with_openssl ? "" : "not ");
+ NSLOG(netsurf, INFO, "cURL %slinked against openssl",
+ curl_with_openssl ? "" : "not ");
/* cURL initialised okay, register the fetchers */
@@ -1532,19 +1548,21 @@ nserror fetch_curl_register(void)
}
if (fetcher_add(scheme, &fetcher_ops) != NSERROR_OK) {
- LOG("Unable to register cURL fetcher for %s", data->protocols[i]);
+ NSLOG(netsurf, INFO,
+ "Unable to register cURL fetcher for %s",
+ data->protocols[i]);
}
}
return NSERROR_OK;
curl_easy_setopt_failed:
- LOG("curl_easy_setopt failed.");
+ NSLOG(netsurf, INFO, "curl_easy_setopt failed.");
return NSERROR_INIT_FAILED;
#if LIBCURL_VERSION_NUM >= 0x071e00
curl_multi_setopt_failed:
- LOG("curl_multi_setopt failed.");
+ NSLOG(netsurf, INFO, "curl_multi_setopt failed.");
return NSERROR_INIT_FAILED;
#endif
}
diff --git a/content/fetchers/data.c b/content/fetchers/data.c
index cb99e6ff2..5ba021fd3 100644
--- a/content/fetchers/data.c
+++ b/content/fetchers/data.c
@@ -57,14 +57,16 @@ static struct fetch_data_context *ring = NULL;
static bool fetch_data_initialise(lwc_string *scheme)
{
- LOG("fetch_data_initialise called for %s", lwc_string_data(scheme));
+ NSLOG(netsurf, INFO, "fetch_data_initialise called for %s",
+ lwc_string_data(scheme));
return true;
}
static void fetch_data_finalise(lwc_string *scheme)
{
- LOG("fetch_data_finalise called for %s", lwc_string_data(scheme));
+ NSLOG(netsurf, INFO, "fetch_data_finalise called for %s",
+ lwc_string_data(scheme));
}
static bool fetch_data_can_fetch(const nsurl *url)
@@ -147,7 +149,7 @@ static bool fetch_data_process(struct fetch_data_context *c)
* data must still be there.
*/
- LOG("url: %.140s", c->url);
+ NSLOG(netsurf, INFO, "url: %.140s", c->url);
if (strlen(c->url) < 6) {
/* 6 is the minimum possible length (data:,) */
@@ -259,8 +261,10 @@ static void fetch_data_poll(lwc_string *scheme)
char header[64];
fetch_set_http_code(c->parent_fetch, 200);
- LOG("setting data: MIME type to %s, length to %" PRIsizet,
- c->mimetype, c->datalen);
+ NSLOG(netsurf, INFO,
+ "setting data: MIME type to %s, length to %"PRIsizet,
+ c->mimetype,
+ c->datalen);
/* Any callback can result in the fetch being aborted.
* Therefore, we _must_ check for this after _every_
* call to fetch_data_send_callback().
@@ -296,7 +300,8 @@ static void fetch_data_poll(lwc_string *scheme)
fetch_data_send_callback(&msg, c);
}
} else {
- LOG("Processing of %s failed!", c->url);
+ NSLOG(netsurf, INFO, "Processing of %s failed!",
+ c->url);
/* Ensure that we're unlocked here. If we aren't,
* then fetch_data_process() is broken.
diff --git a/content/fetchers/resource.c b/content/fetchers/resource.c
index b8b4b191f..78757733e 100644
--- a/content/fetchers/resource.c
+++ b/content/fetchers/resource.c
@@ -276,14 +276,16 @@ static bool fetch_resource_initialise(lwc_string *scheme)
&e->data,
&e->data_len);
if (res == NSERROR_OK) {
- LOG("direct data for %s", fetch_resource_paths[i]);
+ NSLOG(netsurf, INFO, "direct data for %s",
+ fetch_resource_paths[i]);
fetch_resource_path_count++;
} else {
e->redirect_url = guit->fetch->get_resource_url(fetch_resource_paths[i]);
if (e->redirect_url == NULL) {
lwc_string_unref(e->path);
} else {
- LOG("redirect url for %s", fetch_resource_paths[i]);
+ NSLOG(netsurf, INFO, "redirect url for %s",
+ fetch_resource_paths[i]);
fetch_resource_path_count++;
}
}
diff --git a/content/fs_backing_store.c b/content/fs_backing_store.c
index 9d410654b..1b59ea150 100644
--- a/content/fs_backing_store.c
+++ b/content/fs_backing_store.c
@@ -519,11 +519,12 @@ invalidate_entry(struct store_state *state, struct store_entry *bse)
* This entry cannot be immediately removed as it has
* associated allocation so wait for allocation release.
*/
- LOG("invalidating entry with referenced allocation");
+ NSLOG(netsurf, INFO,
+ "invalidating entry with referenced allocation");
return NSERROR_OK;
}
- LOG("Removing entry for %p", bse);
+ NSLOG(netsurf, INFO, "Removing entry for %p", bse);
/* remove the entry from the index */
ret = remove_store_entry(state, &bse);
@@ -533,12 +534,12 @@ invalidate_entry(struct store_state *state, struct store_entry *bse)
ret = invalidate_element(state, bse, ENTRY_ELEM_META);
if (ret != NSERROR_OK) {
- LOG("Error invalidating metadata element");
+ NSLOG(netsurf, INFO, "Error invalidating metadata element");
}
ret = invalidate_element(state, bse, ENTRY_ELEM_DATA);
if (ret != NSERROR_OK) {
- LOG("Error invalidating data element");
+ NSLOG(netsurf, INFO, "Error invalidating data element");
}
return NSERROR_OK;
@@ -620,8 +621,10 @@ static nserror store_evict(struct store_state *state)
return NSERROR_OK;
}
- LOG("Evicting entries to reduce %"PRIu64" by %"PRIsizet,
- state->total_alloc, state->hysteresis);
+ NSLOG(netsurf, INFO,
+ "Evicting entries to reduce %"PRIu64" by %"PRIsizet,
+ state->total_alloc,
+ state->hysteresis);
/* allocate storage for the list */
elist = malloc(sizeof(entry_ident_t) * state->last_entry);
@@ -658,7 +661,8 @@ static nserror store_evict(struct store_state *state)
free(elist);
- LOG("removed %"PRIsizet" in %d entries", removed, ent);
+ NSLOG(netsurf, INFO, "removed %"PRIsizet" in %d entries", removed,
+ ent);
return ret;
}
@@ -773,7 +777,10 @@ static nserror write_blocks(struct store_state *state)
&state->blocks[elem_idx][bfidx].use_map[0],
BLOCK_USE_MAP_SIZE);
if (wr != BLOCK_USE_MAP_SIZE) {
- LOG("writing block file %d use index on file number %d failed", elem_idx, bfidx);
+ NSLOG(netsurf, INFO,
+ "writing block file %d use index on file number %d failed",
+ elem_idx,
+ bfidx);
goto wr_err;
}
written += wr;
@@ -829,19 +836,21 @@ static nserror set_block_extents(struct store_state *state)
return NSERROR_OK;
}
- LOG("Starting");
+ NSLOG(netsurf, INFO, "Starting");
for (elem_idx = 0; elem_idx < ENTRY_ELEM_COUNT; elem_idx++) {
for (bfidx = 0; bfidx < BLOCK_FILE_COUNT; bfidx++) {
if (state->blocks[elem_idx][bfidx].fd != -1) {
/* ensure block file is correct extent */
ftr = ftruncate(state->blocks[elem_idx][bfidx].fd, 1U << (log2_block_size[elem_idx] + BLOCK_ENTRY_COUNT));
if (ftr == -1) {
- LOG("Truncate failed errno:%d", errno);
+ NSLOG(netsurf, INFO,
+ "Truncate failed errno:%d",
+ errno);
}
}
}
}
- LOG("Complete");
+ NSLOG(netsurf, INFO, "Complete");
state->blocks_opened = false;
@@ -886,7 +895,7 @@ get_store_entry(struct store_state *state, nsurl *url, struct store_entry **bse)
entry_ident_t ident;
unsigned int sei; /* store entry index */
- LOG("url:%s", nsurl_access(url));
+ NSLOG(netsurf, INFO, "url:%s", nsurl_access(url));
/* use the url hash as the entry identifier */
ident = nsurl_hash(url);
@@ -894,13 +903,14 @@ get_store_entry(struct store_state *state, nsurl *url, struct store_entry **bse)
sei = BS_ENTRY_INDEX(ident, state);
if (sei == 0) {
- LOG("Failed to find ident 0x%x in index", ident);
+ NSLOG(netsurf, INFO, "Failed to find ident 0x%x in index",
+ ident);
return NSERROR_NOT_FOUND;
}
if (state->entries[sei].ident != ident) {
/* entry ident did not match */
- LOG("ident did not match entry");
+ NSLOG(netsurf, INFO, "ident did not match entry");
return NSERROR_NOT_FOUND;
}
@@ -975,7 +985,7 @@ set_store_entry(struct store_state *state,
nserror ret;
struct store_entry_element *elem;
- LOG("url:%s", nsurl_access(url));
+ NSLOG(netsurf, INFO, "url:%s", nsurl_access(url));
/* evict entries as required and ensure there is at least one
* new entry available.
@@ -1013,7 +1023,10 @@ set_store_entry(struct store_state *state,
* to see if the old entry is in use and if
* not prefer the newly stored entry instead?
*/
- LOG("Entry index collision trying to replace %x with %x", se->ident, ident);
+ NSLOG(netsurf, INFO,
+ "Entry index collision trying to replace %x with %x",
+ se->ident,
+ ident);
return NSERROR_PERMISSION;
}
}
@@ -1026,7 +1039,8 @@ set_store_entry(struct store_state *state,
/* this entry cannot be removed as it has associated
* allocation.
*/
- LOG("attempt to overwrite entry with in use data");
+ NSLOG(netsurf, INFO,
+ "attempt to overwrite entry with in use data");
return NSERROR_PERMISSION;
}
@@ -1085,7 +1099,7 @@ store_open(struct store_state *state,
fname = store_fname(state, ident, elem_idx);
if (fname == NULL) {
- LOG("filename error");
+ NSLOG(netsurf, INFO, "filename error");
return -1;
}
@@ -1093,13 +1107,14 @@ store_open(struct store_state *state,
if (openflags & O_CREAT) {
ret = netsurf_mkdir_all(fname);
if (ret != NSERROR_OK) {
- LOG("file path \"%s\" could not be created", fname);
+ NSLOG(netsurf, INFO,
+ "file path \"%s\" could not be created", fname);
free(fname);
return -1;
}
}
- LOG("opening %s", fname);
+ NSLOG(netsurf, INFO, "opening %s", fname);
fd = open(fname, openflags, S_IRUSR | S_IWUSR);
free(fname);
@@ -1126,9 +1141,9 @@ build_entrymap(struct store_state *state)
{
unsigned int eloop;
- LOG("Allocating %ld bytes for max of %d buckets",
- (1 << state->ident_bits) * sizeof(entry_index_t),
- 1 << state->ident_bits);
+ NSLOG(netsurf, INFO, "Allocating %ld bytes for max of %d buckets",
+ (1 << state->ident_bits) * sizeof(entry_index_t),
+ 1 << state->ident_bits);
state->addrmap = calloc(1 << state->ident_bits, sizeof(entry_index_t));
if (state->addrmap == NULL) {
@@ -1138,12 +1153,12 @@ build_entrymap(struct store_state *state)
state->total_alloc = 0;
for (eloop = 1; eloop < state->last_entry; eloop++) {
- /*
- LOG("entry:%d ident:0x%08x used:%d",
- eloop,
- BS_ADDRESS(state->entries[eloop].ident, state),
- state->entries[eloop].use_count);
- */
+
+ NSLOG(llcache, DEEPDEBUG,
+ "entry:%d ident:0x%08x used:%d",
+ eloop,
+ BS_ADDRESS(state->entries[eloop].ident, state),
+ state->entries[eloop].use_count);
/* update the address map to point at the entry */
BS_ENTRY_INDEX(state->entries[eloop].ident, state) = eloop;
@@ -1204,10 +1219,12 @@ read_entries(struct store_state *state)
entries_size = (1 << state->entry_bits) * sizeof(struct store_entry);
- LOG("Allocating %"PRIsizet" bytes for max of %d entries of %ld length elements %ld length",
- entries_size, 1 << state->entry_bits,
- sizeof(struct store_entry),
- sizeof(struct store_entry_element));
+ NSLOG(netsurf, INFO,
+ "Allocating %"PRIsizet" bytes for max of %d entries of %ld length elements %ld length",
+ entries_size,
+ 1 << state->entry_bits,
+ sizeof(struct store_entry),
+ sizeof(struct store_entry_element));
state->entries = calloc(1, entries_size);
if (state->entries == NULL) {
@@ -1222,7 +1239,8 @@ read_entries(struct store_state *state)
close(fd);
if (rd > 0) {
state->last_entry = rd / sizeof(struct store_entry);
- LOG("Read %d entries", state->last_entry);
+ NSLOG(netsurf, INFO, "Read %d entries",
+ state->last_entry);
}
} else {
/* could rebuild entries from fs */
@@ -1253,7 +1271,7 @@ read_blocks(struct store_state *state)
return ret;
}
- LOG("Initialising block use map from %s", fname);
+ NSLOG(netsurf, INFO, "Initialising block use map from %s", fname);
fd = open(fname, O_RDWR);
free(fname);
@@ -1265,7 +1283,10 @@ read_blocks(struct store_state *state)
&state->blocks[elem_idx][bfidx].use_map[0],
BLOCK_USE_MAP_SIZE);
if (rd <= 0) {
- LOG("reading block file %d use index on file number %d failed", elem_idx, bfidx);
+ NSLOG(netsurf, INFO,
+ "reading block file %d use index on file number %d failed",
+ elem_idx,
+ bfidx);
goto rd_err;
}
}
@@ -1274,7 +1295,7 @@ read_blocks(struct store_state *state)
close(fd);
} else {
- LOG("Initialising block use map to defaults");
+ NSLOG(netsurf, INFO, "Initialising block use map to defaults");
/* ensure block 0 (invalid sentinel) is skipped */
state->blocks[ENTRY_ELEM_DATA][0].use_map[0] = 1;
state->blocks[ENTRY_ELEM_META][0].use_map[0] = 1;
@@ -1344,7 +1365,7 @@ write_control(struct store_state *state)
return ret;
}
- LOG("writing control file \"%s\"", fname);
+ NSLOG(netsurf, INFO, "writing control file \"%s\"", fname);
ret = netsurf_mkdir_all(fname);
if (ret != NSERROR_OK) {
@@ -1392,7 +1413,7 @@ read_control(struct store_state *state)
return ret;
}
- LOG("opening control file \"%s\"", fname);
+ NSLOG(netsurf, INFO, "opening control file \"%s\"", fname);
fcontrol = fopen(fname, "rb");
@@ -1509,7 +1530,8 @@ initialise(const struct llcache_store_parameters *parameters)
/* read store control and create new if required */
ret = read_control(newstate);
if (ret != NSERROR_OK) {
- LOG("read control failed %s", messages_get_errorcode(ret));
+ NSLOG(netsurf, INFO, "read control failed %s",
+ messages_get_errorcode(ret));
ret = write_control(newstate);
if (ret == NSERROR_OK) {
unlink_entries(newstate);
@@ -1558,15 +1580,17 @@ initialise(const struct llcache_store_parameters *parameters)
storestate = newstate;
- LOG("FS backing store init successful");
+ NSLOG(netsurf, INFO, "FS backing store init successful");
- LOG("path:%s limit:%"PRIsizet" hyst:%"PRIsizet" addr:%d entries:%d",
- newstate->path,
- newstate->limit,
- newstate->hysteresis,
- newstate->ident_bits,
- newstate->entry_bits);
- LOG("Using %"PRIu64"/%"PRIsizet, newstate->total_alloc, newstate->limit);
+ NSLOG(netsurf, INFO,
+ "path:%s limit:%"PRIsizet" hyst:%"PRIsizet" addr:%d entries:%d",
+ newstate->path,
+ newstate->limit,
+ newstate->hysteresis,
+ newstate->ident_bits,
+ newstate->entry_bits);
+ NSLOG(netsurf, INFO, "Using %"PRIu64"/%"PRIsizet,
+ newstate->total_alloc, newstate->limit);
return NSERROR_OK;
}
@@ -1605,14 +1629,15 @@ finalise(void)
/* avoid division by zero */
if (op_count > 0) {
- LOG("Cache total/hit/miss/fail (counts) %d/%"PRIsizet"/%"PRIsizet"/%d (100%%/%"PRIsizet"%%/%"PRIsizet"%%/%d%%)",
- op_count,
- storestate->hit_count,
- storestate->miss_count,
- 0,
- (storestate->hit_count * 100) / op_count,
- (storestate->miss_count * 100) / op_count,
- 0);
+ NSLOG(netsurf, INFO,
+ "Cache total/hit/miss/fail (counts) %d/%"PRIsizet"/%"PRIsizet"/%d (100%%/%"PRIsizet"%%/%"PRIsizet"%%/%d%%)",
+ op_count,
+ storestate->hit_count,
+ storestate->miss_count,
+ 0,
+ (storestate->hit_count * 100) / op_count,
+ (storestate->miss_count * 100) / op_count,
+ 0);
}
free(storestate->path);
@@ -1646,7 +1671,7 @@ static nserror store_write_block(struct store_state *state,
state->blocks[elem_idx][bf].fd = store_open(state, bf,
elem_idx + ENTRY_ELEM_COUNT, O_CREAT | O_RDWR);
if (state->blocks[elem_idx][bf].fd == -1) {
- LOG("Open failed errno %d", errno);
+ NSLOG(netsurf, INFO, "Open failed errno %d", errno);
return NSERROR_SAVE_FAILED;
}
@@ -1661,21 +1686,21 @@ static nserror store_write_block(struct store_state *state,
bse->elem[elem_idx].size,
offst);
if (wr != (ssize_t)bse->elem[elem_idx].size) {
- LOG("Write failed %"PRIssizet" of %d bytes from %p at 0x%jx block %d errno %d",
- wr,
- bse->elem[elem_idx].size,
- bse->elem[elem_idx].data,
- (uintmax_t)offst,
- bse->elem[elem_idx].block,
- errno);
+ NSLOG(netsurf, INFO,
+ "Write failed %"PRIssizet" of %d bytes from %p at 0x%jx block %d errno %d",
+ wr,
+ bse->elem[elem_idx].size,
+ bse->elem[elem_idx].data,
+ (uintmax_t)offst,
+ bse->elem[elem_idx].block,
+ errno);
return NSERROR_SAVE_FAILED;
}
- LOG("Wrote %"PRIssizet" bytes from %p at 0x%jx block %d",
- wr,
- bse->elem[elem_idx].data,
- (uintmax_t)offst,
- bse->elem[elem_idx].block);
+ NSLOG(netsurf, INFO,
+ "Wrote %"PRIssizet" bytes from %p at 0x%jx block %d", wr,
+ bse->elem[elem_idx].data, (uintmax_t)offst,
+ bse->elem[elem_idx].block);
return NSERROR_OK;
}
@@ -1699,7 +1724,7 @@ static nserror store_write_file(struct store_state *state,
fd = store_open(state, bse->ident, elem_idx, O_CREAT | O_WRONLY);
if (fd < 0) {
perror("");
- LOG("Open failed %d errno %d", fd, errno);
+ NSLOG(netsurf, INFO, "Open failed %d errno %d", fd, errno);
return NSERROR_SAVE_FAILED;
}
@@ -1708,17 +1733,19 @@ static nserror store_write_file(struct store_state *state,
close(fd);
if (wr != (ssize_t)bse->elem[elem_idx].size) {
- LOG("Write failed %"PRIssizet" of %d bytes from %p errno %d",
- wr,
- bse->elem[elem_idx].size,
- bse->elem[elem_idx].data,
- err);
+ NSLOG(netsurf, INFO,
+ "Write failed %"PRIssizet" of %d bytes from %p errno %d",
+ wr,
+ bse->elem[elem_idx].size,
+ bse->elem[elem_idx].data,
+ err);
/** @todo Delete the file? */
return NSERROR_SAVE_FAILED;
}
- LOG("Wrote %"PRIssizet" bytes from %p", wr, bse->elem[elem_idx].data);
+ NSLOG(netsurf, INFO, "Wrote %"PRIssizet" bytes from %p", wr,
+ bse->elem[elem_idx].data);
return NSERROR_OK;
}
@@ -1759,7 +1786,7 @@ store(nsurl *url,
/* set the store entry up */
ret = set_store_entry(storestate, url, elem_idx, data, datalen, &bse);
if (ret != NSERROR_OK) {
- LOG("store entry setting failed");
+ NSLOG(netsurf, INFO, "store entry setting failed");
return ret;
}
@@ -1782,7 +1809,7 @@ static nserror entry_release_alloc(struct store_entry_element *elem)
if ((elem->flags & ENTRY_ELEM_FLAG_HEAP) != 0) {
elem->ref--;
if (elem->ref == 0) {
- LOG("freeing %p", elem->data);
+ NSLOG(netsurf, INFO, "freeing %p", elem->data);
free(elem->data);
elem->flags &= ~ENTRY_ELEM_FLAG_HEAP;
}
@@ -1814,7 +1841,7 @@ static nserror store_read_block(struct store_state *state,
state->blocks[elem_idx][bf].fd = store_open(state, bf,
elem_idx + ENTRY_ELEM_COUNT, O_CREAT | O_RDWR);
if (state->blocks[elem_idx][bf].fd == -1) {
- LOG("Open failed errno %d", errno);
+ NSLOG(netsurf, INFO, "Open failed errno %d", errno);
return NSERROR_SAVE_FAILED;
}
@@ -1829,21 +1856,21 @@ static nserror store_read_block(struct store_state *state,
bse->elem[elem_idx].size,
offst);
if (rd != (ssize_t)bse->elem[elem_idx].size) {
- LOG("Failed reading %"PRIssizet" of %d bytes into %p from 0x%jx block %d errno %d",
- rd,
- bse->elem[elem_idx].size,
- bse->elem[elem_idx].data,
- (uintmax_t)offst,
- bse->elem[elem_idx].block,
- errno);
+ NSLOG(netsurf, INFO,
+ "Failed reading %"PRIssizet" of %d bytes into %p from 0x%jx block %d errno %d",
+ rd,
+ bse->elem[elem_idx].size,
+ bse->elem[elem_idx].data,
+ (uintmax_t)offst,
+ bse->elem[elem_idx].block,
+ errno);
return NSERROR_SAVE_FAILED;
}
- LOG("Read %"PRIssizet" bytes into %p from 0x%jx block %d",
- rd,
- bse->elem[elem_idx].data,
- (uintmax_t)offst,
- bse->elem[elem_idx].block);
+ NSLOG(netsurf, INFO,
+ "Read %"PRIssizet" bytes into %p from 0x%jx block %d", rd,
+ bse->elem[elem_idx].data, (uintmax_t)offst,
+ bse->elem[elem_idx].block);
return NSERROR_OK;
}
@@ -1868,7 +1895,7 @@ static nserror store_read_file(struct store_state *state,
/* separate file in backing store */
fd = store_open(storestate, bse->ident, elem_idx, O_RDONLY);
if (fd < 0) {
- LOG("Open failed %d errno %d", fd, errno);
+ NSLOG(netsurf, INFO, "Open failed %d errno %d", fd, errno);
/** @todo should this invalidate the entry? */
return NSERROR_NOT_FOUND;
}
@@ -1878,8 +1905,10 @@ static nserror store_read_file(struct store_state *state,
bse->elem[elem_idx].data + tot,
bse->elem[elem_idx].size - tot);
if (rd <= 0) {
- LOG("read error returned %"PRIssizet" errno %d",
- rd, errno);
+ NSLOG(netsurf, INFO,
+ "read error returned %"PRIssizet" errno %d",
+ rd,
+ errno);
ret = NSERROR_NOT_FOUND;
break;
}
@@ -1888,7 +1917,8 @@ static nserror store_read_file(struct store_state *state,
close(fd);
- LOG("Read %"PRIsizet" bytes into %p", tot, bse->elem[elem_idx].data);
+ NSLOG(netsurf, INFO, "Read %"PRIsizet" bytes into %p", tot,
+ bse->elem[elem_idx].data);
return ret;
}
@@ -1921,13 +1951,14 @@ fetch(nsurl *url,
/* fetch store entry */
ret = get_store_entry(storestate, url, &bse);
if (ret != NSERROR_OK) {
- LOG("entry not found");
+ NSLOG(netsurf, INFO, "entry not found");
storestate->miss_count++;
return ret;
}
storestate->hit_count++;
- LOG("retrieving cache data for url:%s", nsurl_access(url));
+ NSLOG(netsurf, INFO, "retrieving cache data for url:%s",
+ nsurl_access(url));
/* calculate the entry element index */
if ((bsflags & BACKING_STORE_META) != 0) {
@@ -1942,16 +1973,20 @@ fetch(nsurl *url,
/* use the existing allocation and bump the ref count. */
elem->ref++;
- LOG("Using existing entry (%p) allocation %p refs:%d", bse, elem->data, elem->ref);
+ NSLOG(netsurf, INFO,
+ "Using existing entry (%p) allocation %p refs:%d", bse,
+ elem->data, elem->ref);
} else {
/* allocate from the heap */
elem->data = malloc(elem->size);
if (elem->data == NULL) {
- LOG("Failed to create new heap allocation");
+ NSLOG(netsurf, INFO,
+ "Failed to create new heap allocation");
return NSERROR_NOMEM;
}
- LOG("Created new heap allocation %p", elem->data);
+ NSLOG(netsurf, INFO, "Created new heap allocation %p",
+ elem->data);
/* mark the entry as having a valid heap allocation */
elem->flags |= ENTRY_ELEM_FLAG_HEAP;
@@ -2000,7 +2035,7 @@ static nserror release(nsurl *url, enum backing_store_flags bsflags)
ret = get_store_entry(storestate, url, &bse);
if (ret != NSERROR_OK) {
- LOG("entry not found");
+ NSLOG(netsurf, INFO, "entry not found");
return ret;
}
diff --git a/content/handlers/css/css.c b/content/handlers/css/css.c
index 997eb5115..93efd6a1b 100644
--- a/content/handlers/css/css.c
+++ b/content/handlers/css/css.c
@@ -136,7 +136,6 @@ nscss_create(const content_handler *handler,
const char *charset = NULL;
const char *xnsbase = NULL;
lwc_string *charset_value = NULL;
- union content_msg_data msg_data;
nserror error;
result = calloc(1, sizeof(nscss_content));
@@ -171,8 +170,7 @@ nscss_create(const content_handler *handler,
xnsbase, charset, result->base.quirks,
nscss_content_done, result);
if (error != NSERROR_OK) {
- msg_data.error = messages_get("NoMemory");
- content_broadcast(&result->base, CONTENT_MSG_ERROR, msg_data);
+ content_broadcast_errorcode(&result->base, NSERROR_NOMEM);
if (charset_value != NULL)
lwc_string_unref(charset_value);
free(result);
@@ -250,13 +248,11 @@ static nserror nscss_create_css_data(struct content_css_data *c,
bool nscss_process_data(struct content *c, const char *data, unsigned int size)
{
nscss_content *css = (nscss_content *) c;
- union content_msg_data msg_data;
css_error error;
error = nscss_process_css_data(&css->data, data, size);
if (error != CSS_OK && error != CSS_NEEDDATA) {
- msg_data.error = "?";
- content_broadcast(c, CONTENT_MSG_ERROR, msg_data);
+ content_broadcast_errorcode(c, NSERROR_CSS);
}
return (error == CSS_OK || error == CSS_NEEDDATA);
@@ -286,13 +282,11 @@ static css_error nscss_process_css_data(struct content_css_data *c,
bool nscss_convert(struct content *c)
{
nscss_content *css = (nscss_content *) c;
- union content_msg_data msg_data;
css_error error;
error = nscss_convert_css_data(&css->data);
if (error != CSS_OK) {
- msg_data.error = "?";
- content_broadcast(c, CONTENT_MSG_ERROR, msg_data);
+ content_broadcast_errorcode(c, NSERROR_CSS);
return false;
}
@@ -327,9 +321,11 @@ static css_error nscss_convert_css_data(struct content_css_data *c)
const char *url;
if (css_stylesheet_get_url(c->sheet, &url) == CSS_OK) {
- LOG("Failed converting %p %s (%d)", c, url, error);
+ NSLOG(netsurf, INFO, "Failed converting %p %s (%d)",
+ c, url, error);
} else {
- LOG("Failed converting %p (%d)", c, error);
+ NSLOG(netsurf, INFO, "Failed converting %p (%d)", c,
+ error);
}
}
@@ -475,7 +471,6 @@ content_type nscss_content_type(void)
*/
void nscss_content_done(struct content_css_data *css, void *pw)
{
- union content_msg_data msg_data;
struct content *c = pw;
uint32_t i;
size_t size;
@@ -484,8 +479,7 @@ void nscss_content_done(struct content_css_data *css, void *pw)
/* Retrieve the size of this sheet */
error = css_stylesheet_size(css->sheet, &size);
if (error != CSS_OK) {
- msg_data.error = "?";
- content_broadcast(c, CONTENT_MSG_ERROR, msg_data);
+ content_broadcast_errorcode(c, NSERROR_CSS);
content_set_error(c);
return;
}
@@ -606,7 +600,9 @@ css_error nscss_handle_import(void *pw, css_stylesheet *parent,
nsurl_unref(ns_ref);
#ifdef NSCSS_IMPORT_TRACE
- LOG("Import %d '%s' -> (handle: %p ctx: %p)", c->import_count, lwc_string_data(url), c->imports[c->import_count].c, ctx);
+ NSLOG(netsurf, INFO, "Import %d '%s' -> (handle: %p ctx: %p)",
+ c->import_count, lwc_string_data(url),
+ c->imports[c->import_count].c, ctx);
#endif
c->import_count++;
@@ -629,7 +625,7 @@ nserror nscss_import(hlcache_handle *handle,
css_error error = CSS_OK;
#ifdef NSCSS_IMPORT_TRACE
- LOG("Event %d for %p (%p)", event->type, handle, ctx);
+ NSLOG(netsurf, INFO, "Event %d for %p (%p)", event->type, handle, ctx);
#endif
assert(ctx->css->imports[ctx->index].c == handle);
@@ -639,6 +635,7 @@ nserror nscss_import(hlcache_handle *handle,
error = nscss_import_complete(ctx);
break;
+ case CONTENT_MSG_ERRORCODE:
case CONTENT_MSG_ERROR:
hlcache_handle_release(handle);
ctx->css->imports[ctx->index].c = NULL;
@@ -670,7 +667,8 @@ css_error nscss_import_complete(nscss_import_ctx *ctx)
error = nscss_register_imports(ctx->css);
#ifdef NSCSS_IMPORT_TRACE
- LOG("Destroying import context %p for %d", ctx, ctx->index);
+ NSLOG(netsurf, INFO, "Destroying import context %p for %d", ctx,
+ ctx->index);
#endif
/* No longer need import context */
diff --git a/content/handlers/css/dump.c b/content/handlers/css/dump.c
index 1ad188cb8..529bd4a88 100644
--- a/content/handlers/css/dump.c
+++ b/content/handlers/css/dump.c
@@ -20,6 +20,7 @@
#include <libcss/libcss.h>
#include "css/dump.h"
+#include "css/utils.h"
/**
* Dump a fixed point value to the stream in a textual form.
@@ -783,7 +784,7 @@ void nscss_dump_computed_style(FILE *stream, const css_computed_style *style)
}
/* display */
- val = css_computed_display_static(style);
+ val = ns_computed_display_static(style);
switch (val) {
case CSS_DISPLAY_INLINE:
fprintf(stream, "display: inline ");
@@ -1268,7 +1269,7 @@ void nscss_dump_computed_style(FILE *stream, const css_computed_style *style)
}
/* min-height */
- val = css_computed_min_height(style, &len1, &unit1);
+ val = ns_computed_min_height(style, &len1, &unit1);
switch (val) {
case CSS_MIN_HEIGHT_SET:
fprintf(stream, "min-height: ");
@@ -1282,7 +1283,7 @@ void nscss_dump_computed_style(FILE *stream, const css_computed_style *style)
}
/* min-width */
- val = css_computed_min_width(style, &len1, &unit1);
+ val = ns_computed_min_width(style, &len1, &unit1);
switch (val) {
case CSS_MIN_WIDTH_SET:
fprintf(stream, "min-width: ");
diff --git a/content/handlers/css/hints.c b/content/handlers/css/hints.c
index 9dfcf402b..3a15f8e08 100644
--- a/content/handlers/css/hints.c
+++ b/content/handlers/css/hints.c
@@ -748,6 +748,8 @@ static void css_hint_vertical_align_table_cells(
corestring_dom_valign, &attr);
if (err == DOM_NO_ERR && attr != NULL) {
+ hint->data.length.value = 0;
+ hint->data.length.unit = CSS_UNIT_PX;
if (dom_string_caseless_lwc_isequal(attr,
corestring_lwc_top)) {
hint->prop = CSS_PROP_VERTICAL_ALIGN;
@@ -1615,7 +1617,7 @@ css_error node_presentational_hint(void *pw, void *node,
}
#ifdef LOG_STATS
- LOG("Properties with hints: %i", hint_ctx.len);
+ NSLOG(netsurf, INFO, "Properties with hints: %i", hint_ctx.len);
#endif
css_hint_get_hints(hints, nhints);
diff --git a/content/handlers/css/select.c b/content/handlers/css/select.c
index daa3b4087..328d6a711 100644
--- a/content/handlers/css/select.c
+++ b/content/handlers/css/select.c
@@ -175,20 +175,20 @@ css_stylesheet *nscss_create_inline_style(const uint8_t *data, size_t len,
error = css_stylesheet_create(&params, &sheet);
if (error != CSS_OK) {
- LOG("Failed creating sheet: %d", error);
+ NSLOG(netsurf, INFO, "Failed creating sheet: %d", error);
return NULL;
}
error = css_stylesheet_append_data(sheet, data, len);
if (error != CSS_OK && error != CSS_NEEDDATA) {
- LOG("failed appending data: %d", error);
+ NSLOG(netsurf, INFO, "failed appending data: %d", error);
css_stylesheet_destroy(sheet);
return NULL;
}
error = css_stylesheet_data_done(sheet);
if (error != CSS_OK) {
- LOG("failed completing parse: %d", error);
+ NSLOG(netsurf, INFO, "failed completing parse: %d", error);
css_stylesheet_destroy(sheet);
return NULL;
}
@@ -214,7 +214,8 @@ static void nscss_dom_user_data_handler(dom_node_operation operation,
CSS_NODE_CLONED,
NULL, src, dst, data);
if (error != CSS_OK)
- LOG("Failed to clone libcss_node_data.");
+ NSLOG(netsurf, INFO,
+ "Failed to clone libcss_node_data.");
break;
case DOM_NODE_RENAMED:
@@ -222,7 +223,8 @@ static void nscss_dom_user_data_handler(dom_node_operation operation,
CSS_NODE_MODIFIED,
NULL, src, NULL, data);
if (error != CSS_OK)
- LOG("Failed to update libcss_node_data.");
+ NSLOG(netsurf, INFO,
+ "Failed to update libcss_node_data.");
break;
case DOM_NODE_IMPORTED:
@@ -232,11 +234,12 @@ static void nscss_dom_user_data_handler(dom_node_operation operation,
CSS_NODE_DELETED,
NULL, src, NULL, data);
if (error != CSS_OK)
- LOG("Failed to delete libcss_node_data.");
+ NSLOG(netsurf, INFO,
+ "Failed to delete libcss_node_data.");
break;
default:
- LOG("User data operation not handled.");
+ NSLOG(netsurf, INFO, "User data operation not handled.");
assert(0);
}
}
diff --git a/content/handlers/css/utils.h b/content/handlers/css/utils.h
index 58a5ea6e6..21cb4973b 100644
--- a/content/handlers/css/utils.h
+++ b/content/handlers/css/utils.h
@@ -46,4 +46,73 @@ css_fixed nscss_len2pt(css_fixed length, css_unit unit);
*/
css_fixed nscss_len2px(css_fixed length, css_unit unit, const css_computed_style *style);
+
+/**
+ * Temporary helper wrappers for for libcss computed style getter, while
+ * we don't support flexbox related property values.
+ */
+
+static inline uint8_t ns_computed_display(
+ const css_computed_style *style, bool root)
+{
+ uint8_t value = css_computed_display(style, root);
+
+ if (value == CSS_DISPLAY_FLEX) {
+ return CSS_DISPLAY_BLOCK;
+
+ } else if (value == CSS_DISPLAY_INLINE_FLEX) {
+ return CSS_DISPLAY_INLINE_BLOCK;
+ }
+
+ return value;
+}
+
+
+static inline uint8_t ns_computed_display_static(
+ const css_computed_style *style)
+{
+ uint8_t value = css_computed_display_static(style);
+
+ if (value == CSS_DISPLAY_FLEX) {
+ return CSS_DISPLAY_BLOCK;
+
+ } else if (value == CSS_DISPLAY_INLINE_FLEX) {
+ return CSS_DISPLAY_INLINE_BLOCK;
+ }
+
+ return value;
+}
+
+
+static inline uint8_t ns_computed_min_height(
+ const css_computed_style *style,
+ css_fixed *length, css_unit *unit)
+{
+ uint8_t value = css_computed_min_height(style, length, unit);
+
+ if (value == CSS_MIN_HEIGHT_AUTO) {
+ value = CSS_MIN_HEIGHT_SET;
+ *length = 0;
+ *unit = CSS_UNIT_PX;
+ }
+
+ return value;
+}
+
+
+static inline uint8_t ns_computed_min_width(
+ const css_computed_style *style,
+ css_fixed *length, css_unit *unit)
+{
+ uint8_t value = css_computed_min_width(style, length, unit);
+
+ if (value == CSS_MIN_WIDTH_AUTO) {
+ value = CSS_MIN_WIDTH_SET;
+ *length = 0;
+ *unit = CSS_UNIT_PX;
+ }
+
+ return value;
+}
+
#endif
diff --git a/content/handlers/image/bmp.c b/content/handlers/image/bmp.c
index 271787449..48a37fb24 100644
--- a/content/handlers/image/bmp.c
+++ b/content/handlers/image/bmp.c
@@ -68,8 +68,7 @@ static void *nsbmp_bitmap_create(int width, int height, unsigned int bmp_state)
}
static nserror nsbmp_create_bmp_data(nsbmp_content *bmp)
-{
- union content_msg_data msg_data;
+{
bmp_bitmap_callback_vt bmp_bitmap_callbacks = {
.bitmap_create = nsbmp_bitmap_create,
.bitmap_destroy = guit->bitmap->destroy,
@@ -79,8 +78,7 @@ static nserror nsbmp_create_bmp_data(nsbmp_content *bmp)
bmp->bmp = calloc(sizeof(struct bmp_image), 1);
if (bmp->bmp == NULL) {
- msg_data.error = messages_get("NoMemory");
- content_broadcast(&bmp->base, CONTENT_MSG_ERROR, msg_data);
+ content_broadcast_errorcode(&bmp->base, NSERROR_NOMEM);
return NSERROR_NOMEM;
}
@@ -123,7 +121,6 @@ static bool nsbmp_convert(struct content *c)
{
nsbmp_content *bmp = (nsbmp_content *) c;
bmp_result res;
- union content_msg_data msg_data;
uint32_t swidth;
const char *data;
unsigned long size;
@@ -138,13 +135,11 @@ static bool nsbmp_convert(struct content *c)
case BMP_OK:
break;
case BMP_INSUFFICIENT_MEMORY:
- msg_data.error = messages_get("NoMemory");
- content_broadcast(c, CONTENT_MSG_ERROR, msg_data);
+ content_broadcast_errorcode(c, NSERROR_NOMEM);
return false;
case BMP_INSUFFICIENT_DATA:
case BMP_DATA_ERROR:
- msg_data.error = messages_get("BadBMP");
- content_broadcast(c, CONTENT_MSG_ERROR, msg_data);
+ content_broadcast_errorcode(c, NSERROR_BMP_ERROR);
return false;
}
diff --git a/content/handlers/image/gif.c b/content/handlers/image/gif.c
index c4f039490..253265caa 100644
--- a/content/handlers/image/gif.c
+++ b/content/handlers/image/gif.c
@@ -72,7 +72,6 @@ static void *nsgif_bitmap_create(int width, int height)
static nserror nsgif_create_gif_data(nsgif_content *c)
{
- union content_msg_data msg_data;
gif_bitmap_callback_vt gif_bitmap_callbacks = {
.bitmap_create = nsgif_bitmap_create,
.bitmap_destroy = guit->bitmap->destroy,
@@ -85,8 +84,7 @@ static nserror nsgif_create_gif_data(nsgif_content *c)
/* Initialise our data structure */
c->gif = calloc(sizeof(gif_animation), 1);
if (c->gif == NULL) {
- msg_data.error = messages_get("NoMemory");
- content_broadcast(&c->base, CONTENT_MSG_ERROR, msg_data);
+ content_broadcast_errorcode(&c->base, NSERROR_NOMEM);
return NSERROR_NOMEM;
}
gif_create(c->gif, &gif_bitmap_callbacks);
@@ -231,14 +229,13 @@ static void nsgif_animate(void *p)
data.redraw.object_width = gif->base.width;
data.redraw.object_height = gif->base.height;
- content_broadcast(&gif->base, CONTENT_MSG_REDRAW, data);
+ content_broadcast(&gif->base, CONTENT_MSG_REDRAW, &data);
}
static bool nsgif_convert(struct content *c)
{
nsgif_content *gif = (nsgif_content *) c;
int res;
- union content_msg_data msg_data;
const char *data;
unsigned long size;
char *title;
@@ -251,17 +248,18 @@ static bool nsgif_convert(struct content *c)
res = gif_initialise(gif->gif, size, (unsigned char *) data);
if (res != GIF_OK && res != GIF_WORKING &&
res != GIF_INSUFFICIENT_FRAME_DATA) {
+ nserror error = NSERROR_UNKNOWN;
switch (res) {
case GIF_FRAME_DATA_ERROR:
case GIF_INSUFFICIENT_DATA:
case GIF_DATA_ERROR:
- msg_data.error = messages_get("BadGIF");
+ error = NSERROR_GIF_ERROR;
break;
case GIF_INSUFFICIENT_MEMORY:
- msg_data.error = messages_get("NoMemory");
+ error = NSERROR_NOMEM;
break;
}
- content_broadcast(c, CONTENT_MSG_ERROR, msg_data);
+ content_broadcast_errorcode(c, error);
return false;
}
} while (res != GIF_OK && res != GIF_INSUFFICIENT_FRAME_DATA);
@@ -269,8 +267,7 @@ static bool nsgif_convert(struct content *c)
/* Abort on bad GIFs */
if ((gif->gif->frame_count_partial == 0) || (gif->gif->width == 0) ||
(gif->gif->height == 0)) {
- msg_data.error = messages_get("BadGIF");
- content_broadcast(c, CONTENT_MSG_ERROR, msg_data);
+ content_broadcast_errorcode(c, NSERROR_GIF_ERROR);
return false;
}
diff --git a/content/handlers/image/ico.c b/content/handlers/image/ico.c
index b14ea7fe1..85aab9f64 100644
--- a/content/handlers/image/ico.c
+++ b/content/handlers/image/ico.c
@@ -66,7 +66,6 @@ static void *nsico_bitmap_create(int width, int height, unsigned int bmp_state)
static nserror nsico_create_ico_data(nsico_content *c)
{
- union content_msg_data msg_data;
bmp_bitmap_callback_vt bmp_bitmap_callbacks = {
.bitmap_create = nsico_bitmap_create,
.bitmap_destroy = guit->bitmap->destroy,
@@ -76,8 +75,7 @@ static nserror nsico_create_ico_data(nsico_content *c)
c->ico = calloc(sizeof(ico_collection), 1);
if (c->ico == NULL) {
- msg_data.error = messages_get("NoMemory");
- content_broadcast(&c->base, CONTENT_MSG_ERROR, msg_data);
+ content_broadcast_errorcode(&c->base, NSERROR_NOMEM);
return NSERROR_NOMEM;
}
ico_collection_create(c->ico, &bmp_bitmap_callbacks);
@@ -122,7 +120,6 @@ static bool nsico_convert(struct content *c)
nsico_content *ico = (nsico_content *) c;
struct bmp_image *bmp;
bmp_result res;
- union content_msg_data msg_data;
const char *data;
unsigned long size;
char *title;
@@ -137,13 +134,11 @@ static bool nsico_convert(struct content *c)
case BMP_OK:
break;
case BMP_INSUFFICIENT_MEMORY:
- msg_data.error = messages_get("NoMemory");
- content_broadcast(c, CONTENT_MSG_ERROR, msg_data);
+ content_broadcast_errorcode(c, NSERROR_NOMEM);
return false;
case BMP_INSUFFICIENT_DATA:
case BMP_DATA_ERROR:
- msg_data.error = messages_get("BadICO");
- content_broadcast(c, CONTENT_MSG_ERROR, msg_data);
+ content_broadcast_errorcode(c, NSERROR_ICO_ERROR);
return false;
}
@@ -165,7 +160,7 @@ static bool nsico_convert(struct content *c)
bmp = ico_find(ico->ico, 255, 255);
if (bmp == NULL) {
/* return error */
- LOG("Failed to select icon");
+ NSLOG(netsurf, INFO, "Failed to select icon");
return false;
}
@@ -188,7 +183,7 @@ static bool nsico_redraw(struct content *c, struct content_redraw_data *data,
bmp = ico_find(ico->ico, data->width, data->height);
if (bmp == NULL) {
/* return error */
- LOG("Failed to select icon");
+ NSLOG(netsurf, INFO, "Failed to select icon");
return false;
}
@@ -197,7 +192,7 @@ static bool nsico_redraw(struct content *c, struct content_redraw_data *data,
if (bmp_decode(bmp) != BMP_OK) {
return false;
} else {
- LOG("Decoding bitmap");
+ NSLOG(netsurf, INFO, "Decoding bitmap");
guit->bitmap->modified(bmp->bitmap);
}
@@ -260,7 +255,7 @@ static void *nsico_get_internal(const struct content *c, void *context)
bmp = ico_find(ico->ico, 16, 16);
if (bmp == NULL) {
/* return error */
- LOG("Failed to select icon");
+ NSLOG(netsurf, INFO, "Failed to select icon");
return NULL;
}
diff --git a/content/handlers/image/image_cache.c b/content/handlers/image/image_cache.c
index 02107f75f..a1de01da5 100644
--- a/content/handlers/image/image_cache.c
+++ b/content/handlers/image/image_cache.c
@@ -256,11 +256,12 @@ static void image_cache__free_bitmap(struct image_cache_entry_s *centry)
{
if (centry->bitmap != NULL) {
#ifdef IMAGE_CACHE_VERBOSE
- LOG("Freeing bitmap %p size %d age %d redraw count %d",
- centry->bitmap,
- centry->bitmap_size,
- image_cache->current_age - centry->bitmap_age,
- centry->redraw_count);
+ NSLOG(netsurf, INFO,
+ "Freeing bitmap %p size %d age %d redraw count %d",
+ centry->bitmap,
+ centry->bitmap_size,
+ image_cache->current_age - centry->bitmap_age,
+ centry->redraw_count);
#endif
guit->bitmap->destroy(centry->bitmap);
centry->bitmap = NULL;
@@ -281,7 +282,7 @@ static void image_cache__free_bitmap(struct image_cache_entry_s *centry)
static void image_cache__free_entry(struct image_cache_entry_s *centry)
{
#ifdef IMAGE_CACHE_VERBOSE
- LOG("freeing %p ", centry);
+ NSLOG(netsurf, INFO, "freeing %p ", centry);
#endif
if (centry->redraw_count == 0) {
@@ -331,7 +332,7 @@ static void image_cache__background_update(void *p)
icache->current_age += icache->params.bg_clean_time;
#ifdef IMAGE_CACHE_VERBOSE
- LOG("Cache age %ds", icache->current_age / 1000);
+ NSLOG(netsurf, INFO, "Cache age %ds", icache->current_age / 1000);
#endif
image_cache__clean(icache);
@@ -383,13 +384,16 @@ bool image_cache_speculate(struct content *c)
if ((image_cache->total_bitmap_size < image_cache->params.limit) &&
(c->size <= image_cache->params.speculative_small)) {
#ifdef IMAGE_CACHE_VERBOSE
- LOG("content size (%d) is smaller than minimum (%d)", c->size, SPECULATE_SMALL);
+ NSLOG(netsurf, INFO,
+ "content size (%d) is smaller than minimum (%d)",
+ c->size,
+ SPECULATE_SMALL);
#endif
decision = true;
}
#ifdef IMAGE_CACHE_VERBOSE
- LOG("returning %d", decision);
+ NSLOG(netsurf, INFO, "returning %d", decision);
#endif
return decision;
}
@@ -422,8 +426,10 @@ image_cache_init(const struct image_cache_parameters *image_cache_parameters)
image_cache__background_update,
image_cache);
- LOG("Image cache initialised with a limit of %" PRIsizet " hysteresis of %"PRIsizet,
- image_cache->params.limit, image_cache->params.hysteresis);
+ NSLOG(netsurf, INFO,
+ "Image cache initialised with a limit of %"PRIsizet" hysteresis of %"PRIsizet,
+ image_cache->params.limit,
+ image_cache->params.hysteresis);
return NSERROR_OK;
}
@@ -435,8 +441,8 @@ nserror image_cache_fini(void)
guit->misc->schedule(-1, image_cache__background_update, image_cache);
- LOG("Size at finish %" PRIsizet " (in %d)",
- image_cache->total_bitmap_size, image_cache->bitmap_count);
+ NSLOG(netsurf, INFO, "Size at finish %"PRIsizet" (in %d)",
+ image_cache->total_bitmap_size, image_cache->bitmap_count);
while (image_cache->entries != NULL) {
image_cache__free_entry(image_cache->entries);
@@ -446,11 +452,13 @@ nserror image_cache_fini(void)
image_cache->miss_count +
image_cache->fail_count;
- LOG("Age %ds", image_cache->current_age / 1000);
- LOG("Peak size %" PRIsizet " (in %d)",
- image_cache->max_bitmap_size, image_cache->max_bitmap_size_count);
- LOG("Peak image count %d (size %" PRIsizet ")",
- image_cache->max_bitmap_count, image_cache->max_bitmap_count_size);
+ NSLOG(netsurf, INFO, "Age %ds", image_cache->current_age / 1000);
+ NSLOG(netsurf, INFO, "Peak size %"PRIsizet" (in %d)",
+ image_cache->max_bitmap_size,
+ image_cache->max_bitmap_size_count);
+ NSLOG(netsurf, INFO, "Peak image count %d (size %"PRIsizet")",
+ image_cache->max_bitmap_count,
+ image_cache->max_bitmap_count_size);
if (op_count > 0) {
uint64_t op_size;
@@ -459,35 +467,39 @@ nserror image_cache_fini(void)
image_cache->miss_size +
image_cache->fail_size;
- LOG("Cache total/hit/miss/fail (counts) %d/%d/%d/%d (100%%/%d%%/%d%%/%d%%)",
- op_count,
- image_cache->hit_count,
- image_cache->miss_count,
- image_cache->fail_count,
- (image_cache->hit_count * 100) / op_count,
- (image_cache->miss_count * 100) / op_count,
- (image_cache->fail_count * 100) / op_count);
- LOG("Cache total/hit/miss/fail (size) %"PRIu64"/%"PRIu64"/%"PRIu64"/%"PRIu64" (100%%/%"PRId64"%%/%"PRId64"%%/%"PRId64"%%)",
- op_size,
- image_cache->hit_size,
- image_cache->miss_size,
- image_cache->fail_size,
- (image_cache->hit_size * 100) / op_size,
- (image_cache->miss_size * 100) / op_size,
- (image_cache->fail_size * 100) / op_size);
+ NSLOG(netsurf, INFO,
+ "Cache total/hit/miss/fail (counts) %d/%d/%d/%d (100%%/%d%%/%d%%/%d%%)",
+ op_count,
+ image_cache->hit_count,
+ image_cache->miss_count,
+ image_cache->fail_count,
+ (image_cache->hit_count * 100) / op_count,
+ (image_cache->miss_count * 100) / op_count,
+ (image_cache->fail_count * 100) / op_count);
+ NSLOG(netsurf, INFO,
+ "Cache total/hit/miss/fail (size) %"PRIu64"/%"PRIu64"/%"PRIu64"/%"PRIu64" (100%%/%"PRId64"%%/%"PRId64"%%/%"PRId64"%%)",
+ op_size,
+ image_cache->hit_size,
+ image_cache->miss_size,
+ image_cache->fail_size,
+ (image_cache->hit_size * 100) / op_size,
+ (image_cache->miss_size * 100) / op_size,
+ (image_cache->fail_size * 100) / op_size);
}
- LOG("Total images never rendered: %d (includes %d that were converted)",
- image_cache->total_unrendered,
- image_cache->specultive_miss_count);
+ NSLOG(netsurf, INFO,
+ "Total images never rendered: %d (includes %d that were converted)",
+ image_cache->total_unrendered,
+ image_cache->specultive_miss_count);
- LOG("Total number of excessive conversions: %d (from %d images converted more than once)",
- image_cache->total_extra_conversions,
- image_cache->total_extra_conversions_count);
+ NSLOG(netsurf, INFO,
+ "Total number of excessive conversions: %d (from %d images converted more than once)",
+ image_cache->total_extra_conversions,
+ image_cache->total_extra_conversions_count);
- LOG("Bitmap of size %d had most (%d) conversions",
- image_cache->peak_conversions_size,
- image_cache->peak_conversions);
+ NSLOG(netsurf, INFO, "Bitmap of size %d had most (%d) conversions",
+ image_cache->peak_conversions_size,
+ image_cache->peak_conversions);
free(image_cache);
@@ -519,7 +531,8 @@ nserror image_cache_add(struct content *content,
centry->bitmap_size = content->width * content->height * 4;
}
- LOG("centry %p, content %p, bitmap %p", centry, content, bitmap);
+ NSLOG(netsurf, INFO, "centry %p, content %p, bitmap %p", centry,
+ content, bitmap);
centry->convert = convert;
@@ -558,7 +571,8 @@ nserror image_cache_remove(struct content *content)
/* get the cache entry */
centry = image_cache__find(content);
if (centry == NULL) {
- LOG("Could not find cache entry for content (%p)", content);
+ NSLOG(netsurf, INFO,
+ "Could not find cache entry for content (%p)", content);
return NSERROR_NOT_FOUND;
}
@@ -622,7 +636,7 @@ case chr : \
FMTCHR('b', PRIssizet, params.hysteresis);
FMTCHR('c', PRIssizet, total_bitmap_size);
FMTCHR('d', "d", bitmap_count);
- FMTCHR('e', "d", current_age / 1000);
+ FMTCHR('e', "u", current_age / 1000);
FMTCHR('f', PRIssizet, max_bitmap_size);
FMTCHR('g', "d", max_bitmap_size_count);
FMTCHR('h', "d", max_bitmap_count);
@@ -631,7 +645,7 @@ case chr : \
case 'j':
slen += snprintf(string + slen, size - slen,
- "%d", pct?100:op_count);
+ "%u", pct?100:op_count);
break;
FMTPCHR('k', "d", hit_count, op_count);
@@ -651,7 +665,7 @@ case chr : \
FMTCHR('t', "d", specultive_miss_count);
FMTCHR('u', "d", total_extra_conversions);
FMTCHR('v', "d", total_extra_conversions_count);
- FMTCHR('w', "d", peak_conversions_size);
+ FMTCHR('w', "u", peak_conversions_size);
FMTCHR('x', "d", peak_conversions);
@@ -674,8 +688,11 @@ case chr : \
}
/* exported interface documented in image_cache.h */
-int image_cache_snentryf(char *string, size_t size, unsigned int entryn,
- const char *fmt)
+int
+image_cache_snentryf(char *string,
+ size_t size,
+ unsigned int entryn,
+ const char *fmt)
{
struct image_cache_entry_s *centry;
size_t slen = 0; /* current output string length */
@@ -692,7 +709,7 @@ int image_cache_snentryf(char *string, size_t size, unsigned int entryn,
switch (fmt[fmtc]) {
case 'e':
slen += snprintf(string + slen, size - slen,
- "%d", entryn);
+ "%u", entryn);
break;
case 'r':
@@ -788,7 +805,8 @@ bool image_cache_redraw(struct content *c,
/* get the cache entry */
centry = image_cache__find(c);
if (centry == NULL) {
- LOG("Could not find cache entry for content (%p)", c);
+ NSLOG(netsurf, INFO,
+ "Could not find cache entry for content (%p)", c);
return false;
}
@@ -827,7 +845,8 @@ void image_cache_destroy(struct content *content)
/* get the cache entry */
centry = image_cache__find(content);
if (centry == NULL) {
- LOG("Could not find cache entry for content (%p)", content);
+ NSLOG(netsurf, INFO,
+ "Could not find cache entry for content (%p)", content);
} else {
image_cache__free_entry(centry);
}
diff --git a/content/handlers/image/jpeg.c b/content/handlers/image/jpeg.c
index 5ae9e70cd..44b1c5271 100644
--- a/content/handlers/image/jpeg.c
+++ b/content/handlers/image/jpeg.c
@@ -142,7 +142,7 @@ static void nsjpeg_term_source(j_decompress_ptr cinfo)
static void nsjpeg_error_log(j_common_ptr cinfo)
{
cinfo->err->format_message(cinfo, nsjpeg_error_buffer);
- LOG("%s", nsjpeg_error_buffer);
+ NSLOG(netsurf, INFO, "%s", nsjpeg_error_buffer);
}
@@ -156,7 +156,7 @@ static void nsjpeg_error_exit(j_common_ptr cinfo)
jmp_buf *setjmp_buffer = (jmp_buf *) cinfo->client_data;
cinfo->err->format_message(cinfo, nsjpeg_error_buffer);
- LOG("%s", nsjpeg_error_buffer);
+ NSLOG(netsurf, INFO, "%s", nsjpeg_error_buffer);
longjmp(*setjmp_buffer, 1);
}
@@ -301,7 +301,7 @@ static bool nsjpeg_convert(struct content *c)
jpeg_destroy_decompress(&cinfo);
msg_data.error = nsjpeg_error_buffer;
- content_broadcast(c, CONTENT_MSG_ERROR, msg_data);
+ content_broadcast(c, CONTENT_MSG_ERROR, &msg_data);
return false;
}
diff --git a/content/handlers/image/nssprite.c b/content/handlers/image/nssprite.c
index 247574aa4..269c24356 100644
--- a/content/handlers/image/nssprite.c
+++ b/content/handlers/image/nssprite.c
@@ -48,14 +48,14 @@ typedef struct nssprite_content {
#define ERRCHK(x) do { \
rosprite_error err = x; \
if (err == ROSPRITE_EOF) { \
- LOG("Got ROSPRITE_EOF when loading sprite file"); \
- return false; \
+ NSLOG(netsurf, INFO, "Got ROSPRITE_EOF when loading sprite file"); \
+ goto ro_sprite_error; \
} else if (err == ROSPRITE_BADMODE) { \
- LOG("Got ROSPRITE_BADMODE when loading sprite file"); \
- return false; \
+ NSLOG(netsurf, INFO, "Got ROSPRITE_BADMODE when loading sprite file"); \
+ goto ro_sprite_error; \
} else if (err == ROSPRITE_OK) { \
} else { \
- return false; \
+ goto ro_sprite_error; \
} \
} while(0)
@@ -95,9 +95,8 @@ static nserror nssprite_create(const content_handler *handler,
static bool nssprite_convert(struct content *c)
{
nssprite_content *nssprite = (nssprite_content *) c;
- union content_msg_data msg_data;
- struct rosprite_mem_context* ctx;
+ struct rosprite_mem_context* ctx = NULL;
const char *data;
unsigned long size;
@@ -118,14 +117,12 @@ static bool nssprite_convert(struct content *c)
nssprite->bitmap = guit->bitmap->create(sprite->width, sprite->height, BITMAP_NEW);
if (!nssprite->bitmap) {
- msg_data.error = messages_get("NoMemory");
- content_broadcast(c, CONTENT_MSG_ERROR, msg_data);
+ content_broadcast_errorcode(c, NSERROR_NOMEM);
return false;
}
uint32_t* imagebuf = (uint32_t *)guit->bitmap->get_buffer(nssprite->bitmap);
if (!imagebuf) {
- msg_data.error = messages_get("NoMemory");
- content_broadcast(c, CONTENT_MSG_ERROR, msg_data);
+ content_broadcast_errorcode(c, NSERROR_NOMEM);
return false;
}
unsigned char *spritebuf = (unsigned char *)sprite->image;
@@ -163,6 +160,14 @@ static bool nssprite_convert(struct content *c)
content_set_status(c, ""); /* Done: update status bar */
return true;
+
+ro_sprite_error:
+ if (ctx != NULL) {
+ rosprite_destroy_mem_context(ctx);
+ }
+ content_broadcast_errorcode(c, NSERROR_SPRITE_ERROR);
+
+ return false;
}
diff --git a/content/handlers/image/png.c b/content/handlers/image/png.c
index 0baf411bf..7a4ce3010 100644
--- a/content/handlers/image/png.c
+++ b/content/handlers/image/png.c
@@ -74,7 +74,7 @@ enum nspng_cberr {
*/
static void nspng_warning(png_structp png_ptr, png_const_charp warning_message)
{
- LOG("%s", warning_message);
+ NSLOG(netsurf, INFO, "%s", warning_message);
}
/**
@@ -82,7 +82,7 @@ static void nspng_warning(png_structp png_ptr, png_const_charp warning_message)
*/
static void nspng_error(png_structp png_ptr, png_const_charp error_message)
{
- LOG("%s", error_message);
+ NSLOG(netsurf, INFO, "%s", error_message);
longjmp(png_jmpbuf(png_ptr), CBERR_LIBPNG);
}
@@ -175,10 +175,8 @@ static void info_callback(png_structp png_s, png_infop info)
png_c->rowbytes = png_get_rowbytes(png_s, info);
png_c->interlace = (interlace == PNG_INTERLACE_ADAM7);
- LOG("size %li * %li, rowbytes %" PRIsizet,
- (unsigned long)width,
- (unsigned long)height,
- png_c->rowbytes);
+ NSLOG(netsurf, INFO, "size %li * %li, rowbytes %"PRIsizet,
+ (unsigned long)width, (unsigned long)height, png_c->rowbytes);
}
static void row_callback(png_structp png_s, png_bytep new_row,
@@ -240,14 +238,11 @@ static void end_callback(png_structp png_s, png_infop info)
static nserror nspng_create_png_data(nspng_content *png_c)
{
- union content_msg_data msg_data;
-
png_c->bitmap = NULL;
png_c->png = png_create_read_struct(PNG_LIBPNG_VER_STRING, 0, 0, 0);
if (png_c->png == NULL) {
- msg_data.error = messages_get("NoMemory");
- content_broadcast(&png_c->base, CONTENT_MSG_ERROR, msg_data);
+ content_broadcast_errorcode(&png_c->base, NSERROR_NOMEM);
return NSERROR_NOMEM;
}
@@ -257,19 +252,17 @@ static nserror nspng_create_png_data(nspng_content *png_c)
if (png_c->info == NULL) {
png_destroy_read_struct(&png_c->png, &png_c->info, 0);
- msg_data.error = messages_get("NoMemory");
- content_broadcast(&png_c->base, CONTENT_MSG_ERROR, msg_data);
+ content_broadcast_errorcode(&png_c->base, NSERROR_NOMEM);
return NSERROR_NOMEM;
}
if (setjmp(png_jmpbuf(png_c->png))) {
png_destroy_read_struct(&png_c->png, &png_c->info, 0);
- LOG("Failed to set callbacks");
+ NSLOG(netsurf, INFO, "Failed to set callbacks");
png_c->png = NULL;
png_c->info = NULL;
- msg_data.error = messages_get("PNGError");
- content_broadcast(&png_c->base, CONTENT_MSG_ERROR, msg_data);
+ content_broadcast_errorcode(&png_c->base, NSERROR_PNG_ERROR);
return NSERROR_NOMEM;
}
@@ -323,7 +316,6 @@ static bool nspng_process_data(struct content *c, const char *data,
unsigned int size)
{
nspng_content *png_c = (nspng_content *)c;
- union content_msg_data msg_data;
volatile bool ret = true;
if (png_c->no_process_data) {
@@ -356,14 +348,14 @@ static bool nspng_process_data(struct content *c, const char *data,
* up png conversion and signal the content
* error
*/
- LOG("Fatal PNG error during header, error content");
+ NSLOG(netsurf, INFO,
+ "Fatal PNG error during header, error content");
png_destroy_read_struct(&png_c->png, &png_c->info, 0);
png_c->png = NULL;
png_c->info = NULL;
- msg_data.error = messages_get("PNGError");
- content_broadcast(c, CONTENT_MSG_ERROR, msg_data);
+ content_broadcast_errorcode(c, NSERROR_PNG_ERROR);
ret = false;
diff --git a/content/handlers/image/rsvg.c b/content/handlers/image/rsvg.c
index 0665f217f..ca2d81eeb 100644
--- a/content/handlers/image/rsvg.c
+++ b/content/handlers/image/rsvg.c
@@ -62,17 +62,14 @@ typedef struct rsvg_content {
static nserror rsvg_create_svg_data(rsvg_content *c)
{
- union content_msg_data msg_data;
-
c->rsvgh = NULL;
c->cs = NULL;
c->ct = NULL;
c->bitmap = NULL;
if ((c->rsvgh = rsvg_handle_new()) == NULL) {
- LOG("rsvg_handle_new() returned NULL.");
- msg_data.error = messages_get("NoMemory");
- content_broadcast(&c->base, CONTENT_MSG_ERROR, msg_data);
+ NSLOG(netsurf, INFO, "rsvg_handle_new() returned NULL.");
+ content_broadcast_errorcode(&c->base, NSERROR_NOMEM);
return NSERROR_NOMEM;
}
@@ -115,14 +112,13 @@ static bool rsvg_process_data(struct content *c, const char *data,
unsigned int size)
{
rsvg_content *d = (rsvg_content *) c;
- union content_msg_data msg_data;
GError *err = NULL;
if (rsvg_handle_write(d->rsvgh, (const guchar *)data, (gsize)size,
&err) == FALSE) {
- LOG("rsvg_handle_write returned an error: %s", err->message);
- msg_data.error = err->message;
- content_broadcast(c, CONTENT_MSG_ERROR, msg_data);
+ NSLOG(netsurf, INFO,
+ "rsvg_handle_write returned an error: %s", err->message);
+ content_broadcast_errorcode(c, NSERROR_SVG_ERROR);
return false;
}
@@ -161,14 +157,13 @@ static inline void rsvg_argb_to_abgr(uint8_t *pixels,
static bool rsvg_convert(struct content *c)
{
rsvg_content *d = (rsvg_content *) c;
- union content_msg_data msg_data;
RsvgDimensionData rsvgsize;
GError *err = NULL;
if (rsvg_handle_close(d->rsvgh, &err) == FALSE) {
- LOG("rsvg_handle_close returned an error: %s", err->message);
- msg_data.error = err->message;
- content_broadcast(c, CONTENT_MSG_ERROR, msg_data);
+ NSLOG(netsurf, INFO,
+ "rsvg_handle_close returned an error: %s", err->message);
+ content_broadcast_errorcode(c, NSERROR_SVG_ERROR);
return false;
}
@@ -184,9 +179,9 @@ static bool rsvg_convert(struct content *c)
if ((d->bitmap = guit->bitmap->create(c->width, c->height,
BITMAP_NEW)) == NULL) {
- LOG("Failed to create bitmap for rsvg render.");
- msg_data.error = messages_get("NoMemory");
- content_broadcast(c, CONTENT_MSG_ERROR, msg_data);
+ NSLOG(netsurf, INFO,
+ "Failed to create bitmap for rsvg render.");
+ content_broadcast_errorcode(c, NSERROR_NOMEM);
return false;
}
@@ -195,16 +190,16 @@ static bool rsvg_convert(struct content *c)
CAIRO_FORMAT_ARGB32,
c->width, c->height,
guit->bitmap->get_rowstride(d->bitmap))) == NULL) {
- LOG("Failed to create Cairo image surface for rsvg render.");
- msg_data.error = messages_get("NoMemory");
- content_broadcast(c, CONTENT_MSG_ERROR, msg_data);
+ NSLOG(netsurf, INFO,
+ "Failed to create Cairo image surface for rsvg render.");
+ content_broadcast_errorcode(c, NSERROR_NOMEM);
return false;
}
if ((d->ct = cairo_create(d->cs)) == NULL) {
- LOG("Failed to create Cairo drawing context for rsvg render.");
- msg_data.error = messages_get("NoMemory");
- content_broadcast(c, CONTENT_MSG_ERROR, msg_data);
+ NSLOG(netsurf, INFO,
+ "Failed to create Cairo drawing context for rsvg render.");
+ content_broadcast_errorcode(c, NSERROR_NOMEM);
return false;
}
diff --git a/content/handlers/image/svg.c b/content/handlers/image/svg.c
index b34c6b7bb..2edc7bd08 100644
--- a/content/handlers/image/svg.c
+++ b/content/handlers/image/svg.c
@@ -49,8 +49,6 @@ typedef struct svg_content {
static nserror svg_create_svg_data(svg_content *c)
{
- union content_msg_data msg_data;
-
c->diagram = svgtiny_create();
if (c->diagram == NULL)
goto no_memory;
@@ -61,8 +59,7 @@ static nserror svg_create_svg_data(svg_content *c)
return NSERROR_OK;
no_memory:
- msg_data.error = messages_get("NoMemory");
- content_broadcast(&c->base, CONTENT_MSG_ERROR, msg_data);
+ content_broadcast_errorcode(&c->base, NSERROR_NOMEM);
return NSERROR_NOMEM;
}
diff --git a/content/handlers/javascript/duktape/Console.bnd b/content/handlers/javascript/duktape/Console.bnd
index 7b4de1ee3..c4c0c8399 100644
--- a/content/handlers/javascript/duktape/Console.bnd
+++ b/content/handlers/javascript/duktape/Console.bnd
@@ -34,7 +34,7 @@ write_log_entry(duk_context *ctx, unsigned int group, char logtype)
/* spcs... pfx strs... */
duk_concat(ctx, duk_get_top(ctx));
/* str */
- LOG("%s", duk_safe_to_string(ctx, 0));
+ NSLOG(netsurf, INFO, "%s", duk_safe_to_string(ctx, 0));
}
%};
diff --git a/content/handlers/javascript/duktape/Document.bnd b/content/handlers/javascript/duktape/Document.bnd
index 8658aec45..ece417d0d 100644
--- a/content/handlers/javascript/duktape/Document.bnd
+++ b/content/handlers/javascript/duktape/Document.bnd
@@ -41,11 +41,12 @@ method Document::write()
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);
+ NSLOG(netsurf, INFO,
+ "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);
+ NSLOG(netsurf, INFO, "error; no parser for htmlc: %p", htmlc);
return 0;
}
@@ -74,11 +75,12 @@ method Document::writeln()
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);
+ NSLOG(netsurf, INFO,
+ "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);
+ NSLOG(netsurf, INFO, "error; no parser for htmlc: %p", htmlc);
return 0;
}
@@ -311,8 +313,9 @@ getter Document::cookie()
return 1;
}
} else {
- LOG("error getting htmlc. parent node:%p htmlc:%p",
- priv->parent.node, htmlc);
+ NSLOG(netsurf, INFO,
+ "error getting htmlc. parent node:%p htmlc:%p",
+ priv->parent.node, htmlc);
}
return 0;
%}
diff --git a/content/handlers/javascript/duktape/Element.bnd b/content/handlers/javascript/duktape/Element.bnd
index d34e8c1eb..f7e33545f 100644
--- a/content/handlers/javascript/duktape/Element.bnd
+++ b/content/handlers/javascript/duktape/Element.bnd
@@ -183,7 +183,7 @@ getter Element::childElementCount()
element = NULL;
}
}
- LOG("I found %u of them", jsret);
+ NSLOG(netsurf, INFO, "I found %u of them", jsret);
duk_push_uint(ctx, jsret);
return 1;
%}
diff --git a/content/handlers/javascript/duktape/EventTarget.bnd b/content/handlers/javascript/duktape/EventTarget.bnd
index 92e2ac83e..d1f9e50d7 100644
--- a/content/handlers/javascript/duktape/EventTarget.bnd
+++ b/content/handlers/javascript/duktape/EventTarget.bnd
@@ -173,7 +173,8 @@ method EventTarget::addEventListener()
exc = dom_string_create((const uint8_t*)ev_ty, ev_ty_l,
&ev_ty_s);
if (exc != DOM_NO_ERR) {
- LOG("Oh dear, failed to create dom_string in addEventListener()");
+ NSLOG(netsurf, INFO,
+ "Oh dear, failed to create dom_string in addEventListener()");
return 0;
}
dukky_register_event_listener_for(
diff --git a/content/handlers/javascript/duktape/Location.bnd b/content/handlers/javascript/duktape/Location.bnd
index ca7e90509..a731730de 100644
--- a/content/handlers/javascript/duktape/Location.bnd
+++ b/content/handlers/javascript/duktape/Location.bnd
@@ -40,7 +40,7 @@ method Location::reload()
if (priv_win->win != NULL) {
browser_window_reload(priv_win->win, false);
} else {
- LOG("failed to get browser context");
+ NSLOG(netsurf, INFO, "failed to get browser context");
}
return 0;
%}
@@ -54,7 +54,7 @@ method Location::assign()
duk_pop(ctx);
if (priv_win == NULL || priv_win->win == NULL) {
- LOG("failed to get browser context");
+ NSLOG(netsurf, INFO, "failed to get browser context");
return 0;
}
@@ -83,7 +83,7 @@ method Location::replace()
duk_pop(ctx);
if (priv_win == NULL || priv_win->win == NULL) {
- LOG("failed to get browser context");
+ NSLOG(netsurf, INFO, "failed to get browser context");
return 0;
}
@@ -131,7 +131,7 @@ setter Location::href()
duk_pop(ctx);
if (priv_win == NULL || priv_win->win == NULL) {
- LOG("failed to get browser context");
+ NSLOG(netsurf, INFO, "failed to get browser context");
return 0;
}
diff --git a/content/handlers/javascript/duktape/Window.bnd b/content/handlers/javascript/duktape/Window.bnd
index 4af8c7aa9..3f680d47d 100644
--- a/content/handlers/javascript/duktape/Window.bnd
+++ b/content/handlers/javascript/duktape/Window.bnd
@@ -25,9 +25,10 @@ init Window(struct browser_window *win, struct html_content *htmlc)
/* element window */
priv->win = win;
priv->htmlc = htmlc;
- LOG("win=%p htmlc=%p", priv->win, priv->htmlc);
+ NSLOG(netsurf, INFO, "win=%p htmlc=%p", priv->win, priv->htmlc);
- LOG("URL is %s", nsurl_access(browser_window_get_url(priv->win)));
+ NSLOG(netsurf, INFO,
+ "URL is %s", nsurl_access(browser_window_get_url(priv->win)));
%}
prototype Window()
@@ -138,6 +139,6 @@ 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);
+ NSLOG(netsurf, INFO, "JS ALERT: %*s", (int)msg_len, msg);
return 0;
%}
diff --git a/content/handlers/javascript/duktape/duk_config.h b/content/handlers/javascript/duktape/duk_config.h
index 4a16a68da..379e9f647 100644
--- a/content/handlers/javascript/duktape/duk_config.h
+++ b/content/handlers/javascript/duktape/duk_config.h
@@ -525,6 +525,11 @@
#endif
#elif defined(DUK_F_WINDOWS)
/* --- Windows --- */
+/* Windows version can't obviously be determined at compile time,
+ * but _WIN32_WINNT indicates the minimum version targeted:
+ * - https://msdn.microsoft.com/en-us/library/6sehtctf.aspx
+ */
+
/* Initial fix: disable secure CRT related warnings when compiling Duktape
* itself (must be defined before including Windows headers). Don't define
* for user code including duktape.h.
@@ -535,17 +540,40 @@
/* Windows 32-bit and 64-bit are currently the same. */
/* MSVC does not have sys/param.h */
+
+#if defined(DUK_COMPILING_DUKTAPE)
+/* Only include when compiling Duktape to avoid polluting application build
+ * with a lot of unnecessary defines.
+ */
+#include <windows.h>
+#endif
+
+/* GetSystemTimePreciseAsFileTime() available from Windows 8:
+ * https://msdn.microsoft.com/en-us/library/windows/desktop/hh706895(v=vs.85).aspx
+ */
+#if defined(DUK_USE_DATE_NOW_WINDOWS_SUBMS) || defined(DUK_USE_DATE_NOW_WINDOWS)
+/* User forced provider. */
+#else
+#if defined(_WIN32_WINNT) && (_WIN32_WINNT >= 0x0602)
+#define DUK_USE_DATE_NOW_WINDOWS_SUBMS
+#else
#define DUK_USE_DATE_NOW_WINDOWS
+#endif
+#endif
+
#define DUK_USE_DATE_TZO_WINDOWS
+
/* Note: PRS and FMT are intentionally left undefined for now. This means
* there is no platform specific date parsing/formatting but there is still
* the ISO 8601 standard format.
*/
-#if defined(DUK_COMPILING_DUKTAPE)
-/* Only include when compiling Duktape to avoid polluting application build
- * with a lot of unnecessary defines.
+
+/* QueryPerformanceCounter() may go backwards in Windows XP, so enable for
+ * Vista and later: https://msdn.microsoft.com/en-us/library/windows/desktop/dn553408(v=vs.85).aspx#qpc_support_in_windows_versions
*/
-#include <windows.h>
+#if !defined(DUK_USE_GET_MONOTONIC_TIME_WINDOWS_QPC) && \
+ defined(_WIN32_WINNT) && (_WIN32_WINNT >= 0x0600)
+#define DUK_USE_GET_MONOTONIC_TIME_WINDOWS_QPC
#endif
#define DUK_USE_OS_STRING "windows"
@@ -667,6 +695,10 @@
#define DUK_USE_DATE_PRS_STRPTIME
#define DUK_USE_DATE_FMT_STRFTIME
+#if 0 /* XXX: safe condition? */
+#define DUK_USE_GET_MONOTONIC_TIME_CLOCK_GETTIME
+#endif
+
#define DUK_USE_OS_STRING "linux"
#elif defined(DUK_F_SUN)
/* --- Solaris --- */
@@ -818,12 +850,6 @@
#if !defined(DUK_USE_BYTEORDER)
#define DUK_USE_BYTEORDER 1
#endif
-/* XXX: This is technically not guaranteed because it's possible to configure
- * an x86 to require aligned accesses with Alignment Check (AC) flag.
- */
-#if !defined(DUK_USE_ALIGN_BY)
-#define DUK_USE_ALIGN_BY 1
-#endif
#define DUK_USE_PACKED_TVAL
#define DUK_F_PACKED_TVAL_PROVIDED
#elif defined(DUK_F_X64)
@@ -832,12 +858,6 @@
#if !defined(DUK_USE_BYTEORDER)
#define DUK_USE_BYTEORDER 1
#endif
-/* XXX: This is technically not guaranteed because it's possible to configure
- * an x86 to require aligned accesses with Alignment Check (AC) flag.
- */
-#if !defined(DUK_USE_ALIGN_BY)
-#define DUK_USE_ALIGN_BY 1
-#endif
#undef DUK_USE_PACKED_TVAL
#define DUK_F_PACKED_TVAL_PROVIDED
#elif defined(DUK_F_X32)
@@ -846,48 +866,30 @@
#if !defined(DUK_USE_BYTEORDER)
#define DUK_USE_BYTEORDER 1
#endif
-/* XXX: This is technically not guaranteed because it's possible to configure
- * an x86 to require aligned accesses with Alignment Check (AC) flag.
- */
-#if !defined(DUK_USE_ALIGN_BY)
-#define DUK_USE_ALIGN_BY 1
-#endif
#define DUK_USE_PACKED_TVAL
#define DUK_F_PACKED_TVAL_PROVIDED
#elif defined(DUK_F_ARM32)
/* --- ARM 32-bit --- */
#define DUK_USE_ARCH_STRING "arm32"
/* Byte order varies, so rely on autodetect. */
-#if !defined(DUK_USE_ALIGN_BY)
-#define DUK_USE_ALIGN_BY 4
-#endif
#define DUK_USE_PACKED_TVAL
#define DUK_F_PACKED_TVAL_PROVIDED
#elif defined(DUK_F_ARM64)
/* --- ARM 64-bit --- */
#define DUK_USE_ARCH_STRING "arm64"
/* Byte order varies, so rely on autodetect. */
-#if !defined(DUK_USE_ALIGN_BY)
-#define DUK_USE_ALIGN_BY 8
-#endif
#undef DUK_USE_PACKED_TVAL
#define DUK_F_PACKED_TVAL_PROVIDED
#elif defined(DUK_F_MIPS32)
/* --- MIPS 32-bit --- */
#define DUK_USE_ARCH_STRING "mips32"
/* MIPS byte order varies so rely on autodetection. */
-#if !defined(DUK_USE_ALIGN_BY)
-#define DUK_USE_ALIGN_BY 8
-#endif
#define DUK_USE_PACKED_TVAL
#define DUK_F_PACKED_TVAL_PROVIDED
#elif defined(DUK_F_MIPS64)
/* --- MIPS 64-bit --- */
#define DUK_USE_ARCH_STRING "mips64"
/* MIPS byte order varies so rely on autodetection. */
-#if !defined(DUK_USE_ALIGN_BY)
-#define DUK_USE_ALIGN_BY 8
-#endif
#undef DUK_USE_PACKED_TVAL
#define DUK_F_PACKED_TVAL_PROVIDED
#elif defined(DUK_F_PPC32)
@@ -896,9 +898,6 @@
#if !defined(DUK_USE_BYTEORDER)
#define DUK_USE_BYTEORDER 3
#endif
-#if !defined(DUK_USE_ALIGN_BY)
-#define DUK_USE_ALIGN_BY 8
-#endif
#define DUK_USE_PACKED_TVAL
#define DUK_F_PACKED_TVAL_PROVIDED
#elif defined(DUK_F_PPC64)
@@ -907,27 +906,18 @@
#if !defined(DUK_USE_BYTEORDER)
#define DUK_USE_BYTEORDER 3
#endif
-#if !defined(DUK_USE_ALIGN_BY)
-#define DUK_USE_ALIGN_BY 8
-#endif
#undef DUK_USE_PACKED_TVAL
#define DUK_F_PACKED_TVAL_PROVIDED
#elif defined(DUK_F_SPARC32)
/* --- SPARC 32-bit --- */
#define DUK_USE_ARCH_STRING "sparc32"
/* SPARC byte order varies so rely on autodetection. */
-#if !defined(DUK_USE_ALIGN_BY)
-#define DUK_USE_ALIGN_BY 8
-#endif
#define DUK_USE_PACKED_TVAL
#define DUK_F_PACKED_TVAL_PROVIDED
#elif defined(DUK_F_SPARC64)
/* --- SPARC 64-bit --- */
#define DUK_USE_ARCH_STRING "sparc64"
/* SPARC byte order varies so rely on autodetection. */
-#if !defined(DUK_USE_ALIGN_BY)
-#define DUK_USE_ALIGN_BY 8
-#endif
#undef DUK_USE_PACKED_TVAL
#define DUK_F_PACKED_TVAL_PROVIDED
#elif defined(DUK_F_SUPERH)
@@ -937,9 +927,6 @@
/* Based on 'make checkalign' there are no alignment requirements on
* Linux SH4, but align by 4 is probably a good basic default.
*/
-#if !defined(DUK_USE_ALIGN_BY)
-#define DUK_USE_ALIGN_BY 4
-#endif
#define DUK_USE_PACKED_TVAL
#define DUK_F_PACKED_TVAL_PROVIDED
#elif defined(DUK_F_M68K)
@@ -948,9 +935,6 @@
#if !defined(DUK_USE_BYTEORDER)
#define DUK_USE_BYTEORDER 3
#endif
-#if !defined(DUK_USE_ALIGN_BY)
-#define DUK_USE_ALIGN_BY 8
-#endif
#define DUK_USE_PACKED_TVAL
#define DUK_F_PACKED_TVAL_PROVIDED
#elif defined(DUK_F_EMSCRIPTEN)
@@ -959,9 +943,6 @@
#if !defined(DUK_USE_BYTEORDER)
#define DUK_USE_BYTEORDER 1
#endif
-#if !defined(DUK_USE_ALIGN_BY)
-#define DUK_USE_ALIGN_BY 8
-#endif
#undef DUK_USE_PACKED_TVAL
#define DUK_F_PACKED_TVAL_PROVIDED
#else
@@ -1307,7 +1288,16 @@
#endif
/* Avoid warning when doing DUK_UNREF(some_function). */
+#if defined(_MSC_VER) && (_MSC_VER < 1500)
+#pragma warning(disable: 4100 4101 4550 4551)
+#define DUK_UNREF(x)
+#else
#define DUK_UNREF(x) do { __pragma(warning(suppress:4100 4101 4550 4551)) (x); } while (0)
+#endif
+
+/* Older versions of MSVC don't support the LL/ULL suffix. */
+#define DUK_U64_CONSTANT(x) x##ui64
+#define DUK_I64_CONSTANT(x) x##i64
#elif defined(DUK_F_EMSCRIPTEN)
/* --- Emscripten --- */
#define DUK_NORETURN(decl) decl __attribute__((noreturn))
@@ -1535,12 +1525,14 @@
defined(DUK_F_BCC) || \
(defined(__WORDSIZE) && (__WORDSIZE == 32)) || \
((defined(DUK_F_OLD_SOLARIS) || defined(DUK_F_AIX) || \
- defined(DUK_F_HPUX)) && defined(_ILP32))
+ defined(DUK_F_HPUX)) && defined(_ILP32)) || \
+ defined(DUK_F_ARM32)
#define DUK_F_32BIT_PTRS
#elif defined(DUK_F_X64) || \
(defined(__WORDSIZE) && (__WORDSIZE == 64)) || \
((defined(DUK_F_OLD_SOLARIS) || defined(DUK_F_AIX) || \
- defined(DUK_F_HPUX)) && defined(_LP64))
+ defined(DUK_F_HPUX)) && defined(_LP64)) || \
+ defined(DUK_F_ARM64)
#define DUK_F_64BIT_PTRS
#else
/* not sure, not needed with C99 anyway */
@@ -1743,13 +1735,16 @@ typedef unsigned long long duk_uint64_t;
typedef signed long long duk_int64_t;
#endif
#endif
-#if !defined(DUK_F_HAVE_64BIT) && \
- (defined(DUK_F_MINGW) || defined(DUK_F_MSVC))
-/* Both MinGW and MSVC have a 64-bit type. */
+#if !defined(DUK_F_HAVE_64BIT) && defined(DUK_F_MINGW)
#define DUK_F_HAVE_64BIT
typedef unsigned long duk_uint64_t;
typedef signed long duk_int64_t;
#endif
+#if !defined(DUK_F_HAVE_64BIT) && defined(DUK_F_MSVC)
+#define DUK_F_HAVE_64BIT
+typedef unsigned __int64 duk_uint64_t;
+typedef signed __int64 duk_int64_t;
+#endif
#if !defined(DUK_F_HAVE_64BIT)
/* cannot detect 64-bit type, not always needed so don't error */
#endif
@@ -1957,8 +1952,8 @@ typedef duk_uint_fast16_t duk_small_uint_fast_t;
#define DUK_SMALL_UINT_FAST_MIN DUK_UINT_FAST16_MIN
#define DUK_SMALL_UINT_FAST_MAX DUK_UINT_FAST16_MAX
-/* Boolean values are represented with the platform 'int'. */
-typedef duk_small_int_t duk_bool_t;
+/* Boolean values are represented with the platform 'unsigned int'. */
+typedef duk_small_uint_t duk_bool_t;
#define DUK_BOOL_MIN DUK_SMALL_INT_MIN
#define DUK_BOOL_MAX DUK_SMALL_INT_MAX
@@ -2029,7 +2024,10 @@ typedef double duk_double_t;
#endif
#endif
-/* Type for public API calls. */
+/* Type used in public API declarations and user code. Typedef maps to
+ * 'struct duk_hthread' like the 'duk_hthread' typedef which is used
+ * exclusively in internals.
+ */
typedef struct duk_hthread duk_context;
/* Check whether we should use 64-bit integers or not.
@@ -2676,6 +2674,13 @@ typedef struct duk_hthread duk_context;
#undef DUK_USE_GCC_PRAGMAS
#endif
+#if !defined(DUK_U64_CONSTANT)
+#define DUK_U64_CONSTANT(x) x##ULL
+#endif
+#if !defined(DUK_I64_CONSTANT)
+#define DUK_I64_CONSTANT(x) x##LL
+#endif
+
/* Workaround for GH-323: avoid inlining control when compiling from
* multiple sources, as it causes compiler portability trouble.
*/
@@ -2773,6 +2778,9 @@ typedef struct duk_hthread duk_context;
#define DUK_USE_BUFFEROBJECT_SUPPORT
#undef DUK_USE_BUFLEN16
#define DUK_USE_BYTECODE_DUMP_SUPPORT
+#define DUK_USE_CACHE_ACTIVATION
+#define DUK_USE_CACHE_CATCHER
+#define DUK_USE_CALLSTACK_LIMIT 10000
#define DUK_USE_COMMONJS_MODULES
#define DUK_USE_COMPILER_RECLIMIT 2500
#define DUK_USE_COROUTINE_SUPPORT
@@ -2807,7 +2815,10 @@ typedef struct duk_hthread duk_context;
#define DUK_USE_ES6_PROXY
#define DUK_USE_ES6_REGEXP_SYNTAX
#define DUK_USE_ES6_UNICODE_ESCAPE
+#define DUK_USE_ES7
#define DUK_USE_ES7_EXP_OPERATOR
+#define DUK_USE_ES8
+#define DUK_USE_ES9
#define DUK_USE_ESBC_LIMITS
#define DUK_USE_ESBC_MAX_BYTES 2147418112L
#define DUK_USE_ESBC_MAX_LINENUMBER 2147418112L
@@ -2822,6 +2833,7 @@ typedef struct duk_hthread duk_context;
#undef DUK_USE_FASTINT
#define DUK_USE_FAST_REFCOUNT_DEFAULT
#undef DUK_USE_FATAL_HANDLER
+#define DUK_USE_FATAL_MAXLEN 128
#define DUK_USE_FINALIZER_SUPPORT
#undef DUK_USE_FINALIZER_TORTURE
#undef DUK_USE_FUNCPTR16
@@ -2831,6 +2843,7 @@ typedef struct duk_hthread duk_context;
#define DUK_USE_FUNC_FILENAME_PROPERTY
#define DUK_USE_FUNC_NAME_PROPERTY
#undef DUK_USE_GC_TORTURE
+#undef DUK_USE_GET_MONOTONIC_TIME
#undef DUK_USE_GET_RANDOM_DOUBLE
#undef DUK_USE_GLOBAL_BINDING
#define DUK_USE_GLOBAL_BUILTIN
@@ -2849,6 +2862,7 @@ typedef struct duk_hthread duk_context;
#define DUK_USE_HSTRING_ARRIDX
#define DUK_USE_HSTRING_CLEN
#undef DUK_USE_HSTRING_EXTDATA
+#define DUK_USE_HSTRING_LAZY_CLEN
#define DUK_USE_HTML_COMMENTS
#define DUK_USE_IDCHAR_FASTPATH
#undef DUK_USE_INJECT_HEAP_ALLOC_ERROR
@@ -2885,12 +2899,15 @@ typedef struct duk_hthread duk_context;
#undef DUK_USE_OBJSIZES16
#undef DUK_USE_PARANOID_ERRORS
#define DUK_USE_PC2LINE
+#define DUK_USE_PERFORMANCE_BUILTIN
#undef DUK_USE_PREFER_SIZE
+#undef DUK_USE_PROMISE_BUILTIN
#define DUK_USE_PROVIDE_DEFAULT_ALLOC_FUNCTIONS
#undef DUK_USE_REFCOUNT16
#define DUK_USE_REFCOUNT32
#define DUK_USE_REFERENCE_COUNTING
#define DUK_USE_REFLECT_BUILTIN
+#define DUK_USE_REGEXP_CANON_BITMAP
#undef DUK_USE_REGEXP_CANON_WORKAROUND
#define DUK_USE_REGEXP_COMPILER_RECLIMIT 10000
#define DUK_USE_REGEXP_EXECUTOR_RECLIMIT 10000
@@ -2925,6 +2942,10 @@ typedef struct duk_hthread duk_context;
#define DUK_USE_TRACEBACKS
#define DUK_USE_TRACEBACK_DEPTH 10
#define DUK_USE_USER_DECLARE() /* no user declarations */
+#define DUK_USE_VALSTACK_GROW_SHIFT 2
+#define DUK_USE_VALSTACK_LIMIT 1000000L
+#define DUK_USE_VALSTACK_SHRINK_CHECK_SHIFT 2
+#define DUK_USE_VALSTACK_SHRINK_SLACK_SHIFT 4
#undef DUK_USE_VALSTACK_UNSAFE
#define DUK_USE_VERBOSE_ERRORS
#define DUK_USE_VERBOSE_EXECUTOR_ERRORS
@@ -2958,11 +2979,13 @@ typedef struct duk_hthread duk_context;
#if defined(DUK_USE_DATE_GET_NOW)
/* External provider already defined. */
#elif defined(DUK_USE_DATE_NOW_GETTIMEOFDAY)
-#define DUK_USE_DATE_GET_NOW(ctx) duk_bi_date_get_now_gettimeofday((ctx))
+#define DUK_USE_DATE_GET_NOW(ctx) duk_bi_date_get_now_gettimeofday()
#elif defined(DUK_USE_DATE_NOW_TIME)
-#define DUK_USE_DATE_GET_NOW(ctx) duk_bi_date_get_now_time((ctx))
+#define DUK_USE_DATE_GET_NOW(ctx) duk_bi_date_get_now_time()
#elif defined(DUK_USE_DATE_NOW_WINDOWS)
-#define DUK_USE_DATE_GET_NOW(ctx) duk_bi_date_get_now_windows((ctx))
+#define DUK_USE_DATE_GET_NOW(ctx) duk_bi_date_get_now_windows()
+#elif defined(DUK_USE_DATE_NOW_WINDOWS_SUBMS)
+#define DUK_USE_DATE_GET_NOW(ctx) duk_bi_date_get_now_windows_subms()
#else
#error no provider for DUK_USE_DATE_GET_NOW()
#endif
@@ -2998,6 +3021,16 @@ typedef struct duk_hthread duk_context;
/* No provider for DUK_USE_DATE_FORMAT_STRING(), fall back to ISO 8601 only. */
#endif
+#if defined(DUK_USE_GET_MONOTONIC_TIME)
+/* External provider already defined. */
+#elif defined(DUK_USE_GET_MONOTONIC_TIME_CLOCK_GETTIME)
+#define DUK_USE_GET_MONOTONIC_TIME(ctx) duk_bi_date_get_monotonic_time_clock_gettime()
+#elif defined(DUK_USE_GET_MONOTONIC_TIME_WINDOWS_QPC)
+#define DUK_USE_GET_MONOTONIC_TIME(ctx) duk_bi_date_get_monotonic_time_windows_qpc()
+#else
+/* No provider for DUK_USE_GET_MONOTONIC_TIME(), fall back to DUK_USE_DATE_GET_NOW(). */
+#endif
+
#endif /* DUK_COMPILING_DUKTAPE */
/*
diff --git a/content/handlers/javascript/duktape/dukky.c b/content/handlers/javascript/duktape/dukky.c
index dd4378b7a..8cfeb3985 100644
--- a/content/handlers/javascript/duktape/dukky.c
+++ b/content/handlers/javascript/duktape/dukky.c
@@ -61,7 +61,8 @@ static duk_ret_t dukky_populate_object(duk_context *ctx, void *udata)
duk_get_prop(ctx, -2);
/* ... obj args prototab {proto/undefined} */
if (duk_is_undefined(ctx, -1)) {
- LOG("RuhRoh, couldn't find a prototype, HTMLUnknownElement it is");
+ NSLOG(netsurf, INFO,
+ "RuhRoh, couldn't find a prototype, HTMLUnknownElement it is");
duk_pop(ctx);
duk_push_string(ctx, PROTO_NAME(HTMLUNKNOWNELEMENT));
duk_get_prop(ctx, -2);
@@ -77,7 +78,7 @@ static duk_ret_t dukky_populate_object(duk_context *ctx, void *udata)
/* ... initfn obj[proto] args prototab proto */
duk_pop_2(ctx);
/* ... initfn obj[proto] args */
- LOG("Call the init function");
+ NSLOG(netsurf, INFO, "Call the init function");
duk_call(ctx, nargs + 1);
return 1; /* The object */
}
@@ -85,7 +86,7 @@ static duk_ret_t dukky_populate_object(duk_context *ctx, void *udata)
duk_ret_t dukky_create_object(duk_context *ctx, const char *name, int args)
{
duk_ret_t ret;
- LOG("name=%s nargs=%d", name+2, args);
+ NSLOG(netsurf, INFO, "name=%s nargs=%d", name + 2, args);
/* ... args */
duk_push_object(ctx);
/* ... args obj */
@@ -106,7 +107,7 @@ duk_ret_t dukky_create_object(duk_context *ctx, const char *name, int args)
if ((ret = duk_safe_call(ctx, dukky_populate_object, NULL, args + 3, 1))
!= DUK_EXEC_SUCCESS)
return ret;
- LOG("created");
+ NSLOG(netsurf, INFO, "created");
return DUK_EXEC_SUCCESS;
}
@@ -146,7 +147,7 @@ dukky_push_node_stacked(duk_context *ctx)
if (duk_safe_call(ctx, dukky_populate_object, NULL, 4, 1)
!= DUK_EXEC_SUCCESS) {
duk_set_top(ctx, top_at_fail);
- LOG("Boo and also hiss");
+ NSLOG(netsurf, INFO, "Boo and also hiss");
return false;
}
/* ... nodeptr klass nodes node */
@@ -384,13 +385,14 @@ dukky_push_node_klass(duk_context *ctx, struct dom_node *node)
err = dom_node_get_namespace(node, &namespace);
if (err != DOM_NO_ERR) {
/* Feck it, element */
- LOG("dom_node_get_namespace() failed");
+ NSLOG(netsurf, INFO,
+ "dom_node_get_namespace() failed");
duk_push_string(ctx, PROTO_NAME(ELEMENT));
break;
}
if (namespace == NULL) {
/* No namespace, -> element */
- LOG("no namespace");
+ NSLOG(netsurf, INFO, "no namespace");
duk_push_string(ctx, PROTO_NAME(ELEMENT));
break;
}
@@ -561,7 +563,7 @@ nserror js_newcontext(int timeout, jscallback *cb, void *cbctx,
duk_context *ctx;
jscontext *ret = calloc(1, sizeof(*ret));
*jsctx = NULL;
- LOG("Creating new duktape javascript context");
+ NSLOG(netsurf, INFO, "Creating new duktape javascript context");
if (ret == NULL) return NSERROR_NOMEM;
ctx = ret->ctx = duk_create_heap(
dukky_alloc_function,
@@ -584,7 +586,7 @@ nserror js_newcontext(int timeout, jscallback *cb, void *cbctx,
void js_destroycontext(jscontext *ctx)
{
- LOG("Destroying duktape javascript context");
+ NSLOG(netsurf, INFO, "Destroying duktape javascript context");
duk_destroy_heap(ctx->ctx);
free(ctx);
}
@@ -593,7 +595,9 @@ jsobject *js_newcompartment(jscontext *ctx, void *win_priv, void *doc_priv)
{
assert(ctx != NULL);
/* Pop any active thread off */
- LOG("Yay, new compartment, win_priv=%p, doc_priv=%p", win_priv, doc_priv);
+ NSLOG(netsurf, INFO,
+ "Yay, new compartment, win_priv=%p, doc_priv=%p", win_priv,
+ doc_priv);
duk_set_top(ctx->ctx, 0);
duk_push_thread(ctx->ctx);
ctx->thread = duk_require_context(ctx->ctx, -1);
@@ -659,15 +663,17 @@ bool js_exec(jscontext *ctx, const char *txt, size_t txtlen)
duk_get_prop_string(CTX, 0, "fileName");
duk_get_prop_string(CTX, 0, "lineNumber");
duk_get_prop_string(CTX, 0, "stack");
- LOG("Uncaught error in JS: %s: %s", duk_safe_to_string(CTX, 1),
- duk_safe_to_string(CTX, 2));
- LOG(" was at: %s line %s", duk_safe_to_string(CTX, 3),
- duk_safe_to_string(CTX, 4));
- LOG(" Stack trace: %s", duk_safe_to_string(CTX, 5));
+ NSLOG(netsurf, INFO, "Uncaught error in JS: %s: %s",
+ duk_safe_to_string(CTX, 1), duk_safe_to_string(CTX, 2));
+ NSLOG(netsurf, INFO, " was at: %s line %s",
+ duk_safe_to_string(CTX, 3), duk_safe_to_string(CTX, 4));
+ NSLOG(netsurf, INFO, " Stack trace: %s",
+ duk_safe_to_string(CTX, 5));
return false;
}
if (duk_get_top(CTX) == 0) duk_push_boolean(CTX, false);
- LOG("Returning %s", duk_get_boolean(CTX, 0) ? "true" : "false");
+ NSLOG(netsurf, INFO, "Returning %s",
+ duk_get_boolean(CTX, 0) ? "true" : "false");
return duk_get_boolean(CTX, 0);
}
@@ -782,7 +788,8 @@ bool dukky_get_current_value_of_event_handler(duk_context *ctx,
/* ... node fullhandlersrc filename */
if (duk_pcompile(ctx, DUK_COMPILE_FUNCTION) != 0) {
/* ... node err */
- LOG("Unable to proceed with handler, could not compile");
+ NSLOG(netsurf, INFO,
+ "Unable to proceed with handler, could not compile");
duk_pop_2(ctx);
return false;
}
@@ -816,29 +823,27 @@ static void dukky_generic_event_handler(dom_event *evt, void *pw)
duk_get_memory_functions(ctx, &funcs);
jsctx = funcs.udata;
- LOG("WOOP WOOP, An event:");
+ NSLOG(netsurf, INFO, "WOOP WOOP, An event:");
exc = dom_event_get_type(evt, &name);
if (exc != DOM_NO_ERR) {
- LOG("Unable to find the event name");
+ NSLOG(netsurf, INFO, "Unable to find the event name");
return;
}
- LOG("Event's name is %*s",
- dom_string_length(name), dom_string_data(name));
+ NSLOG(netsurf, INFO, "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");
+ NSLOG(netsurf, INFO, "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);
+ NSLOG(netsurf, INFO, "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");
+ NSLOG(netsurf, INFO, "Unable to find the event target");
return;
}
@@ -852,7 +857,8 @@ static void dukky_generic_event_handler(dom_event *evt, void *pw)
if (dukky_push_node(ctx, (dom_node *)targ) == false) {
dom_string_unref(name);
dom_node_unref(targ);
- LOG("Unable to push JS node representation?!");
+ NSLOG(netsurf, INFO,
+ "Unable to push JS node representation?!");
return;
}
/* ... node */
@@ -868,21 +874,26 @@ static void dukky_generic_event_handler(dom_event *evt, void *pw)
if (duk_pcall_method(ctx, 1) != 0) {
/* Failed to run the method */
/* ... err */
- LOG("OH NOES! An error running a callback. Meh.");
+ NSLOG(netsurf, INFO,
+ "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");
+ NSLOG(netsurf, INFO,
+ "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));
+ NSLOG(netsurf, INFO, "Uncaught error in JS: %s: %s",
+ duk_safe_to_string(ctx, -5),
+ duk_safe_to_string(ctx, -4));
+ NSLOG(netsurf, INFO, " was at: %s line %s",
+ duk_safe_to_string(ctx, -3),
+ duk_safe_to_string(ctx, -2));
+ NSLOG(netsurf, INFO, " Stack trace: %s",
+ duk_safe_to_string(ctx, -1));
duk_pop_n(ctx, 6);
/* ... */
@@ -962,21 +973,27 @@ handle_extras:
if (duk_pcall_method(ctx, 1) != 0) {
/* Failed to run the method */
/* ... copy handler err */
- LOG("OH NOES! An error running a callback. Meh.");
+ NSLOG(netsurf, INFO,
+ "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");
+ NSLOG(netsurf, INFO,
+ "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));
+ NSLOG(netsurf, INFO, "Uncaught error in JS: %s: %s",
+ duk_safe_to_string(ctx, -5),
+ duk_safe_to_string(ctx, -4));
+ NSLOG(netsurf, INFO,
+ " was at: %s line %s",
+ duk_safe_to_string(ctx, -3),
+ duk_safe_to_string(ctx, -2));
+ NSLOG(netsurf, INFO, " Stack trace: %s",
+ duk_safe_to_string(ctx, -1));
duk_pop_n(ctx, 7);
/* ... copy */
@@ -1034,11 +1051,12 @@ void dukky_register_event_listener_for(duk_context *ctx,
exc = dom_event_target_add_event_listener(
ele, name, listen, capture);
if (exc != DOM_NO_ERR) {
- LOG("Unable to register listener for %p.%*s",
- ele, dom_string_length(name), dom_string_data(name));
+ NSLOG(netsurf, INFO,
+ "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));
+ NSLOG(netsurf, INFO, "have registered listener for %p.%*s",
+ ele, dom_string_length(name), dom_string_data(name));
}
dom_event_listener_unref(listen);
}
@@ -1205,7 +1223,8 @@ bool js_fire_event(jscontext *ctx, const char *type, struct dom_document *doc, s
dom_event *evt;
dom_event_target *body;
- LOG("Event: %s (doc=%p, target=%p)", type, doc, target);
+ NSLOG(netsurf, INFO, "Event: %s (doc=%p, target=%p)", type, doc,
+ target);
/** @todo Make this more generic, this only handles load and only
* targetting the window, so that we actually stand a chance of
@@ -1276,18 +1295,22 @@ bool js_fire_event(jscontext *ctx, const char *type, struct dom_document *doc, s
if (duk_pcall_method(CTX, 1) != 0) {
/* Failed to run the handler */
/* ... err */
- LOG("OH NOES! An error running a handler. Meh.");
+ NSLOG(netsurf, INFO,
+ "OH NOES! An error running a handler. Meh.");
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));
+ NSLOG(netsurf, INFO, "Uncaught error in JS: %s: %s",
+ duk_safe_to_string(CTX, -5),
+ duk_safe_to_string(CTX, -4));
+ NSLOG(netsurf, INFO, " was at: %s line %s",
+ duk_safe_to_string(CTX, -3),
+ duk_safe_to_string(CTX, -2));
+ NSLOG(netsurf, INFO, " Stack trace: %s",
+ duk_safe_to_string(CTX, -1));
duk_pop_n(CTX, 6);
/* ... */
diff --git a/content/handlers/javascript/duktape/dukky.h b/content/handlers/javascript/duktape/dukky.h
index b5809aa08..435e0c305 100644
--- a/content/handlers/javascript/duktape/dukky.h
+++ b/content/handlers/javascript/duktape/dukky.h
@@ -26,11 +26,13 @@
#define DUKKY_H
#ifdef JS_DEBUG
-# define JS_LOG(format, args...) LOG(format , ##args)
+# define JS_LOG(format, args...) NSLOG(netsurf, INFO, format , ##args)
#else
# define JS_LOG(format, ...) ((void) 0)
#endif
+#define LOG(format, args...) NSLOG(netsurf, INFO, format , ##args)
+
duk_ret_t dukky_create_object(duk_context *ctx, const char *name, int args);
duk_bool_t dukky_push_node_stacked(duk_context *ctx);
duk_bool_t dukky_push_node(duk_context *ctx, struct dom_node *node);
diff --git a/content/handlers/javascript/duktape/duktape.c b/content/handlers/javascript/duktape/duktape.c
index c031de021..52b9e1309 100644
--- a/content/handlers/javascript/duktape/duktape.c
+++ b/content/handlers/javascript/duktape/duktape.c
@@ -1,7 +1,7 @@
/* Omit from static analysis. */
#ifndef __clang_analyzer__
/*
- * Single source autogenerated distributable for Duktape 2.1.0.
+ * Single source autogenerated distributable for Duktape 2.2.0.
*
* Git commit external (external).
* Git branch external.
@@ -86,6 +86,9 @@
* * Remko Tron\u00e7on (https://el-tramo.be)
* * Romero Malaquias (rbsm@ic.ufal.br)
* * Michael Drake <michael.drake@codethink.co.uk>
+* * Steven Don (https://github.com/shdon)
+* * Simon Stone (https://github.com/sstone1)
+* * \J. McC. (https://github.com/jmhmccr)
*
* Other contributions
* ===================
@@ -410,47 +413,47 @@ typedef union duk_double_union duk_double_union;
#if defined(DUK_USE_DOUBLE_ME)
/* Macros for 64-bit ops + mixed endian doubles. */
#define DUK__DBLUNION_SET_NAN_FULL(u) do { \
- (u)->ull[DUK_DBL_IDX_ULL0] = 0x000000007ff80000ULL; \
+ (u)->ull[DUK_DBL_IDX_ULL0] = DUK_U64_CONSTANT(0x000000007ff80000); \
} while (0)
#define DUK__DBLUNION_IS_NAN_FULL(u) \
- ((((u)->ull[DUK_DBL_IDX_ULL0] & 0x000000007ff00000ULL) == 0x000000007ff00000ULL) && \
- ((((u)->ull[DUK_DBL_IDX_ULL0]) & 0xffffffff000fffffULL) != 0))
+ ((((u)->ull[DUK_DBL_IDX_ULL0] & DUK_U64_CONSTANT(0x000000007ff00000)) == DUK_U64_CONSTANT(0x000000007ff00000)) && \
+ ((((u)->ull[DUK_DBL_IDX_ULL0]) & DUK_U64_CONSTANT(0xffffffff000fffff)) != 0))
#define DUK__DBLUNION_IS_NORMALIZED_NAN_FULL(u) \
- ((u)->ull[DUK_DBL_IDX_ULL0] == 0x000000007ff80000ULL)
+ ((u)->ull[DUK_DBL_IDX_ULL0] == DUK_U64_CONSTANT(0x000000007ff80000))
#define DUK__DBLUNION_IS_ANYINF(u) \
- (((u)->ull[DUK_DBL_IDX_ULL0] & 0xffffffff7fffffffULL) == 0x000000007ff00000ULL)
+ (((u)->ull[DUK_DBL_IDX_ULL0] & DUK_U64_CONSTANT(0xffffffff7fffffff)) == DUK_U64_CONSTANT(0x000000007ff00000))
#define DUK__DBLUNION_IS_POSINF(u) \
- ((u)->ull[DUK_DBL_IDX_ULL0] == 0x000000007ff00000ULL)
+ ((u)->ull[DUK_DBL_IDX_ULL0] == DUK_U64_CONSTANT(0x000000007ff00000))
#define DUK__DBLUNION_IS_NEGINF(u) \
- ((u)->ull[DUK_DBL_IDX_ULL0] == 0x00000000fff00000ULL)
+ ((u)->ull[DUK_DBL_IDX_ULL0] == DUK_U64_CONSTANT(0x00000000fff00000))
#define DUK__DBLUNION_IS_ANYZERO(u) \
- (((u)->ull[DUK_DBL_IDX_ULL0] & 0xffffffff7fffffffULL) == 0x0000000000000000ULL)
+ (((u)->ull[DUK_DBL_IDX_ULL0] & DUK_U64_CONSTANT(0xffffffff7fffffff)) == DUK_U64_CONSTANT(0x0000000000000000))
#define DUK__DBLUNION_IS_POSZERO(u) \
- ((u)->ull[DUK_DBL_IDX_ULL0] == 0x0000000000000000ULL)
+ ((u)->ull[DUK_DBL_IDX_ULL0] == DUK_U64_CONSTANT(0x0000000000000000))
#define DUK__DBLUNION_IS_NEGZERO(u) \
- ((u)->ull[DUK_DBL_IDX_ULL0] == 0x0000000080000000ULL)
+ ((u)->ull[DUK_DBL_IDX_ULL0] == DUK_U64_CONSTANT(0x0000000080000000))
#else
/* Macros for 64-bit ops + big/little endian doubles. */
#define DUK__DBLUNION_SET_NAN_FULL(u) do { \
- (u)->ull[DUK_DBL_IDX_ULL0] = 0x7ff8000000000000ULL; \
+ (u)->ull[DUK_DBL_IDX_ULL0] = DUK_U64_CONSTANT(0x7ff8000000000000); \
} while (0)
#define DUK__DBLUNION_IS_NAN_FULL(u) \
- ((((u)->ull[DUK_DBL_IDX_ULL0] & 0x7ff0000000000000ULL) == 0x7ff0000000000000UL) && \
- ((((u)->ull[DUK_DBL_IDX_ULL0]) & 0x000fffffffffffffULL) != 0))
+ ((((u)->ull[DUK_DBL_IDX_ULL0] & DUK_U64_CONSTANT(0x7ff0000000000000)) == DUK_U64_CONSTANT(0x7ff0000000000000)) && \
+ ((((u)->ull[DUK_DBL_IDX_ULL0]) & DUK_U64_CONSTANT(0x000fffffffffffff)) != 0))
#define DUK__DBLUNION_IS_NORMALIZED_NAN_FULL(u) \
- ((u)->ull[DUK_DBL_IDX_ULL0] == 0x7ff8000000000000ULL)
+ ((u)->ull[DUK_DBL_IDX_ULL0] == DUK_U64_CONSTANT(0x7ff8000000000000))
#define DUK__DBLUNION_IS_ANYINF(u) \
- (((u)->ull[DUK_DBL_IDX_ULL0] & 0x7fffffffffffffffULL) == 0x7ff0000000000000ULL)
+ (((u)->ull[DUK_DBL_IDX_ULL0] & DUK_U64_CONSTANT(0x7fffffffffffffff)) == DUK_U64_CONSTANT(0x7ff0000000000000))
#define DUK__DBLUNION_IS_POSINF(u) \
- ((u)->ull[DUK_DBL_IDX_ULL0] == 0x7ff0000000000000ULL)
+ ((u)->ull[DUK_DBL_IDX_ULL0] == DUK_U64_CONSTANT(0x7ff0000000000000))
#define DUK__DBLUNION_IS_NEGINF(u) \
- ((u)->ull[DUK_DBL_IDX_ULL0] == 0xfff0000000000000ULL)
+ ((u)->ull[DUK_DBL_IDX_ULL0] == DUK_U64_CONSTANT(0xfff0000000000000))
#define DUK__DBLUNION_IS_ANYZERO(u) \
- (((u)->ull[DUK_DBL_IDX_ULL0] & 0x7fffffffffffffffULL) == 0x0000000000000000ULL)
+ (((u)->ull[DUK_DBL_IDX_ULL0] & DUK_U64_CONSTANT(0x7fffffffffffffff)) == DUK_U64_CONSTANT(0x0000000000000000))
#define DUK__DBLUNION_IS_POSZERO(u) \
- ((u)->ull[DUK_DBL_IDX_ULL0] == 0x0000000000000000ULL)
+ ((u)->ull[DUK_DBL_IDX_ULL0] == DUK_U64_CONSTANT(0x0000000000000000))
#define DUK__DBLUNION_IS_NEGZERO(u) \
- ((u)->ull[DUK_DBL_IDX_ULL0] == 0x8000000000000000ULL)
+ ((u)->ull[DUK_DBL_IDX_ULL0] == DUK_U64_CONSTANT(0x8000000000000000))
#endif
#else /* DUK_USE_64BIT_OPS */
/* Macros for no 64-bit ops, any endianness. */
@@ -597,7 +600,7 @@ typedef union duk_double_union duk_double_union;
/* Some sign bit helpers. */
#if defined(DUK_USE_64BIT_OPS)
-#define DUK_DBLUNION_HAS_SIGNBIT(u) (((u)->ull[DUK_DBL_IDX_ULL0] & 0x8000000000000000ULL) != 0)
+#define DUK_DBLUNION_HAS_SIGNBIT(u) (((u)->ull[DUK_DBL_IDX_ULL0] & DUK_U64_CONSTANT(0x8000000000000000)) != 0)
#define DUK_DBLUNION_GET_SIGNBIT(u) (((u)->ull[DUK_DBL_IDX_ULL0] >> 63U))
#else
#define DUK_DBLUNION_HAS_SIGNBIT(u) (((u)->ui[DUK_DBL_IDX_UI0] & 0x80000000UL) != 0)
@@ -706,10 +709,12 @@ struct duk_hstring_external;
struct duk_hobject;
struct duk_hcompfunc;
struct duk_hnatfunc;
+struct duk_hboundfunc;
struct duk_hthread;
struct duk_hbufobj;
struct duk_hdecenv;
struct duk_hobjenv;
+struct duk_hproxy;
struct duk_hbuffer;
struct duk_hbuffer_fixed;
struct duk_hbuffer_dynamic;
@@ -764,10 +769,12 @@ typedef struct duk_hstring_external duk_hstring_external;
typedef struct duk_hobject duk_hobject;
typedef struct duk_hcompfunc duk_hcompfunc;
typedef struct duk_hnatfunc duk_hnatfunc;
+typedef struct duk_hboundfunc duk_hboundfunc;
typedef struct duk_hthread duk_hthread;
typedef struct duk_hbufobj duk_hbufobj;
typedef struct duk_hdecenv duk_hdecenv;
typedef struct duk_hobjenv duk_hobjenv;
+typedef struct duk_hproxy duk_hproxy;
typedef struct duk_hbuffer duk_hbuffer;
typedef struct duk_hbuffer_fixed duk_hbuffer_fixed;
typedef struct duk_hbuffer_dynamic duk_hbuffer_dynamic;
@@ -942,7 +949,7 @@ typedef struct {
} while (0)
#else
#define DUK__TVAL_SET_I48(tv,i) do { \
- (tv)->ull[DUK_DBL_IDX_ULL0] = (((duk_uint64_t) DUK_TAG_FASTINT) << 48) | (((duk_uint64_t) (i)) & 0x0000ffffffffffffULL); \
+ (tv)->ull[DUK_DBL_IDX_ULL0] = (((duk_uint64_t) DUK_TAG_FASTINT) << 48) | (((duk_uint64_t) (i)) & DUK_U64_CONSTANT(0x0000ffffffffffff)); \
} while (0)
#define DUK__TVAL_SET_U32(tv,i) do { \
(tv)->ull[DUK_DBL_IDX_ULL0] = (((duk_uint64_t) DUK_TAG_FASTINT) << 48) | (duk_uint64_t) (i); \
@@ -1039,7 +1046,7 @@ typedef struct {
#define DUK_TVAL_SET_TVAL(tv,x) do { *(tv) = *(x); } while (0)
/* getters */
-#define DUK_TVAL_GET_BOOLEAN(tv) ((duk_small_int_t) (tv)->us[DUK_DBL_IDX_US1])
+#define DUK_TVAL_GET_BOOLEAN(tv) ((duk_small_uint_t) (tv)->us[DUK_DBL_IDX_US1])
#if defined(DUK_USE_FASTINT)
#define DUK_TVAL_GET_DOUBLE(tv) ((tv)->d)
#define DUK_TVAL_GET_FASTINT(tv) DUK__TVAL_GET_FASTINT((tv))
@@ -1055,7 +1062,7 @@ typedef struct {
(out_fp) = (duk_c_function) (tv)->ui[DUK_DBL_IDX_UI1]; \
} while (0)
#define DUK_TVAL_GET_LIGHTFUNC_FUNCPTR(tv) ((duk_c_function) ((tv)->ui[DUK_DBL_IDX_UI1]))
-#define DUK_TVAL_GET_LIGHTFUNC_FLAGS(tv) (((duk_small_int_t) (tv)->ui[DUK_DBL_IDX_UI0]) & 0xffffUL)
+#define DUK_TVAL_GET_LIGHTFUNC_FLAGS(tv) (((duk_small_uint_t) (tv)->ui[DUK_DBL_IDX_UI0]) & 0xffffUL)
#define DUK_TVAL_GET_STRING(tv) ((duk_hstring *) (tv)->vp[DUK_DBL_IDX_VP1])
#define DUK_TVAL_GET_OBJECT(tv) ((duk_hobject *) (tv)->vp[DUK_DBL_IDX_VP1])
#define DUK_TVAL_GET_BUFFER(tv) ((duk_hbuffer *) (tv)->vp[DUK_DBL_IDX_VP1])
@@ -1193,7 +1200,7 @@ typedef struct {
duk_tval *duk__tv; \
duk__tv = (tv); \
duk__tv->t = DUK_TAG_BOOLEAN; \
- duk__tv->v.i = (val); \
+ duk__tv->v.i = (duk_small_int_t) (val); \
} while (0)
#if defined(DUK_USE_FASTINT)
@@ -1324,7 +1331,7 @@ typedef struct {
#define DUK_TVAL_SET_TVAL(tv,x) do { *(tv) = *(x); } while (0)
/* getters */
-#define DUK_TVAL_GET_BOOLEAN(tv) ((tv)->v.i)
+#define DUK_TVAL_GET_BOOLEAN(tv) ((duk_small_uint_t) (tv)->v.i)
#if defined(DUK_USE_FASTINT)
#define DUK_TVAL_GET_DOUBLE(tv) ((tv)->v.d)
#define DUK_TVAL_GET_FASTINT(tv) ((tv)->v.fi)
@@ -1351,7 +1358,7 @@ typedef struct {
(out_fp) = (tv)->v.lightfunc; \
} while (0)
#define DUK_TVAL_GET_LIGHTFUNC_FUNCPTR(tv) ((tv)->v.lightfunc)
-#define DUK_TVAL_GET_LIGHTFUNC_FLAGS(tv) ((duk_uint32_t) ((tv)->v_extra))
+#define DUK_TVAL_GET_LIGHTFUNC_FLAGS(tv) ((duk_small_uint_t) ((tv)->v_extra))
#define DUK_TVAL_GET_STRING(tv) ((tv)->v.hstring)
#define DUK_TVAL_GET_OBJECT(tv) ((tv)->v.hobject)
#define DUK_TVAL_GET_BUFFER(tv) ((tv)->v.hbuffer)
@@ -1416,11 +1423,11 @@ DUK_INTERNAL_DECL DUK_INLINE duk_double_t duk_tval_get_number_unpacked_fastint(d
#define DUK_LFUNC_FLAGS_GET_MAGIC(lf_flags) \
((duk_int32_t) (duk_int8_t) (((duk_uint16_t) (lf_flags)) >> 8))
#define DUK_LFUNC_FLAGS_GET_LENGTH(lf_flags) \
- (((lf_flags) >> 4) & 0x0f)
+ (((lf_flags) >> 4) & 0x0fU)
#define DUK_LFUNC_FLAGS_GET_NARGS(lf_flags) \
- ((lf_flags) & 0x0f)
+ ((lf_flags) & 0x0fU)
#define DUK_LFUNC_FLAGS_PACK(magic,length,nargs) \
- (((magic) & 0xff) << 8) | ((length) << 4) | (nargs)
+ ((((duk_small_uint_t) (magic)) & 0xffU) << 8) | ((length) << 4) | (nargs)
#define DUK_LFUNC_NARGS_VARARGS 0x0f /* varargs marker */
#define DUK_LFUNC_NARGS_MIN 0x00
@@ -1432,8 +1439,8 @@ DUK_INTERNAL_DECL DUK_INLINE duk_double_t duk_tval_get_number_unpacked_fastint(d
/* fastint constants etc */
#if defined(DUK_USE_FASTINT)
-#define DUK_FASTINT_MIN (-0x800000000000LL)
-#define DUK_FASTINT_MAX 0x7fffffffffffLL
+#define DUK_FASTINT_MIN (DUK_I64_CONSTANT(-0x800000000000))
+#define DUK_FASTINT_MAX (DUK_I64_CONSTANT(0x7fffffffffff))
#define DUK_FASTINT_BITS 48
DUK_INTERNAL_DECL DUK_INLINE void duk_tval_set_number_chkfast_fast(duk_tval *tv, duk_double_t x);
@@ -1662,302 +1669,296 @@ DUK_INTERNAL_DECL void duk_tval_set_number_chkfast_slow(duk_tval *tv, duk_double
#define DUK_STRIDX_CALLER 69 /* 'caller' */
#define DUK_HEAP_STRING_CALLER(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_CALLER)
#define DUK_HTHREAD_STRING_CALLER(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_CALLER)
-#define DUK_STRIDX_DELETE_PROPERTY 70 /* 'deleteProperty' */
+#define DUK_STRIDX_APPLY 70 /* 'apply' */
+#define DUK_HEAP_STRING_APPLY(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_APPLY)
+#define DUK_HTHREAD_STRING_APPLY(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_APPLY)
+#define DUK_STRIDX_CONSTRUCT 71 /* 'construct' */
+#define DUK_HEAP_STRING_CONSTRUCT(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_CONSTRUCT)
+#define DUK_HTHREAD_STRING_CONSTRUCT(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_CONSTRUCT)
+#define DUK_STRIDX_DELETE_PROPERTY 72 /* 'deleteProperty' */
#define DUK_HEAP_STRING_DELETE_PROPERTY(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_DELETE_PROPERTY)
#define DUK_HTHREAD_STRING_DELETE_PROPERTY(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_DELETE_PROPERTY)
-#define DUK_STRIDX_GET 71 /* 'get' */
+#define DUK_STRIDX_GET 73 /* 'get' */
#define DUK_HEAP_STRING_GET(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_GET)
#define DUK_HTHREAD_STRING_GET(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_GET)
-#define DUK_STRIDX_HAS 72 /* 'has' */
+#define DUK_STRIDX_HAS 74 /* 'has' */
#define DUK_HEAP_STRING_HAS(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_HAS)
#define DUK_HTHREAD_STRING_HAS(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_HAS)
-#define DUK_STRIDX_OWN_KEYS 73 /* 'ownKeys' */
+#define DUK_STRIDX_OWN_KEYS 75 /* 'ownKeys' */
#define DUK_HEAP_STRING_OWN_KEYS(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_OWN_KEYS)
#define DUK_HTHREAD_STRING_OWN_KEYS(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_OWN_KEYS)
-#define DUK_STRIDX_SET_PROTOTYPE_OF 74 /* 'setPrototypeOf' */
+#define DUK_STRIDX_SET_PROTOTYPE_OF 76 /* 'setPrototypeOf' */
#define DUK_HEAP_STRING_SET_PROTOTYPE_OF(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_SET_PROTOTYPE_OF)
#define DUK_HTHREAD_STRING_SET_PROTOTYPE_OF(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_SET_PROTOTYPE_OF)
-#define DUK_STRIDX___PROTO__ 75 /* '__proto__' */
+#define DUK_STRIDX___PROTO__ 77 /* '__proto__' */
#define DUK_HEAP_STRING___PROTO__(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX___PROTO__)
#define DUK_HTHREAD_STRING___PROTO__(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX___PROTO__)
-#define DUK_STRIDX_TO_STRING 76 /* 'toString' */
+#define DUK_STRIDX_TO_STRING 78 /* 'toString' */
#define DUK_HEAP_STRING_TO_STRING(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_TO_STRING)
#define DUK_HTHREAD_STRING_TO_STRING(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_TO_STRING)
-#define DUK_STRIDX_TO_JSON 77 /* 'toJSON' */
+#define DUK_STRIDX_TO_JSON 79 /* 'toJSON' */
#define DUK_HEAP_STRING_TO_JSON(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_TO_JSON)
#define DUK_HTHREAD_STRING_TO_JSON(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_TO_JSON)
-#define DUK_STRIDX_TYPE 78 /* 'type' */
+#define DUK_STRIDX_TYPE 80 /* 'type' */
#define DUK_HEAP_STRING_TYPE(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_TYPE)
#define DUK_HTHREAD_STRING_TYPE(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_TYPE)
-#define DUK_STRIDX_DATA 79 /* 'data' */
+#define DUK_STRIDX_DATA 81 /* 'data' */
#define DUK_HEAP_STRING_DATA(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_DATA)
#define DUK_HTHREAD_STRING_DATA(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_DATA)
-#define DUK_STRIDX_LENGTH 80 /* 'length' */
+#define DUK_STRIDX_LENGTH 82 /* 'length' */
#define DUK_HEAP_STRING_LENGTH(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_LENGTH)
#define DUK_HTHREAD_STRING_LENGTH(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_LENGTH)
-#define DUK_STRIDX_SET 81 /* 'set' */
+#define DUK_STRIDX_SET 83 /* 'set' */
#define DUK_HEAP_STRING_SET(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_SET)
#define DUK_HTHREAD_STRING_SET(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_SET)
-#define DUK_STRIDX_STACK 82 /* 'stack' */
+#define DUK_STRIDX_STACK 84 /* 'stack' */
#define DUK_HEAP_STRING_STACK(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_STACK)
#define DUK_HTHREAD_STRING_STACK(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_STACK)
-#define DUK_STRIDX_PC 83 /* 'pc' */
+#define DUK_STRIDX_PC 85 /* 'pc' */
#define DUK_HEAP_STRING_PC(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_PC)
#define DUK_HTHREAD_STRING_PC(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_PC)
-#define DUK_STRIDX_LINE_NUMBER 84 /* 'lineNumber' */
+#define DUK_STRIDX_LINE_NUMBER 86 /* 'lineNumber' */
#define DUK_HEAP_STRING_LINE_NUMBER(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_LINE_NUMBER)
#define DUK_HTHREAD_STRING_LINE_NUMBER(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_LINE_NUMBER)
-#define DUK_STRIDX_INT_TRACEDATA 85 /* '\xffTracedata' */
+#define DUK_STRIDX_INT_TRACEDATA 87 /* '\x82Tracedata' */
#define DUK_HEAP_STRING_INT_TRACEDATA(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_INT_TRACEDATA)
#define DUK_HTHREAD_STRING_INT_TRACEDATA(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_INT_TRACEDATA)
-#define DUK_STRIDX_NAME 86 /* 'name' */
+#define DUK_STRIDX_NAME 88 /* 'name' */
#define DUK_HEAP_STRING_NAME(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_NAME)
#define DUK_HTHREAD_STRING_NAME(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_NAME)
-#define DUK_STRIDX_FILE_NAME 87 /* 'fileName' */
+#define DUK_STRIDX_FILE_NAME 89 /* 'fileName' */
#define DUK_HEAP_STRING_FILE_NAME(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_FILE_NAME)
#define DUK_HTHREAD_STRING_FILE_NAME(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_FILE_NAME)
-#define DUK_STRIDX_LC_POINTER 88 /* 'pointer' */
+#define DUK_STRIDX_LC_POINTER 90 /* 'pointer' */
#define DUK_HEAP_STRING_LC_POINTER(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_LC_POINTER)
#define DUK_HTHREAD_STRING_LC_POINTER(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_LC_POINTER)
-#define DUK_STRIDX_INT_VALUE 89 /* '\xffValue' */
-#define DUK_HEAP_STRING_INT_VALUE(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_INT_VALUE)
-#define DUK_HTHREAD_STRING_INT_VALUE(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_INT_VALUE)
-#define DUK_STRIDX_INT_NEXT 90 /* '\xffNext' */
+#define DUK_STRIDX_INT_TARGET 91 /* '\x82Target' */
+#define DUK_HEAP_STRING_INT_TARGET(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_INT_TARGET)
+#define DUK_HTHREAD_STRING_INT_TARGET(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_INT_TARGET)
+#define DUK_STRIDX_INT_NEXT 92 /* '\x82Next' */
#define DUK_HEAP_STRING_INT_NEXT(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_INT_NEXT)
#define DUK_HTHREAD_STRING_INT_NEXT(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_INT_NEXT)
-#define DUK_STRIDX_INT_BYTECODE 91 /* '\xffBytecode' */
+#define DUK_STRIDX_INT_BYTECODE 93 /* '\x82Bytecode' */
#define DUK_HEAP_STRING_INT_BYTECODE(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_INT_BYTECODE)
#define DUK_HTHREAD_STRING_INT_BYTECODE(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_INT_BYTECODE)
-#define DUK_STRIDX_INT_FORMALS 92 /* '\xffFormals' */
+#define DUK_STRIDX_INT_FORMALS 94 /* '\x82Formals' */
#define DUK_HEAP_STRING_INT_FORMALS(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_INT_FORMALS)
#define DUK_HTHREAD_STRING_INT_FORMALS(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_INT_FORMALS)
-#define DUK_STRIDX_INT_VARMAP 93 /* '\xffVarmap' */
+#define DUK_STRIDX_INT_VARMAP 95 /* '\x82Varmap' */
#define DUK_HEAP_STRING_INT_VARMAP(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_INT_VARMAP)
#define DUK_HTHREAD_STRING_INT_VARMAP(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_INT_VARMAP)
-#define DUK_STRIDX_INT_SOURCE 94 /* '\xffSource' */
+#define DUK_STRIDX_INT_SOURCE 96 /* '\x82Source' */
#define DUK_HEAP_STRING_INT_SOURCE(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_INT_SOURCE)
#define DUK_HTHREAD_STRING_INT_SOURCE(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_INT_SOURCE)
-#define DUK_STRIDX_INT_PC2LINE 95 /* '\xffPc2line' */
+#define DUK_STRIDX_INT_PC2LINE 97 /* '\x82Pc2line' */
#define DUK_HEAP_STRING_INT_PC2LINE(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_INT_PC2LINE)
#define DUK_HTHREAD_STRING_INT_PC2LINE(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_INT_PC2LINE)
-#define DUK_STRIDX_INT_THIS 96 /* '\xffThis' */
-#define DUK_HEAP_STRING_INT_THIS(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_INT_THIS)
-#define DUK_HTHREAD_STRING_INT_THIS(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_INT_THIS)
-#define DUK_STRIDX_INT_ARGS 97 /* '\xffArgs' */
-#define DUK_HEAP_STRING_INT_ARGS(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_INT_ARGS)
-#define DUK_HTHREAD_STRING_INT_ARGS(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_INT_ARGS)
-#define DUK_STRIDX_INT_MAP 98 /* '\xffMap' */
+#define DUK_STRIDX_INT_MAP 98 /* '\x82Map' */
#define DUK_HEAP_STRING_INT_MAP(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_INT_MAP)
#define DUK_HTHREAD_STRING_INT_MAP(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_INT_MAP)
-#define DUK_STRIDX_INT_VARENV 99 /* '\xffVarenv' */
+#define DUK_STRIDX_INT_VARENV 99 /* '\x82Varenv' */
#define DUK_HEAP_STRING_INT_VARENV(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_INT_VARENV)
#define DUK_HTHREAD_STRING_INT_VARENV(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_INT_VARENV)
-#define DUK_STRIDX_INT_FINALIZER 100 /* '\xffFinalizer' */
+#define DUK_STRIDX_INT_FINALIZER 100 /* '\x82Finalizer' */
#define DUK_HEAP_STRING_INT_FINALIZER(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_INT_FINALIZER)
#define DUK_HTHREAD_STRING_INT_FINALIZER(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_INT_FINALIZER)
-#define DUK_STRIDX_INT_TARGET 101 /* '\xffTarget' */
-#define DUK_HEAP_STRING_INT_TARGET(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_INT_TARGET)
-#define DUK_HTHREAD_STRING_INT_TARGET(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_INT_TARGET)
-#define DUK_STRIDX_INT_HANDLER 102 /* '\xffHandler' */
-#define DUK_HEAP_STRING_INT_HANDLER(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_INT_HANDLER)
-#define DUK_HTHREAD_STRING_INT_HANDLER(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_INT_HANDLER)
-#define DUK_STRIDX_COMPILE 103 /* 'compile' */
+#define DUK_STRIDX_INT_VALUE 101 /* '\x82Value' */
+#define DUK_HEAP_STRING_INT_VALUE(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_INT_VALUE)
+#define DUK_HTHREAD_STRING_INT_VALUE(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_INT_VALUE)
+#define DUK_STRIDX_COMPILE 102 /* 'compile' */
#define DUK_HEAP_STRING_COMPILE(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_COMPILE)
#define DUK_HTHREAD_STRING_COMPILE(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_COMPILE)
-#define DUK_STRIDX_INPUT 104 /* 'input' */
+#define DUK_STRIDX_INPUT 103 /* 'input' */
#define DUK_HEAP_STRING_INPUT(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_INPUT)
#define DUK_HTHREAD_STRING_INPUT(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_INPUT)
-#define DUK_STRIDX_ERR_CREATE 105 /* 'errCreate' */
+#define DUK_STRIDX_ERR_CREATE 104 /* 'errCreate' */
#define DUK_HEAP_STRING_ERR_CREATE(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_ERR_CREATE)
#define DUK_HTHREAD_STRING_ERR_CREATE(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_ERR_CREATE)
-#define DUK_STRIDX_ERR_THROW 106 /* 'errThrow' */
+#define DUK_STRIDX_ERR_THROW 105 /* 'errThrow' */
#define DUK_HEAP_STRING_ERR_THROW(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_ERR_THROW)
#define DUK_HTHREAD_STRING_ERR_THROW(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_ERR_THROW)
-#define DUK_STRIDX_ENV 107 /* 'env' */
+#define DUK_STRIDX_ENV 106 /* 'env' */
#define DUK_HEAP_STRING_ENV(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_ENV)
#define DUK_HTHREAD_STRING_ENV(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_ENV)
-#define DUK_STRIDX_HEX 108 /* 'hex' */
+#define DUK_STRIDX_HEX 107 /* 'hex' */
#define DUK_HEAP_STRING_HEX(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_HEX)
#define DUK_HTHREAD_STRING_HEX(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_HEX)
-#define DUK_STRIDX_BASE64 109 /* 'base64' */
+#define DUK_STRIDX_BASE64 108 /* 'base64' */
#define DUK_HEAP_STRING_BASE64(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_BASE64)
#define DUK_HTHREAD_STRING_BASE64(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_BASE64)
-#define DUK_STRIDX_JX 110 /* 'jx' */
+#define DUK_STRIDX_JX 109 /* 'jx' */
#define DUK_HEAP_STRING_JX(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_JX)
#define DUK_HTHREAD_STRING_JX(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_JX)
-#define DUK_STRIDX_JC 111 /* 'jc' */
+#define DUK_STRIDX_JC 110 /* 'jc' */
#define DUK_HEAP_STRING_JC(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_JC)
#define DUK_HTHREAD_STRING_JC(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_JC)
-#define DUK_STRIDX_RESUME 112 /* 'resume' */
-#define DUK_HEAP_STRING_RESUME(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_RESUME)
-#define DUK_HTHREAD_STRING_RESUME(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_RESUME)
-#define DUK_STRIDX_JSON_EXT_UNDEFINED 113 /* '{"_undef":true}' */
+#define DUK_STRIDX_JSON_EXT_UNDEFINED 111 /* '{"_undef":true}' */
#define DUK_HEAP_STRING_JSON_EXT_UNDEFINED(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_JSON_EXT_UNDEFINED)
#define DUK_HTHREAD_STRING_JSON_EXT_UNDEFINED(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_JSON_EXT_UNDEFINED)
-#define DUK_STRIDX_JSON_EXT_NAN 114 /* '{"_nan":true}' */
+#define DUK_STRIDX_JSON_EXT_NAN 112 /* '{"_nan":true}' */
#define DUK_HEAP_STRING_JSON_EXT_NAN(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_JSON_EXT_NAN)
#define DUK_HTHREAD_STRING_JSON_EXT_NAN(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_JSON_EXT_NAN)
-#define DUK_STRIDX_JSON_EXT_POSINF 115 /* '{"_inf":true}' */
+#define DUK_STRIDX_JSON_EXT_POSINF 113 /* '{"_inf":true}' */
#define DUK_HEAP_STRING_JSON_EXT_POSINF(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_JSON_EXT_POSINF)
#define DUK_HTHREAD_STRING_JSON_EXT_POSINF(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_JSON_EXT_POSINF)
-#define DUK_STRIDX_JSON_EXT_NEGINF 116 /* '{"_ninf":true}' */
+#define DUK_STRIDX_JSON_EXT_NEGINF 114 /* '{"_ninf":true}' */
#define DUK_HEAP_STRING_JSON_EXT_NEGINF(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_JSON_EXT_NEGINF)
#define DUK_HTHREAD_STRING_JSON_EXT_NEGINF(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_JSON_EXT_NEGINF)
-#define DUK_STRIDX_JSON_EXT_FUNCTION1 117 /* '{"_func":true}' */
+#define DUK_STRIDX_JSON_EXT_FUNCTION1 115 /* '{"_func":true}' */
#define DUK_HEAP_STRING_JSON_EXT_FUNCTION1(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_JSON_EXT_FUNCTION1)
#define DUK_HTHREAD_STRING_JSON_EXT_FUNCTION1(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_JSON_EXT_FUNCTION1)
-#define DUK_STRIDX_JSON_EXT_FUNCTION2 118 /* '{_func:true}' */
+#define DUK_STRIDX_JSON_EXT_FUNCTION2 116 /* '{_func:true}' */
#define DUK_HEAP_STRING_JSON_EXT_FUNCTION2(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_JSON_EXT_FUNCTION2)
#define DUK_HTHREAD_STRING_JSON_EXT_FUNCTION2(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_JSON_EXT_FUNCTION2)
-#define DUK_STRIDX_BREAK 119 /* 'break' */
+#define DUK_STRIDX_BREAK 117 /* 'break' */
#define DUK_HEAP_STRING_BREAK(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_BREAK)
#define DUK_HTHREAD_STRING_BREAK(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_BREAK)
-#define DUK_STRIDX_CASE 120 /* 'case' */
+#define DUK_STRIDX_CASE 118 /* 'case' */
#define DUK_HEAP_STRING_CASE(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_CASE)
#define DUK_HTHREAD_STRING_CASE(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_CASE)
-#define DUK_STRIDX_CATCH 121 /* 'catch' */
+#define DUK_STRIDX_CATCH 119 /* 'catch' */
#define DUK_HEAP_STRING_CATCH(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_CATCH)
#define DUK_HTHREAD_STRING_CATCH(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_CATCH)
-#define DUK_STRIDX_CONTINUE 122 /* 'continue' */
+#define DUK_STRIDX_CONTINUE 120 /* 'continue' */
#define DUK_HEAP_STRING_CONTINUE(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_CONTINUE)
#define DUK_HTHREAD_STRING_CONTINUE(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_CONTINUE)
-#define DUK_STRIDX_DEBUGGER 123 /* 'debugger' */
+#define DUK_STRIDX_DEBUGGER 121 /* 'debugger' */
#define DUK_HEAP_STRING_DEBUGGER(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_DEBUGGER)
#define DUK_HTHREAD_STRING_DEBUGGER(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_DEBUGGER)
-#define DUK_STRIDX_DEFAULT 124 /* 'default' */
+#define DUK_STRIDX_DEFAULT 122 /* 'default' */
#define DUK_HEAP_STRING_DEFAULT(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_DEFAULT)
#define DUK_HTHREAD_STRING_DEFAULT(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_DEFAULT)
-#define DUK_STRIDX_DELETE 125 /* 'delete' */
+#define DUK_STRIDX_DELETE 123 /* 'delete' */
#define DUK_HEAP_STRING_DELETE(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_DELETE)
#define DUK_HTHREAD_STRING_DELETE(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_DELETE)
-#define DUK_STRIDX_DO 126 /* 'do' */
+#define DUK_STRIDX_DO 124 /* 'do' */
#define DUK_HEAP_STRING_DO(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_DO)
#define DUK_HTHREAD_STRING_DO(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_DO)
-#define DUK_STRIDX_ELSE 127 /* 'else' */
+#define DUK_STRIDX_ELSE 125 /* 'else' */
#define DUK_HEAP_STRING_ELSE(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_ELSE)
#define DUK_HTHREAD_STRING_ELSE(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_ELSE)
-#define DUK_STRIDX_FINALLY 128 /* 'finally' */
+#define DUK_STRIDX_FINALLY 126 /* 'finally' */
#define DUK_HEAP_STRING_FINALLY(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_FINALLY)
#define DUK_HTHREAD_STRING_FINALLY(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_FINALLY)
-#define DUK_STRIDX_FOR 129 /* 'for' */
+#define DUK_STRIDX_FOR 127 /* 'for' */
#define DUK_HEAP_STRING_FOR(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_FOR)
#define DUK_HTHREAD_STRING_FOR(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_FOR)
-#define DUK_STRIDX_LC_FUNCTION 130 /* 'function' */
+#define DUK_STRIDX_LC_FUNCTION 128 /* 'function' */
#define DUK_HEAP_STRING_LC_FUNCTION(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_LC_FUNCTION)
#define DUK_HTHREAD_STRING_LC_FUNCTION(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_LC_FUNCTION)
-#define DUK_STRIDX_IF 131 /* 'if' */
+#define DUK_STRIDX_IF 129 /* 'if' */
#define DUK_HEAP_STRING_IF(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_IF)
#define DUK_HTHREAD_STRING_IF(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_IF)
-#define DUK_STRIDX_IN 132 /* 'in' */
+#define DUK_STRIDX_IN 130 /* 'in' */
#define DUK_HEAP_STRING_IN(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_IN)
#define DUK_HTHREAD_STRING_IN(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_IN)
-#define DUK_STRIDX_INSTANCEOF 133 /* 'instanceof' */
+#define DUK_STRIDX_INSTANCEOF 131 /* 'instanceof' */
#define DUK_HEAP_STRING_INSTANCEOF(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_INSTANCEOF)
#define DUK_HTHREAD_STRING_INSTANCEOF(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_INSTANCEOF)
-#define DUK_STRIDX_NEW 134 /* 'new' */
+#define DUK_STRIDX_NEW 132 /* 'new' */
#define DUK_HEAP_STRING_NEW(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_NEW)
#define DUK_HTHREAD_STRING_NEW(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_NEW)
-#define DUK_STRIDX_RETURN 135 /* 'return' */
+#define DUK_STRIDX_RETURN 133 /* 'return' */
#define DUK_HEAP_STRING_RETURN(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_RETURN)
#define DUK_HTHREAD_STRING_RETURN(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_RETURN)
-#define DUK_STRIDX_SWITCH 136 /* 'switch' */
+#define DUK_STRIDX_SWITCH 134 /* 'switch' */
#define DUK_HEAP_STRING_SWITCH(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_SWITCH)
#define DUK_HTHREAD_STRING_SWITCH(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_SWITCH)
-#define DUK_STRIDX_THIS 137 /* 'this' */
+#define DUK_STRIDX_THIS 135 /* 'this' */
#define DUK_HEAP_STRING_THIS(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_THIS)
#define DUK_HTHREAD_STRING_THIS(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_THIS)
-#define DUK_STRIDX_THROW 138 /* 'throw' */
+#define DUK_STRIDX_THROW 136 /* 'throw' */
#define DUK_HEAP_STRING_THROW(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_THROW)
#define DUK_HTHREAD_STRING_THROW(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_THROW)
-#define DUK_STRIDX_TRY 139 /* 'try' */
+#define DUK_STRIDX_TRY 137 /* 'try' */
#define DUK_HEAP_STRING_TRY(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_TRY)
#define DUK_HTHREAD_STRING_TRY(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_TRY)
-#define DUK_STRIDX_TYPEOF 140 /* 'typeof' */
+#define DUK_STRIDX_TYPEOF 138 /* 'typeof' */
#define DUK_HEAP_STRING_TYPEOF(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_TYPEOF)
#define DUK_HTHREAD_STRING_TYPEOF(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_TYPEOF)
-#define DUK_STRIDX_VAR 141 /* 'var' */
+#define DUK_STRIDX_VAR 139 /* 'var' */
#define DUK_HEAP_STRING_VAR(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_VAR)
#define DUK_HTHREAD_STRING_VAR(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_VAR)
-#define DUK_STRIDX_CONST 142 /* 'const' */
+#define DUK_STRIDX_CONST 140 /* 'const' */
#define DUK_HEAP_STRING_CONST(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_CONST)
#define DUK_HTHREAD_STRING_CONST(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_CONST)
-#define DUK_STRIDX_VOID 143 /* 'void' */
+#define DUK_STRIDX_VOID 141 /* 'void' */
#define DUK_HEAP_STRING_VOID(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_VOID)
#define DUK_HTHREAD_STRING_VOID(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_VOID)
-#define DUK_STRIDX_WHILE 144 /* 'while' */
+#define DUK_STRIDX_WHILE 142 /* 'while' */
#define DUK_HEAP_STRING_WHILE(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_WHILE)
#define DUK_HTHREAD_STRING_WHILE(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_WHILE)
-#define DUK_STRIDX_WITH 145 /* 'with' */
+#define DUK_STRIDX_WITH 143 /* 'with' */
#define DUK_HEAP_STRING_WITH(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_WITH)
#define DUK_HTHREAD_STRING_WITH(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_WITH)
-#define DUK_STRIDX_CLASS 146 /* 'class' */
+#define DUK_STRIDX_CLASS 144 /* 'class' */
#define DUK_HEAP_STRING_CLASS(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_CLASS)
#define DUK_HTHREAD_STRING_CLASS(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_CLASS)
-#define DUK_STRIDX_ENUM 147 /* 'enum' */
+#define DUK_STRIDX_ENUM 145 /* 'enum' */
#define DUK_HEAP_STRING_ENUM(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_ENUM)
#define DUK_HTHREAD_STRING_ENUM(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_ENUM)
-#define DUK_STRIDX_EXPORT 148 /* 'export' */
+#define DUK_STRIDX_EXPORT 146 /* 'export' */
#define DUK_HEAP_STRING_EXPORT(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_EXPORT)
#define DUK_HTHREAD_STRING_EXPORT(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_EXPORT)
-#define DUK_STRIDX_EXTENDS 149 /* 'extends' */
+#define DUK_STRIDX_EXTENDS 147 /* 'extends' */
#define DUK_HEAP_STRING_EXTENDS(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_EXTENDS)
#define DUK_HTHREAD_STRING_EXTENDS(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_EXTENDS)
-#define DUK_STRIDX_IMPORT 150 /* 'import' */
+#define DUK_STRIDX_IMPORT 148 /* 'import' */
#define DUK_HEAP_STRING_IMPORT(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_IMPORT)
#define DUK_HTHREAD_STRING_IMPORT(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_IMPORT)
-#define DUK_STRIDX_SUPER 151 /* 'super' */
+#define DUK_STRIDX_SUPER 149 /* 'super' */
#define DUK_HEAP_STRING_SUPER(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_SUPER)
#define DUK_HTHREAD_STRING_SUPER(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_SUPER)
-#define DUK_STRIDX_LC_NULL 152 /* 'null' */
+#define DUK_STRIDX_LC_NULL 150 /* 'null' */
#define DUK_HEAP_STRING_LC_NULL(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_LC_NULL)
#define DUK_HTHREAD_STRING_LC_NULL(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_LC_NULL)
-#define DUK_STRIDX_TRUE 153 /* 'true' */
+#define DUK_STRIDX_TRUE 151 /* 'true' */
#define DUK_HEAP_STRING_TRUE(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_TRUE)
#define DUK_HTHREAD_STRING_TRUE(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_TRUE)
-#define DUK_STRIDX_FALSE 154 /* 'false' */
+#define DUK_STRIDX_FALSE 152 /* 'false' */
#define DUK_HEAP_STRING_FALSE(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_FALSE)
#define DUK_HTHREAD_STRING_FALSE(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_FALSE)
-#define DUK_STRIDX_IMPLEMENTS 155 /* 'implements' */
+#define DUK_STRIDX_IMPLEMENTS 153 /* 'implements' */
#define DUK_HEAP_STRING_IMPLEMENTS(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_IMPLEMENTS)
#define DUK_HTHREAD_STRING_IMPLEMENTS(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_IMPLEMENTS)
-#define DUK_STRIDX_INTERFACE 156 /* 'interface' */
+#define DUK_STRIDX_INTERFACE 154 /* 'interface' */
#define DUK_HEAP_STRING_INTERFACE(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_INTERFACE)
#define DUK_HTHREAD_STRING_INTERFACE(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_INTERFACE)
-#define DUK_STRIDX_LET 157 /* 'let' */
+#define DUK_STRIDX_LET 155 /* 'let' */
#define DUK_HEAP_STRING_LET(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_LET)
#define DUK_HTHREAD_STRING_LET(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_LET)
-#define DUK_STRIDX_PACKAGE 158 /* 'package' */
+#define DUK_STRIDX_PACKAGE 156 /* 'package' */
#define DUK_HEAP_STRING_PACKAGE(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_PACKAGE)
#define DUK_HTHREAD_STRING_PACKAGE(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_PACKAGE)
-#define DUK_STRIDX_PRIVATE 159 /* 'private' */
+#define DUK_STRIDX_PRIVATE 157 /* 'private' */
#define DUK_HEAP_STRING_PRIVATE(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_PRIVATE)
#define DUK_HTHREAD_STRING_PRIVATE(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_PRIVATE)
-#define DUK_STRIDX_PROTECTED 160 /* 'protected' */
+#define DUK_STRIDX_PROTECTED 158 /* 'protected' */
#define DUK_HEAP_STRING_PROTECTED(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_PROTECTED)
#define DUK_HTHREAD_STRING_PROTECTED(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_PROTECTED)
-#define DUK_STRIDX_PUBLIC 161 /* 'public' */
+#define DUK_STRIDX_PUBLIC 159 /* 'public' */
#define DUK_HEAP_STRING_PUBLIC(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_PUBLIC)
#define DUK_HTHREAD_STRING_PUBLIC(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_PUBLIC)
-#define DUK_STRIDX_STATIC 162 /* 'static' */
+#define DUK_STRIDX_STATIC 160 /* 'static' */
#define DUK_HEAP_STRING_STATIC(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_STATIC)
#define DUK_HTHREAD_STRING_STATIC(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_STATIC)
-#define DUK_STRIDX_YIELD 163 /* 'yield' */
+#define DUK_STRIDX_YIELD 161 /* 'yield' */
#define DUK_HEAP_STRING_YIELD(heap) DUK_HEAP_GET_STRING((heap),DUK_STRIDX_YIELD)
#define DUK_HTHREAD_STRING_YIELD(thr) DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_YIELD)
-#define DUK_HEAP_NUM_STRINGS 164
-#define DUK_STRIDX_START_RESERVED 119
-#define DUK_STRIDX_START_STRICT_RESERVED 155
-#define DUK_STRIDX_END_RESERVED 164 /* exclusive endpoint */
+#define DUK_HEAP_NUM_STRINGS 162
+#define DUK_STRIDX_START_RESERVED 117
+#define DUK_STRIDX_START_STRICT_RESERVED 153
+#define DUK_STRIDX_END_RESERVED 162 /* exclusive endpoint */
/* To convert a heap stridx to a token number, subtract
* DUK_STRIDX_START_RESERVED and add DUK_TOK_START_RESERVED.
*/
#if !defined(DUK_SINGLE_FILE)
-DUK_INTERNAL_DECL const duk_uint8_t duk_strings_data[903];
+DUK_INTERNAL_DECL const duk_uint8_t duk_strings_data[892];
#endif /* !DUK_SINGLE_FILE */
#define DUK_STRDATA_MAX_STRLEN 17
-#define DUK_STRDATA_DATA_LENGTH 903
+#define DUK_STRDATA_DATA_LENGTH 892
#endif /* DUK_USE_ROM_STRINGS */
#if defined(DUK_USE_ROM_OBJECTS)
@@ -2013,10 +2014,14 @@ DUK_INTERNAL_DECL duk_ret_t duk_bi_object_prototype_value_of(duk_context *ctx);
DUK_INTERNAL_DECL duk_ret_t duk_bi_object_prototype_has_own_property(duk_context *ctx);
DUK_INTERNAL_DECL duk_ret_t duk_bi_object_prototype_is_prototype_of(duk_context *ctx);
DUK_INTERNAL_DECL duk_ret_t duk_bi_object_prototype_property_is_enumerable(duk_context *ctx);
+DUK_INTERNAL_DECL duk_ret_t duk_bi_object_prototype_defineaccessor(duk_context *ctx);
+DUK_INTERNAL_DECL duk_ret_t duk_bi_object_prototype_lookupaccessor(duk_context *ctx);
DUK_INTERNAL_DECL duk_ret_t duk_bi_function_prototype_to_string(duk_context *ctx);
DUK_INTERNAL_DECL duk_ret_t duk_bi_function_prototype_apply(duk_context *ctx);
DUK_INTERNAL_DECL duk_ret_t duk_bi_function_prototype_call(duk_context *ctx);
DUK_INTERNAL_DECL duk_ret_t duk_bi_function_prototype_bind(duk_context *ctx);
+DUK_INTERNAL_DECL duk_ret_t duk_bi_native_function_length(duk_context *ctx);
+DUK_INTERNAL_DECL duk_ret_t duk_bi_native_function_name(duk_context *ctx);
DUK_INTERNAL_DECL duk_ret_t duk_bi_array_constructor_is_array(duk_context *ctx);
DUK_INTERNAL_DECL duk_ret_t duk_bi_array_prototype_to_string(duk_context *ctx);
DUK_INTERNAL_DECL duk_ret_t duk_bi_array_prototype_join_shared(duk_context *ctx);
@@ -2083,10 +2088,13 @@ DUK_INTERNAL_DECL duk_ret_t duk_bi_error_prototype_linenumber_setter(duk_context
DUK_INTERNAL_DECL duk_ret_t duk_bi_error_prototype_to_string(duk_context *ctx);
DUK_INTERNAL_DECL duk_ret_t duk_bi_math_object_onearg_shared(duk_context *ctx);
DUK_INTERNAL_DECL duk_ret_t duk_bi_math_object_twoarg_shared(duk_context *ctx);
+DUK_INTERNAL_DECL duk_ret_t duk_bi_math_object_clz32(duk_context *ctx);
DUK_INTERNAL_DECL duk_ret_t duk_bi_math_object_hypot(duk_context *ctx);
+DUK_INTERNAL_DECL duk_ret_t duk_bi_math_object_imul(duk_context *ctx);
DUK_INTERNAL_DECL duk_ret_t duk_bi_math_object_max(duk_context *ctx);
DUK_INTERNAL_DECL duk_ret_t duk_bi_math_object_min(duk_context *ctx);
DUK_INTERNAL_DECL duk_ret_t duk_bi_math_object_random(duk_context *ctx);
+DUK_INTERNAL_DECL duk_ret_t duk_bi_math_object_sign(duk_context *ctx);
DUK_INTERNAL_DECL duk_ret_t duk_bi_json_object_parse(duk_context *ctx);
DUK_INTERNAL_DECL duk_ret_t duk_bi_json_object_stringify(duk_context *ctx);
DUK_INTERNAL_DECL duk_ret_t duk_bi_duktape_object_info(duk_context *ctx);
@@ -2100,6 +2108,8 @@ DUK_INTERNAL_DECL duk_ret_t duk_bi_thread_yield(duk_context *ctx);
DUK_INTERNAL_DECL duk_ret_t duk_bi_thread_resume(duk_context *ctx);
DUK_INTERNAL_DECL duk_ret_t duk_bi_thread_current(duk_context *ctx);
DUK_INTERNAL_DECL duk_ret_t duk_bi_pointer_prototype_tostring_shared(duk_context *ctx);
+DUK_INTERNAL_DECL duk_ret_t duk_bi_reflect_apply(duk_context *ctx);
+DUK_INTERNAL_DECL duk_ret_t duk_bi_reflect_construct(duk_context *ctx);
DUK_INTERNAL_DECL duk_ret_t duk_bi_reflect_object_delete_property(duk_context *ctx);
DUK_INTERNAL_DECL duk_ret_t duk_bi_reflect_object_get(duk_context *ctx);
DUK_INTERNAL_DECL duk_ret_t duk_bi_reflect_object_has(duk_context *ctx);
@@ -2128,8 +2138,9 @@ DUK_INTERNAL_DECL duk_ret_t duk_bi_textencoder_prototype_encoding_getter(duk_con
DUK_INTERNAL_DECL duk_ret_t duk_bi_textencoder_prototype_encode(duk_context *ctx);
DUK_INTERNAL_DECL duk_ret_t duk_bi_textdecoder_prototype_shared_getter(duk_context *ctx);
DUK_INTERNAL_DECL duk_ret_t duk_bi_textdecoder_prototype_decode(duk_context *ctx);
+DUK_INTERNAL_DECL duk_ret_t duk_bi_performance_now(duk_context *ctx);
#if !defined(DUK_SINGLE_FILE)
-DUK_INTERNAL_DECL const duk_c_function duk_bi_native_functions[166];
+DUK_INTERNAL_DECL const duk_c_function duk_bi_native_functions[176];
#endif /* !DUK_SINGLE_FILE */
#define DUK_BIDX_GLOBAL 0
#define DUK_BIDX_GLOBAL_ENV 1
@@ -2137,92 +2148,69 @@ DUK_INTERNAL_DECL const duk_c_function duk_bi_native_functions[166];
#define DUK_BIDX_OBJECT_PROTOTYPE 3
#define DUK_BIDX_FUNCTION_CONSTRUCTOR 4
#define DUK_BIDX_FUNCTION_PROTOTYPE 5
-#define DUK_BIDX_ARRAY_CONSTRUCTOR 6
-#define DUK_BIDX_ARRAY_PROTOTYPE 7
-#define DUK_BIDX_STRING_CONSTRUCTOR 8
-#define DUK_BIDX_STRING_PROTOTYPE 9
-#define DUK_BIDX_BOOLEAN_CONSTRUCTOR 10
-#define DUK_BIDX_BOOLEAN_PROTOTYPE 11
-#define DUK_BIDX_NUMBER_CONSTRUCTOR 12
-#define DUK_BIDX_NUMBER_PROTOTYPE 13
-#define DUK_BIDX_DATE_CONSTRUCTOR 14
-#define DUK_BIDX_DATE_PROTOTYPE 15
-#define DUK_BIDX_REGEXP_CONSTRUCTOR 16
-#define DUK_BIDX_REGEXP_PROTOTYPE 17
-#define DUK_BIDX_ERROR_CONSTRUCTOR 18
-#define DUK_BIDX_ERROR_PROTOTYPE 19
-#define DUK_BIDX_EVAL_ERROR_CONSTRUCTOR 20
-#define DUK_BIDX_EVAL_ERROR_PROTOTYPE 21
-#define DUK_BIDX_RANGE_ERROR_CONSTRUCTOR 22
-#define DUK_BIDX_RANGE_ERROR_PROTOTYPE 23
-#define DUK_BIDX_REFERENCE_ERROR_CONSTRUCTOR 24
-#define DUK_BIDX_REFERENCE_ERROR_PROTOTYPE 25
-#define DUK_BIDX_SYNTAX_ERROR_CONSTRUCTOR 26
-#define DUK_BIDX_SYNTAX_ERROR_PROTOTYPE 27
-#define DUK_BIDX_TYPE_ERROR_CONSTRUCTOR 28
-#define DUK_BIDX_TYPE_ERROR_PROTOTYPE 29
-#define DUK_BIDX_URI_ERROR_CONSTRUCTOR 30
-#define DUK_BIDX_URI_ERROR_PROTOTYPE 31
-#define DUK_BIDX_MATH 32
-#define DUK_BIDX_JSON 33
-#define DUK_BIDX_TYPE_ERROR_THROWER 34
-#define DUK_BIDX_DUKTAPE 35
-#define DUK_BIDX_THREAD_CONSTRUCTOR 36
-#define DUK_BIDX_THREAD_PROTOTYPE 37
-#define DUK_BIDX_POINTER_CONSTRUCTOR 38
-#define DUK_BIDX_POINTER_PROTOTYPE 39
-#define DUK_BIDX_DOUBLE_ERROR 40
-#define DUK_BIDX_PROXY_CONSTRUCTOR 41
-#define DUK_BIDX_REFLECT 42
-#define DUK_BIDX_SYMBOL_PROTOTYPE 43
-#define DUK_BIDX_ARRAYBUFFER_CONSTRUCTOR 44
-#define DUK_BIDX_ARRAYBUFFER_PROTOTYPE 45
-#define DUK_BIDX_DATAVIEW_CONSTRUCTOR 46
-#define DUK_BIDX_DATAVIEW_PROTOTYPE 47
-#define DUK_BIDX_TYPEDARRAY_CONSTRUCTOR 48
-#define DUK_BIDX_TYPEDARRAY_PROTOTYPE 49
-#define DUK_BIDX_INT8ARRAY_CONSTRUCTOR 50
-#define DUK_BIDX_INT8ARRAY_PROTOTYPE 51
-#define DUK_BIDX_UINT8ARRAY_CONSTRUCTOR 52
-#define DUK_BIDX_UINT8ARRAY_PROTOTYPE 53
-#define DUK_BIDX_UINT8CLAMPEDARRAY_CONSTRUCTOR 54
-#define DUK_BIDX_UINT8CLAMPEDARRAY_PROTOTYPE 55
-#define DUK_BIDX_INT16ARRAY_CONSTRUCTOR 56
-#define DUK_BIDX_INT16ARRAY_PROTOTYPE 57
-#define DUK_BIDX_UINT16ARRAY_CONSTRUCTOR 58
-#define DUK_BIDX_UINT16ARRAY_PROTOTYPE 59
-#define DUK_BIDX_INT32ARRAY_CONSTRUCTOR 60
-#define DUK_BIDX_INT32ARRAY_PROTOTYPE 61
-#define DUK_BIDX_UINT32ARRAY_CONSTRUCTOR 62
-#define DUK_BIDX_UINT32ARRAY_PROTOTYPE 63
-#define DUK_BIDX_FLOAT32ARRAY_CONSTRUCTOR 64
-#define DUK_BIDX_FLOAT32ARRAY_PROTOTYPE 65
-#define DUK_BIDX_FLOAT64ARRAY_CONSTRUCTOR 66
-#define DUK_BIDX_FLOAT64ARRAY_PROTOTYPE 67
-#define DUK_BIDX_NODEJS_BUFFER_CONSTRUCTOR 68
-#define DUK_BIDX_NODEJS_BUFFER_PROTOTYPE 69
-#define DUK_BIDX_TEXTENCODER_CONSTRUCTOR 70
-#define DUK_BIDX_TEXTENCODER_PROTOTYPE 71
-#define DUK_BIDX_TEXTDECODER_CONSTRUCTOR 72
-#define DUK_BIDX_TEXTDECODER_PROTOTYPE 73
-#define DUK_NUM_BUILTINS 74
-#define DUK_NUM_BIDX_BUILTINS 74
-#define DUK_NUM_ALL_BUILTINS 74
+#define DUK_BIDX_NATIVE_FUNCTION_PROTOTYPE 6
+#define DUK_BIDX_ARRAY_CONSTRUCTOR 7
+#define DUK_BIDX_ARRAY_PROTOTYPE 8
+#define DUK_BIDX_STRING_CONSTRUCTOR 9
+#define DUK_BIDX_STRING_PROTOTYPE 10
+#define DUK_BIDX_BOOLEAN_CONSTRUCTOR 11
+#define DUK_BIDX_BOOLEAN_PROTOTYPE 12
+#define DUK_BIDX_NUMBER_CONSTRUCTOR 13
+#define DUK_BIDX_NUMBER_PROTOTYPE 14
+#define DUK_BIDX_DATE_CONSTRUCTOR 15
+#define DUK_BIDX_DATE_PROTOTYPE 16
+#define DUK_BIDX_REGEXP_CONSTRUCTOR 17
+#define DUK_BIDX_REGEXP_PROTOTYPE 18
+#define DUK_BIDX_ERROR_CONSTRUCTOR 19
+#define DUK_BIDX_ERROR_PROTOTYPE 20
+#define DUK_BIDX_EVAL_ERROR_CONSTRUCTOR 21
+#define DUK_BIDX_EVAL_ERROR_PROTOTYPE 22
+#define DUK_BIDX_RANGE_ERROR_CONSTRUCTOR 23
+#define DUK_BIDX_RANGE_ERROR_PROTOTYPE 24
+#define DUK_BIDX_REFERENCE_ERROR_CONSTRUCTOR 25
+#define DUK_BIDX_REFERENCE_ERROR_PROTOTYPE 26
+#define DUK_BIDX_SYNTAX_ERROR_CONSTRUCTOR 27
+#define DUK_BIDX_SYNTAX_ERROR_PROTOTYPE 28
+#define DUK_BIDX_TYPE_ERROR_CONSTRUCTOR 29
+#define DUK_BIDX_TYPE_ERROR_PROTOTYPE 30
+#define DUK_BIDX_URI_ERROR_CONSTRUCTOR 31
+#define DUK_BIDX_URI_ERROR_PROTOTYPE 32
+#define DUK_BIDX_TYPE_ERROR_THROWER 33
+#define DUK_BIDX_DUKTAPE 34
+#define DUK_BIDX_THREAD_PROTOTYPE 35
+#define DUK_BIDX_POINTER_PROTOTYPE 36
+#define DUK_BIDX_DOUBLE_ERROR 37
+#define DUK_BIDX_SYMBOL_PROTOTYPE 38
+#define DUK_BIDX_ARRAYBUFFER_PROTOTYPE 39
+#define DUK_BIDX_DATAVIEW_PROTOTYPE 40
+#define DUK_BIDX_INT8ARRAY_PROTOTYPE 41
+#define DUK_BIDX_UINT8ARRAY_PROTOTYPE 42
+#define DUK_BIDX_UINT8CLAMPEDARRAY_PROTOTYPE 43
+#define DUK_BIDX_INT16ARRAY_PROTOTYPE 44
+#define DUK_BIDX_UINT16ARRAY_PROTOTYPE 45
+#define DUK_BIDX_INT32ARRAY_PROTOTYPE 46
+#define DUK_BIDX_UINT32ARRAY_PROTOTYPE 47
+#define DUK_BIDX_FLOAT32ARRAY_PROTOTYPE 48
+#define DUK_BIDX_FLOAT64ARRAY_PROTOTYPE 49
+#define DUK_BIDX_NODEJS_BUFFER_PROTOTYPE 50
+#define DUK_NUM_BUILTINS 51
+#define DUK_NUM_BIDX_BUILTINS 51
+#define DUK_NUM_ALL_BUILTINS 76
#if defined(DUK_USE_DOUBLE_LE)
#if !defined(DUK_SINGLE_FILE)
-DUK_INTERNAL_DECL const duk_uint8_t duk_builtins_data[3819];
+DUK_INTERNAL_DECL const duk_uint8_t duk_builtins_data[3972];
#endif /* !DUK_SINGLE_FILE */
-#define DUK_BUILTINS_DATA_LENGTH 3819
+#define DUK_BUILTINS_DATA_LENGTH 3972
#elif defined(DUK_USE_DOUBLE_BE)
#if !defined(DUK_SINGLE_FILE)
-DUK_INTERNAL_DECL const duk_uint8_t duk_builtins_data[3819];
+DUK_INTERNAL_DECL const duk_uint8_t duk_builtins_data[3972];
#endif /* !DUK_SINGLE_FILE */
-#define DUK_BUILTINS_DATA_LENGTH 3819
+#define DUK_BUILTINS_DATA_LENGTH 3972
#elif defined(DUK_USE_DOUBLE_ME)
#if !defined(DUK_SINGLE_FILE)
-DUK_INTERNAL_DECL const duk_uint8_t duk_builtins_data[3819];
+DUK_INTERNAL_DECL const duk_uint8_t duk_builtins_data[3972];
#endif /* !DUK_SINGLE_FILE */
-#define DUK_BUILTINS_DATA_LENGTH 3819
+#define DUK_BUILTINS_DATA_LENGTH 3972
#else
#error invalid endianness defines
#endif
@@ -2337,10 +2325,10 @@ struct duk_bitencoder_ctx {
/*
* Buffer writer (dynamic buffer only)
*
- * Helper for writing to a dynamic buffer with a concept of a "spare" area
+ * Helper for writing to a dynamic buffer with a concept of a "slack" area
* to reduce resizes. You can ensure there is enough space beforehand and
* then write for a while without further checks, relying on a stable data
- * pointer. Spare handling is automatic so call sites only indicate how
+ * pointer. Slack handling is automatic so call sites only indicate how
* much data they need right now.
*
* There are several ways to write using bufwriter. The best approach
@@ -2366,8 +2354,13 @@ struct duk_bufwriter_ctx {
duk_hbuffer_dynamic *buf;
};
-#define DUK_BW_SPARE_ADD 64
-#define DUK_BW_SPARE_SHIFT 4 /* 2^4 -> 1/16 = 6.25% spare */
+#if defined(DUK_USE_PREFER_SIZE)
+#define DUK_BW_SLACK_ADD 64
+#define DUK_BW_SLACK_SHIFT 4 /* 2^4 -> 1/16 = 6.25% slack */
+#else
+#define DUK_BW_SLACK_ADD 64
+#define DUK_BW_SLACK_SHIFT 2 /* 2^2 -> 1/4 = 25% slack */
+#endif
/* Initialization and finalization (compaction), converting to other types. */
@@ -2382,7 +2375,7 @@ struct duk_bufwriter_ctx {
duk_bw_compact((thr), (bw_ctx)); \
} while (0)
#define DUK_BW_PUSH_AS_STRING(thr,bw_ctx) do { \
- duk_push_lstring((duk_context *) (thr), \
+ duk_push_lstring((thr), \
(const char *) (bw_ctx)->p_base, \
(duk_size_t) ((bw_ctx)->p - (bw_ctx)->p_base)); \
} while (0)
@@ -2465,7 +2458,7 @@ struct duk_bufwriter_ctx {
duk_bw_compact((thr), (bw_ctx)); \
} while (0)
-/* Fast write calls which assume you control the spare beforehand.
+/* Fast write calls which assume you control the slack beforehand.
* Multibyte write variants exist and use a temporary write pointer
* because byte writes alias with anything: with a stored pointer
* explicit pointer load/stores get generated (e.g. gcc -Os).
@@ -2528,7 +2521,7 @@ struct duk_bufwriter_ctx {
#define DUK_BW_WRITE_RAW_XUTF8(thr,bw_ctx,cp) do { \
duk_ucodepoint_t duk__cp; \
duk_small_int_t duk__enc_len; \
- duk__cp = (cp); \
+ duk__cp = (duk_ucodepoint_t) (cp); \
DUK_BW_ASSERT_SPACE((thr), (bw_ctx), duk_unicode_get_xutf8_length(duk__cp)); \
duk__enc_len = duk_unicode_encode_xutf8(duk__cp, (bw_ctx)->p); \
(bw_ctx)->p += duk__enc_len; \
@@ -2854,10 +2847,17 @@ DUK_INTERNAL_DECL duk_double_t duk_double_fmax(duk_double_t x, duk_double_t y);
#define DUK_STR_BUFFER_TOO_LONG "buffer too long"
#define DUK_STR_ALLOC_FAILED "alloc failed"
#define DUK_STR_WRONG_BUFFER_TYPE "wrong buffer type"
-#define DUK_STR_ENCODE_FAILED "encode failed"
-#define DUK_STR_DECODE_FAILED "decode failed"
+#define DUK_STR_BASE64_ENCODE_FAILED "base64 encode failed"
+#define DUK_STR_SOURCE_DECODE_FAILED "source decode failed"
+#define DUK_STR_UTF8_DECODE_FAILED "utf-8 decode failed"
+#define DUK_STR_BASE64_DECODE_FAILED "base64 decode failed"
+#define DUK_STR_HEX_DECODE_FAILED "hex decode failed"
+#define DUK_STR_INVALID_BYTECODE "invalid bytecode"
#define DUK_STR_NO_SOURCECODE "no sourcecode"
#define DUK_STR_RESULT_TOO_LONG "result too long"
+#define DUK_STR_INVALID_CFUNC_RC "invalid C function rc"
+#define DUK_STR_INVALID_INSTANCEOF_RVAL "invalid instanceof rval"
+#define DUK_STR_INVALID_INSTANCEOF_RVAL_NOPROTO "instanceof rval has no .prototype"
/* JSON */
#define DUK_STR_FMT_PTR "%p"
@@ -2867,7 +2867,6 @@ DUK_INTERNAL_DECL duk_double_t duk_double_fmax(duk_double_t x, duk_double_t y);
#define DUK_STR_CYCLIC_INPUT "cyclic input"
/* Object property access */
-#define DUK_STR_PROXY_REVOKED "proxy revoked"
#define DUK_STR_INVALID_BASE "invalid base value"
#define DUK_STR_STRICT_CALLER_READ "cannot read strict 'caller'"
#define DUK_STR_PROXY_REJECTED "proxy rejected"
@@ -2876,6 +2875,7 @@ DUK_INTERNAL_DECL duk_double_t duk_double_fmax(duk_double_t x, duk_double_t y);
#define DUK_STR_INVALID_DESCRIPTOR "invalid descriptor"
/* Proxy */
+#define DUK_STR_PROXY_REVOKED "proxy revoked"
#define DUK_STR_INVALID_TRAP_RESULT "invalid trap result"
/* Variables */
@@ -2900,6 +2900,7 @@ DUK_INTERNAL_DECL duk_double_t duk_double_fmax(duk_double_t x, duk_double_t y);
#define DUK_STR_CANNOT_DELETE_IDENTIFIER "cannot delete identifier"
#define DUK_STR_INVALID_EXPRESSION "invalid expression"
#define DUK_STR_INVALID_LVALUE "invalid lvalue"
+#define DUK_STR_INVALID_NEWTARGET "invalid new.target"
#define DUK_STR_EXPECTED_IDENTIFIER "expected identifier"
#define DUK_STR_EMPTY_EXPR_NOT_ALLOWED "empty expression not allowed"
#define DUK_STR_INVALID_FOR "invalid for statement"
@@ -2916,7 +2917,7 @@ DUK_INTERNAL_DECL duk_double_t duk_double_fmax(duk_double_t x, duk_double_t y);
#define DUK_STR_INVALID_GETSET_NAME "invalid getter/setter name"
#define DUK_STR_FUNC_NAME_REQUIRED "function name required"
-/* Regexp */
+/* RegExp */
#define DUK_STR_INVALID_QUANTIFIER "invalid regexp quantifier"
#define DUK_STR_INVALID_QUANTIFIER_NO_ATOM "quantifier without preceding atom"
#define DUK_STR_INVALID_QUANTIFIER_VALUES "quantifier values invalid (qmin > qmax)"
@@ -2935,7 +2936,6 @@ DUK_INTERNAL_DECL duk_double_t duk_double_fmax(duk_double_t x, duk_double_t y);
/* Limits */
#define DUK_STR_VALSTACK_LIMIT "valstack limit"
#define DUK_STR_CALLSTACK_LIMIT "callstack limit"
-#define DUK_STR_CATCHSTACK_LIMIT "catchstack limit"
#define DUK_STR_PROTOTYPE_CHAIN_LIMIT "prototype chain limit"
#define DUK_STR_BOUND_CHAIN_LIMIT "function call bound chain limit"
#define DUK_STR_C_CALLSTACK_LIMIT "C call stack depth limit"
@@ -3114,20 +3114,20 @@ typedef duk_uint32_t duk_instr_t;
/* Opcodes. */
#define DUK_OP_LDREG 0
#define DUK_OP_STREG 1
-#define DUK_OP_LDCONST 2
-#define DUK_OP_LDINT 3
-#define DUK_OP_LDINTX 4
-#define DUK_OP_LDTHIS 5
-#define DUK_OP_LDUNDEF 6
-#define DUK_OP_LDNULL 7
-#define DUK_OP_LDTRUE 8
-#define DUK_OP_LDFALSE 9
-#define DUK_OP_BNOT 10
-#define DUK_OP_LNOT 11
-#define DUK_OP_UNM 12
-#define DUK_OP_UNP 13
-#define DUK_OP_TYPEOF 14
-#define DUK_OP_TYPEOFID 15
+#define DUK_OP_JUMP 2
+#define DUK_OP_LDCONST 3
+#define DUK_OP_LDINT 4
+#define DUK_OP_LDINTX 5
+#define DUK_OP_LDTHIS 6
+#define DUK_OP_LDUNDEF 7
+#define DUK_OP_LDNULL 8
+#define DUK_OP_LDTRUE 9
+#define DUK_OP_LDFALSE 10
+#define DUK_OP_GETVAR 11
+#define DUK_OP_BNOT 12
+#define DUK_OP_LNOT 13
+#define DUK_OP_UNM 14
+#define DUK_OP_UNP 15
#define DUK_OP_EQ 16
#define DUK_OP_EQ_RR 16
#define DUK_OP_EQ_CR 17
@@ -3297,67 +3297,68 @@ typedef duk_uint32_t duk_instr_t;
#define DUK_OP_REGEXP_CR 149
#define DUK_OP_REGEXP_RC 150
#define DUK_OP_REGEXP_CC 151
-#define DUK_OP_CSVAR 152
-#define DUK_OP_CSVAR_RR 152
-#define DUK_OP_CSVAR_CR 153
-#define DUK_OP_CSVAR_RC 154
-#define DUK_OP_CSVAR_CC 155
-#define DUK_OP_CLOSURE 156
-#define DUK_OP_GETVAR 157
-#define DUK_OP_PUTVAR 158
-#define DUK_OP_DELVAR 159
-#define DUK_OP_JUMP 160
-#define DUK_OP_RETREG 161
-#define DUK_OP_RETUNDEF 162
-#define DUK_OP_RETCONST 163
-#define DUK_OP_RETCONSTN 164 /* return const without incref (e.g. number) */
-#define DUK_OP_LABEL 165
-#define DUK_OP_ENDLABEL 166
-#define DUK_OP_BREAK 167
-#define DUK_OP_CONTINUE 168
-#define DUK_OP_TRYCATCH 169
-#define DUK_OP_ENDTRY 170
-#define DUK_OP_ENDCATCH 171
-#define DUK_OP_ENDFIN 172
-#define DUK_OP_THROW 173
-#define DUK_OP_CSREG 174
-#define DUK_OP_EVALCALL 175
-#define DUK_OP_CALL 176 /* must be even */
-#define DUK_OP_TAILCALL 177 /* must be odd */
-#define DUK_OP_NEW 178
-#define DUK_OP_NEWOBJ 179
-#define DUK_OP_NEWARR 180
-#define DUK_OP_MPUTOBJ 181
-#define DUK_OP_MPUTOBJI 182
-#define DUK_OP_INITSET 183
-#define DUK_OP_INITGET 184
-#define DUK_OP_MPUTARR 185
-#define DUK_OP_MPUTARRI 186
-#define DUK_OP_SETALEN 187
-#define DUK_OP_INITENUM 188
-#define DUK_OP_NEXTENUM 189
-#define DUK_OP_INVLHS 190
-#define DUK_OP_DEBUGGER 191
-#define DUK_OP_NOP 192
-#define DUK_OP_INVALID 193
-#define DUK_OP_UNUSED194 194
-#define DUK_OP_UNUSED195 195
-#define DUK_OP_UNUSED196 196
-#define DUK_OP_UNUSED197 197
-#define DUK_OP_UNUSED198 198
-#define DUK_OP_UNUSED199 199
-#define DUK_OP_UNUSED200 200
-#define DUK_OP_UNUSED201 201
-#define DUK_OP_UNUSED202 202
-#define DUK_OP_UNUSED203 203
-#define DUK_OP_UNUSED204 204
-#define DUK_OP_UNUSED205 205
-#define DUK_OP_UNUSED206 206
+#define DUK_OP_CLOSURE 152
+#define DUK_OP_TYPEOF 153
+#define DUK_OP_TYPEOFID 154
+#define DUK_OP_PUTVAR 155
+#define DUK_OP_DELVAR 156
+#define DUK_OP_RETREG 157
+#define DUK_OP_RETUNDEF 158
+#define DUK_OP_RETCONST 159
+#define DUK_OP_RETCONSTN 160 /* return const without incref (e.g. number) */
+#define DUK_OP_LABEL 161
+#define DUK_OP_ENDLABEL 162
+#define DUK_OP_BREAK 163
+#define DUK_OP_CONTINUE 164
+#define DUK_OP_TRYCATCH 165
+#define DUK_OP_ENDTRY 166
+#define DUK_OP_ENDCATCH 167
+#define DUK_OP_ENDFIN 168
+#define DUK_OP_THROW 169
+#define DUK_OP_INVLHS 170
+#define DUK_OP_CSREG 171
+#define DUK_OP_CSVAR 172
+#define DUK_OP_CSVAR_RR 172
+#define DUK_OP_CSVAR_CR 173
+#define DUK_OP_CSVAR_RC 174
+#define DUK_OP_CSVAR_CC 175
+#define DUK_OP_CALL0 176 /* DUK_OP_CALL0 & 0x0F must be zero. */
+#define DUK_OP_CALL1 177
+#define DUK_OP_CALL2 178
+#define DUK_OP_CALL3 179
+#define DUK_OP_CALL4 180
+#define DUK_OP_CALL5 181
+#define DUK_OP_CALL6 182
+#define DUK_OP_CALL7 183
+#define DUK_OP_CALL8 184
+#define DUK_OP_CALL9 185
+#define DUK_OP_CALL10 186
+#define DUK_OP_CALL11 187
+#define DUK_OP_CALL12 188
+#define DUK_OP_CALL13 189
+#define DUK_OP_CALL14 190
+#define DUK_OP_CALL15 191
+#define DUK_OP_NEWOBJ 192
+#define DUK_OP_NEWARR 193
+#define DUK_OP_MPUTOBJ 194
+#define DUK_OP_MPUTOBJI 195
+#define DUK_OP_INITSET 196
+#define DUK_OP_INITGET 197
+#define DUK_OP_MPUTARR 198
+#define DUK_OP_MPUTARRI 199
+#define DUK_OP_SETALEN 200
+#define DUK_OP_INITENUM 201
+#define DUK_OP_NEXTENUM 202
+#define DUK_OP_NEWTARGET 203
+#define DUK_OP_DEBUGGER 204
+#define DUK_OP_NOP 205
+#define DUK_OP_INVALID 206
#define DUK_OP_UNUSED207 207
-#define DUK_OP_UNUSED208 208
-#define DUK_OP_UNUSED209 209
-#define DUK_OP_UNUSED210 210
-#define DUK_OP_UNUSED211 211
+#define DUK_OP_GETPROPC 208
+#define DUK_OP_GETPROPC_RR 208
+#define DUK_OP_GETPROPC_CR 209
+#define DUK_OP_GETPROPC_RC 210
+#define DUK_OP_GETPROPC_CC 211
#define DUK_OP_UNUSED212 212
#define DUK_OP_UNUSED213 213
#define DUK_OP_UNUSED214 214
@@ -3407,14 +3408,24 @@ typedef duk_uint32_t duk_instr_t;
/* XXX: Allocate flags from opcode field? Would take 16 opcode slots
* but avoids shuffling in more cases. Maybe not worth it.
*/
-/* DUK_OP_TRYCATCH flags in A */
-#define DUK_BC_TRYCATCH_FLAG_HAVE_CATCH (1 << 0)
-#define DUK_BC_TRYCATCH_FLAG_HAVE_FINALLY (1 << 1)
-#define DUK_BC_TRYCATCH_FLAG_CATCH_BINDING (1 << 2)
-#define DUK_BC_TRYCATCH_FLAG_WITH_BINDING (1 << 3)
+/* DUK_OP_TRYCATCH flags in A. */
+#define DUK_BC_TRYCATCH_FLAG_HAVE_CATCH (1U << 0)
+#define DUK_BC_TRYCATCH_FLAG_HAVE_FINALLY (1U << 1)
+#define DUK_BC_TRYCATCH_FLAG_CATCH_BINDING (1U << 2)
+#define DUK_BC_TRYCATCH_FLAG_WITH_BINDING (1U << 3)
+
+/* DUK_OP_DECLVAR flags in A; bottom bits are reserved for propdesc flags
+ * (DUK_PROPDESC_FLAG_XXX).
+ */
+#define DUK_BC_DECLVAR_FLAG_FUNC_DECL (1U << 4) /* function declaration */
-/* DUK_OP_DECLVAR flags in A; bottom bits are reserved for propdesc flags (DUK_PROPDESC_FLAG_XXX) */
-#define DUK_BC_DECLVAR_FLAG_FUNC_DECL (1 << 4) /* function declaration */
+/* DUK_OP_CALLn flags, part of opcode field. Three lowest bits must match
+ * DUK_CALL_FLAG_xxx directly.
+ */
+#define DUK_BC_CALL_FLAG_TAILCALL (1U << 0)
+#define DUK_BC_CALL_FLAG_CONSTRUCT (1U << 1)
+#define DUK_BC_CALL_FLAG_CALLED_AS_EVAL (1U << 2)
+#define DUK_BC_CALL_FLAG_INDIRECT (1U << 3)
/* Misc constants and helper macros. */
#define DUK_BC_LDINT_BIAS (1L << 15)
@@ -3597,6 +3608,8 @@ typedef void (*duk_re_range_callback)(void *user, duk_codepoint_t r1, duk_codepo
#define DUK_TOK_MAXVAL 101 /* inclusive */
+#define DUK_TOK_INVALID DUK_SMALL_UINT_MAX
+
/* Convert heap string index to a token (reserved words) */
#define DUK_STRIDX_TO_TOK(x) ((x) - DUK_STRIDX_START_RESERVED + DUK_TOK_START_RESERVED)
@@ -3775,8 +3788,8 @@ typedef void (*duk_re_range_callback)(void *user, duk_codepoint_t r1, duk_codepo
* stale values otherwise.
*/
struct duk_token {
- duk_small_int_t t; /* token type (with reserved word identification) */
- duk_small_int_t t_nores; /* token type (with reserved words as DUK_TOK_IDENTIFER) */
+ duk_small_uint_t t; /* token type (with reserved word identification) */
+ duk_small_uint_t t_nores; /* token type (with reserved words as DUK_TOK_IDENTIFER) */
duk_double_t num; /* numeric value of token */
duk_hstring *str1; /* string 1 of token (borrowed, stored to ctx->slot1_idx) */
duk_hstring *str2; /* string 2 of token (borrowed, stored to ctx->slot2_idx) */
@@ -3791,11 +3804,11 @@ struct duk_token {
/* A regexp token value. */
struct duk_re_token {
- duk_small_int_t t; /* token type */
- duk_small_int_t greedy;
- duk_uint_fast32_t num; /* numeric value (character, count) */
- duk_uint_fast32_t qmin;
- duk_uint_fast32_t qmax;
+ duk_small_uint_t t; /* token type */
+ duk_small_uint_t greedy;
+ duk_uint32_t num; /* numeric value (character, count) */
+ duk_uint32_t qmin;
+ duk_uint32_t qmax;
};
/* A structure for 'snapshotting' a point for rewinding */
@@ -3898,13 +3911,12 @@ DUK_INTERNAL_DECL void duk_lexer_parse_re_ranges(duk_lexer_ctx *lex_ctx, duk_re_
* Chosen so that when a regconst is cast to duk_int32_t, all consts are
* negative values.
*/
-#define DUK_REGCONST_CONST_MARKER 0x80000000UL
-
-/* type to represent a reg/const reference during compilation */
-typedef duk_uint32_t duk_regconst_t;
+#define DUK_REGCONST_CONST_MARKER DUK_INT32_MIN /* = -0x80000000 */
-/* type to represent a straight register reference, with <0 indicating none */
-typedef duk_int32_t duk_reg_t;
+/* Type to represent a reg/const reference during compilation, with <0
+ * indicating a constant. Some call sites also use -1 to indicate 'none'.
+ */
+typedef duk_int32_t duk_regconst_t;
typedef struct {
duk_small_uint_t t; /* DUK_ISPEC_XXX */
@@ -3944,8 +3956,8 @@ struct duk_compiler_instr {
* Compiler state
*/
-#define DUK_LABEL_FLAG_ALLOW_BREAK (1 << 0)
-#define DUK_LABEL_FLAG_ALLOW_CONTINUE (1 << 1)
+#define DUK_LABEL_FLAG_ALLOW_BREAK (1U << 0)
+#define DUK_LABEL_FLAG_ALLOW_CONTINUE (1U << 1)
#define DUK_DECL_TYPE_VAR 0
#define DUK_DECL_TYPE_FUNC 1
@@ -4003,14 +4015,14 @@ struct duk_compiler_func {
duk_idx_t varmap_idx;
/* Temp reg handling. */
- duk_reg_t temp_first; /* first register that is a temporary (below: variables) */
- duk_reg_t temp_next; /* next temporary register to allocate */
- duk_reg_t temp_max; /* highest value of temp_reg (temp_max - 1 is highest used reg) */
+ duk_regconst_t temp_first; /* first register that is a temporary (below: variables) */
+ duk_regconst_t temp_next; /* next temporary register to allocate */
+ duk_regconst_t temp_max; /* highest value of temp_reg (temp_max - 1 is highest used reg) */
/* Shuffle registers if large number of regs/consts. */
- duk_reg_t shuffle1;
- duk_reg_t shuffle2;
- duk_reg_t shuffle3;
+ duk_regconst_t shuffle1;
+ duk_regconst_t shuffle2;
+ duk_regconst_t shuffle3;
/* Stats for current expression being parsed. */
duk_int_t nud_count;
@@ -4026,7 +4038,7 @@ struct duk_compiler_func {
duk_int_t with_depth; /* with stack depth (affects identifier lookups) */
duk_int_t fnum_next; /* inner function numbering */
duk_int_t num_formals; /* number of formal arguments */
- duk_reg_t reg_stmt_value; /* register for writing value of 'non-empty' statements (global or eval code), -1 is marker */
+ duk_regconst_t reg_stmt_value; /* register for writing value of 'non-empty' statements (global or eval code), -1 is marker */
#if defined(DUK_USE_DEBUGGER_SUPPORT)
duk_int_t min_line; /* XXX: typing (duk_hcompfunc has duk_uint32_t) */
duk_int_t max_line;
@@ -4126,9 +4138,9 @@ DUK_INTERNAL_DECL void duk_js_compile(duk_hthread *thr, const duk_uint8_t *src_b
#define DUK_REOP_ASSERT_NOT_WORD_BOUNDARY 19
/* flags */
-#define DUK_RE_FLAG_GLOBAL (1 << 0)
-#define DUK_RE_FLAG_IGNORE_CASE (1 << 1)
-#define DUK_RE_FLAG_MULTILINE (1 << 2)
+#define DUK_RE_FLAG_GLOBAL (1U << 0)
+#define DUK_RE_FLAG_IGNORE_CASE (1U << 1)
+#define DUK_RE_FLAG_MULTILINE (1U << 2)
struct duk_re_matcher_ctx {
duk_hthread *thr;
@@ -4207,6 +4219,9 @@ DUK_INTERNAL_DECL void duk_regexp_match_force_global(duk_hthread *thr); /* hack
/* XXX: macro for shared header fields (avoids some padding issues) */
+#if (DUK_USE_ALIGN_BY == 8) && defined(DUK_USE_PACK_MSVC_PRAGMA)
+#pragma pack(push, 8)
+#endif
struct duk_heaphdr {
duk_uint32_t h_flags;
@@ -4252,7 +4267,16 @@ struct duk_heaphdr {
#if defined(DUK_USE_HEAPPTR16)
duk_uint16_t h_extra16;
#endif
-};
+}
+#if (DUK_USE_ALIGN_BY == 8) && defined(DUK_USE_PACK_GCC_ATTR)
+__attribute__ ((aligned (8)))
+#elif (DUK_USE_ALIGN_BY == 8) && defined(DUK_USE_PACK_CLANG_ATTR)
+__attribute__ ((aligned (8)))
+#endif
+;
+#if (DUK_USE_ALIGN_BY == 8) && defined(DUK_USE_PACK_MSVC_PRAGMA)
+#pragma pack(pop)
+#endif
struct duk_heaphdr_string {
/* 16 bits would be enough for shared heaphdr flags and duk_hstring
@@ -5142,6 +5166,33 @@ struct duk_heaphdr_string {
#endif /* DUK_USE_REFERENCE_COUNTING */
+/*
+ * Some convenience macros that don't have optimized implementations now.
+ */
+
+#define DUK_TVAL_SET_TVAL_UPDREF_NORZ(thr,tv_dst,tv_src) do { \
+ duk_hthread *duk__thr = (thr); \
+ duk_tval *duk__dst = (tv_dst); \
+ duk_tval *duk__src = (tv_src); \
+ DUK_UNREF(duk__thr); \
+ DUK_TVAL_DECREF_NORZ(thr, duk__dst); \
+ DUK_TVAL_SET_TVAL(duk__dst, duk__src); \
+ DUK_TVAL_INCREF(thr, duk__dst); \
+ } while (0)
+
+#define DUK_TVAL_SET_U32_UPDREF_NORZ(thr,tv_dst,val) do { \
+ duk_hthread *duk__thr = (thr); \
+ duk_tval *duk__dst = (tv_dst); \
+ duk_uint32_t duk__val = (duk_uint32_t) (val); \
+ DUK_UNREF(duk__thr); \
+ DUK_TVAL_DECREF_NORZ(thr, duk__dst); \
+ DUK_TVAL_SET_U32(duk__dst, duk__val); \
+ } while (0)
+
+/*
+ * Prototypes
+ */
+
#if defined(DUK_USE_REFERENCE_COUNTING)
#if defined(DUK_USE_FINALIZER_SUPPORT)
DUK_INTERNAL_DECL void duk_refzero_check_slow(duk_hthread *thr);
@@ -5186,6 +5237,8 @@ DUK_INTERNAL_DECL void duk_heaphdr_decref_norz(duk_hthread *thr, duk_heaphdr *h)
#if !defined(DUK_API_INTERNAL_H_INCLUDED)
#define DUK_API_INTERNAL_H_INCLUDED
+#define DUK_INTERNAL_SYMBOL(x) ("\x82" x)
+
/* duk_push_sprintf constants */
#define DUK_PUSH_SPRINTF_INITIAL_SIZE 256L
#define DUK_PUSH_SPRINTF_SANITY_LIMIT (1L * 1024L * 1024L * 1024L)
@@ -5195,186 +5248,197 @@ DUK_INTERNAL_DECL void duk_heaphdr_decref_norz(duk_hthread *thr, duk_heaphdr *h)
*/
#define DUK_ERRCODE_FLAG_NOBLAME_FILELINE (1L << 24)
-/* Valstack resize flags */
-#define DUK_VSRESIZE_FLAG_SHRINK (1 << 0)
-#define DUK_VSRESIZE_FLAG_COMPACT (1 << 1)
-#define DUK_VSRESIZE_FLAG_THROW (1 << 2)
-
/* Current convention is to use duk_size_t for value stack sizes and global indices,
* and duk_idx_t for local frame indices.
*/
-DUK_INTERNAL_DECL
-duk_bool_t duk_valstack_resize_raw(duk_context *ctx,
- duk_size_t min_new_size,
- duk_small_uint_t flags);
+DUK_INTERNAL_DECL DUK_INLINE void duk_valstack_grow_check_throw(duk_hthread *thr, duk_size_t min_bytes);
+DUK_INTERNAL_DECL DUK_INLINE duk_bool_t duk_valstack_grow_check_nothrow(duk_hthread *thr, duk_size_t min_bytes);
+DUK_INTERNAL_DECL void duk_valstack_shrink_check_nothrow(duk_hthread *thr, duk_bool_t snug);
+
+DUK_INTERNAL_DECL void duk_copy_tvals_incref(duk_hthread *thr, duk_tval *tv_dst, duk_tval *tv_src, duk_size_t count);
+
+DUK_INTERNAL_DECL duk_tval *duk_reserve_gap(duk_hthread *thr, duk_idx_t idx_base, duk_idx_t count);
-DUK_INTERNAL_DECL void duk_dup_0(duk_context *ctx);
-DUK_INTERNAL_DECL void duk_dup_1(duk_context *ctx);
-DUK_INTERNAL_DECL void duk_dup_2(duk_context *ctx);
+DUK_INTERNAL_DECL void duk_set_top_unsafe(duk_hthread *thr, duk_idx_t idx);
+DUK_INTERNAL_DECL void duk_set_top_and_wipe(duk_hthread *thr, duk_idx_t top, duk_idx_t idx_wipe_start);
+
+DUK_INTERNAL_DECL void duk_dup_0(duk_hthread *thr);
+DUK_INTERNAL_DECL void duk_dup_1(duk_hthread *thr);
+DUK_INTERNAL_DECL void duk_dup_2(duk_hthread *thr);
/* duk_dup_m1() would be same as duk_dup_top() */
-DUK_INTERNAL_DECL void duk_dup_m2(duk_context *ctx);
-DUK_INTERNAL_DECL void duk_dup_m3(duk_context *ctx);
-DUK_INTERNAL_DECL void duk_dup_m4(duk_context *ctx);
+DUK_INTERNAL_DECL void duk_dup_m2(duk_hthread *thr);
+DUK_INTERNAL_DECL void duk_dup_m3(duk_hthread *thr);
+DUK_INTERNAL_DECL void duk_dup_m4(duk_hthread *thr);
-DUK_INTERNAL_DECL void duk_remove_m2(duk_context *ctx);
+DUK_INTERNAL_DECL void duk_remove_unsafe(duk_hthread *thr, duk_idx_t idx);
+DUK_INTERNAL_DECL void duk_remove_m2(duk_hthread *thr);
+DUK_INTERNAL_DECL void duk_remove_n(duk_hthread *thr, duk_idx_t idx, duk_idx_t count);
+DUK_INTERNAL_DECL void duk_remove_n_unsafe(duk_hthread *thr, duk_idx_t idx, duk_idx_t count);
DUK_INTERNAL_DECL duk_int_t duk_get_type_tval(duk_tval *tv);
DUK_INTERNAL_DECL duk_uint_t duk_get_type_mask_tval(duk_tval *tv);
#if defined(DUK_USE_VERBOSE_ERRORS) && defined(DUK_USE_PARANOID_ERRORS)
-DUK_INTERNAL_DECL const char *duk_get_type_name(duk_context *ctx, duk_idx_t idx);
+DUK_INTERNAL_DECL const char *duk_get_type_name(duk_hthread *thr, duk_idx_t idx);
#endif
-DUK_INTERNAL_DECL duk_small_uint_t duk_get_class_number(duk_context *ctx, duk_idx_t idx);
+DUK_INTERNAL_DECL duk_small_uint_t duk_get_class_number(duk_hthread *thr, duk_idx_t idx);
-DUK_INTERNAL_DECL duk_tval *duk_get_tval(duk_context *ctx, duk_idx_t idx);
-DUK_INTERNAL_DECL duk_tval *duk_get_tval_or_unused(duk_context *ctx, duk_idx_t idx);
-DUK_INTERNAL_DECL duk_tval *duk_require_tval(duk_context *ctx, duk_idx_t idx);
-DUK_INTERNAL_DECL void duk_push_tval(duk_context *ctx, duk_tval *tv);
+DUK_INTERNAL_DECL duk_tval *duk_get_tval(duk_hthread *thr, duk_idx_t idx);
+DUK_INTERNAL_DECL duk_tval *duk_get_tval_or_unused(duk_hthread *thr, duk_idx_t idx);
+DUK_INTERNAL_DECL duk_tval *duk_require_tval(duk_hthread *thr, duk_idx_t idx);
+DUK_INTERNAL_DECL void duk_push_tval(duk_hthread *thr, duk_tval *tv);
/* Push the current 'this' binding; throw TypeError if binding is not object
* coercible (CheckObjectCoercible).
*/
-DUK_INTERNAL_DECL void duk_push_this_check_object_coercible(duk_context *ctx);
+DUK_INTERNAL_DECL void duk_push_this_check_object_coercible(duk_hthread *thr);
/* duk_push_this() + CheckObjectCoercible() + duk_to_object() */
-DUK_INTERNAL_DECL duk_hobject *duk_push_this_coercible_to_object(duk_context *ctx);
+DUK_INTERNAL_DECL duk_hobject *duk_push_this_coercible_to_object(duk_hthread *thr);
/* duk_push_this() + CheckObjectCoercible() + duk_to_string() */
-DUK_INTERNAL_DECL duk_hstring *duk_push_this_coercible_to_string(duk_context *ctx);
+DUK_INTERNAL_DECL duk_hstring *duk_push_this_coercible_to_string(duk_hthread *thr);
-DUK_INTERNAL_DECL duk_hstring *duk_push_uint_to_hstring(duk_context *ctx, duk_uint_t i);
+DUK_INTERNAL_DECL duk_hstring *duk_push_uint_to_hstring(duk_hthread *thr, duk_uint_t i);
/* Get a borrowed duk_tval pointer to the current 'this' binding. Caller must
* make sure there's an active callstack entry. Note that the returned pointer
* is unstable with regards to side effects.
*/
-DUK_INTERNAL_DECL duk_tval *duk_get_borrowed_this_tval(duk_context *ctx);
+DUK_INTERNAL_DECL duk_tval *duk_get_borrowed_this_tval(duk_hthread *thr);
/* XXX: add fastint support? */
-#define duk_push_u64(ctx,val) \
- duk_push_number((ctx), (duk_double_t) (val))
-#define duk_push_i64(ctx,val) \
- duk_push_number((ctx), (duk_double_t) (val))
+#define duk_push_u64(thr,val) \
+ duk_push_number((thr), (duk_double_t) (val))
+#define duk_push_i64(thr,val) \
+ duk_push_number((thr), (duk_double_t) (val))
/* duk_push_(u)int() is guaranteed to support at least (un)signed 32-bit range */
-#define duk_push_u32(ctx,val) \
- duk_push_uint((ctx), (duk_uint_t) (val))
-#define duk_push_i32(ctx,val) \
- duk_push_int((ctx), (duk_int_t) (val))
+#define duk_push_u32(thr,val) \
+ duk_push_uint((thr), (duk_uint_t) (val))
+#define duk_push_i32(thr,val) \
+ duk_push_int((thr), (duk_int_t) (val))
/* sometimes stack and array indices need to go on the stack */
-#define duk_push_idx(ctx,val) \
- duk_push_int((ctx), (duk_int_t) (val))
-#define duk_push_uarridx(ctx,val) \
- duk_push_uint((ctx), (duk_uint_t) (val))
-#define duk_push_size_t(ctx,val) \
- duk_push_uint((ctx), (duk_uint_t) (val)) /* XXX: assumed to fit for now */
-
-DUK_INTERNAL_DECL duk_bool_t duk_is_string_notsymbol(duk_context *ctx, duk_idx_t idx);
-
-DUK_INTERNAL_DECL duk_hstring *duk_get_hstring(duk_context *ctx, duk_idx_t idx);
-DUK_INTERNAL_DECL duk_hstring *duk_get_hstring_notsymbol(duk_context *ctx, duk_idx_t idx);
-DUK_INTERNAL_DECL const char *duk_get_string_notsymbol(duk_context *ctx, duk_idx_t idx);
-DUK_INTERNAL_DECL duk_hobject *duk_get_hobject(duk_context *ctx, duk_idx_t idx);
-DUK_INTERNAL_DECL duk_hbuffer *duk_get_hbuffer(duk_context *ctx, duk_idx_t idx);
-DUK_INTERNAL_DECL duk_hthread *duk_get_hthread(duk_context *ctx, duk_idx_t idx);
-DUK_INTERNAL_DECL duk_hcompfunc *duk_get_hcompfunc(duk_context *ctx, duk_idx_t idx);
-DUK_INTERNAL_DECL duk_hnatfunc *duk_get_hnatfunc(duk_context *ctx, duk_idx_t idx);
-
-DUK_INTERNAL_DECL void *duk_get_buffer_data_raw(duk_context *ctx, duk_idx_t idx, duk_size_t *out_size, void *def_ptr, duk_size_t def_len, duk_bool_t throw_flag, duk_bool_t *out_isbuffer);
-
-DUK_INTERNAL_DECL duk_hobject *duk_get_hobject_with_class(duk_context *ctx, duk_idx_t idx, duk_small_uint_t classnum);
-
-DUK_INTERNAL_DECL duk_hobject *duk_get_hobject_promote_mask(duk_context *ctx, duk_idx_t idx, duk_uint_t type_mask);
-DUK_INTERNAL_DECL duk_hobject *duk_require_hobject_promote_mask(duk_context *ctx, duk_idx_t idx, duk_uint_t type_mask);
-DUK_INTERNAL_DECL duk_hobject *duk_require_hobject_accept_mask(duk_context *ctx, duk_idx_t idx, duk_uint_t type_mask);
-#define duk_require_hobject_promote_lfunc(ctx,idx) \
- duk_require_hobject_promote_mask((ctx), (idx), DUK_TYPE_MASK_LIGHTFUNC)
-#define duk_get_hobject_promote_lfunc(ctx,idx) \
- duk_get_hobject_promote_mask((ctx), (idx), DUK_TYPE_MASK_LIGHTFUNC)
+#define duk_push_idx(thr,val) \
+ duk_push_int((thr), (duk_int_t) (val))
+#define duk_push_uarridx(thr,val) \
+ duk_push_uint((thr), (duk_uint_t) (val))
+#define duk_push_size_t(thr,val) \
+ duk_push_uint((thr), (duk_uint_t) (val)) /* XXX: assumed to fit for now */
+
+DUK_INTERNAL_DECL duk_bool_t duk_is_string_notsymbol(duk_hthread *thr, duk_idx_t idx);
+
+DUK_INTERNAL_DECL duk_bool_t duk_is_callable_tval(duk_hthread *thr, duk_tval *tv);
+
+DUK_INTERNAL_DECL duk_hstring *duk_get_hstring(duk_hthread *thr, duk_idx_t idx);
+DUK_INTERNAL_DECL duk_hstring *duk_get_hstring_notsymbol(duk_hthread *thr, duk_idx_t idx);
+DUK_INTERNAL_DECL const char *duk_get_string_notsymbol(duk_hthread *thr, duk_idx_t idx);
+DUK_INTERNAL_DECL duk_hobject *duk_get_hobject(duk_hthread *thr, duk_idx_t idx);
+DUK_INTERNAL_DECL duk_hbuffer *duk_get_hbuffer(duk_hthread *thr, duk_idx_t idx);
+DUK_INTERNAL_DECL duk_hthread *duk_get_hthread(duk_hthread *thr, duk_idx_t idx);
+DUK_INTERNAL_DECL duk_hcompfunc *duk_get_hcompfunc(duk_hthread *thr, duk_idx_t idx);
+DUK_INTERNAL_DECL duk_hnatfunc *duk_get_hnatfunc(duk_hthread *thr, duk_idx_t idx);
+
+DUK_INTERNAL_DECL void *duk_get_buffer_data_raw(duk_hthread *thr, duk_idx_t idx, duk_size_t *out_size, void *def_ptr, duk_size_t def_len, duk_bool_t throw_flag, duk_bool_t *out_isbuffer);
+
+DUK_INTERNAL_DECL duk_hobject *duk_get_hobject_with_class(duk_hthread *thr, duk_idx_t idx, duk_small_uint_t classnum);
+
+DUK_INTERNAL_DECL duk_hobject *duk_get_hobject_promote_mask(duk_hthread *thr, duk_idx_t idx, duk_uint_t type_mask);
+DUK_INTERNAL_DECL duk_hobject *duk_require_hobject_promote_mask(duk_hthread *thr, duk_idx_t idx, duk_uint_t type_mask);
+DUK_INTERNAL_DECL duk_hobject *duk_require_hobject_accept_mask(duk_hthread *thr, duk_idx_t idx, duk_uint_t type_mask);
+#define duk_require_hobject_promote_lfunc(thr,idx) \
+ duk_require_hobject_promote_mask((thr), (idx), DUK_TYPE_MASK_LIGHTFUNC)
+#define duk_get_hobject_promote_lfunc(thr,idx) \
+ duk_get_hobject_promote_mask((thr), (idx), DUK_TYPE_MASK_LIGHTFUNC)
#if 0 /*unused*/
-DUK_INTERNAL_DECL void *duk_get_voidptr(duk_context *ctx, duk_idx_t idx);
+DUK_INTERNAL_DECL void *duk_get_voidptr(duk_hthread *thr, duk_idx_t idx);
#endif
-DUK_INTERNAL_DECL duk_hstring *duk_known_hstring(duk_context *ctx, duk_idx_t idx);
-DUK_INTERNAL_DECL duk_hobject *duk_known_hobject(duk_context *ctx, duk_idx_t idx);
-DUK_INTERNAL_DECL duk_hbuffer *duk_known_hbuffer(duk_context *ctx, duk_idx_t idx);
-DUK_INTERNAL_DECL duk_hcompfunc *duk_known_hcompfunc(duk_context *ctx, duk_idx_t idx);
-DUK_INTERNAL_DECL duk_hnatfunc *duk_known_hnatfunc(duk_context *ctx, duk_idx_t idx);
+DUK_INTERNAL_DECL duk_hstring *duk_known_hstring(duk_hthread *thr, duk_idx_t idx);
+DUK_INTERNAL_DECL duk_hobject *duk_known_hobject(duk_hthread *thr, duk_idx_t idx);
+DUK_INTERNAL_DECL duk_hbuffer *duk_known_hbuffer(duk_hthread *thr, duk_idx_t idx);
+DUK_INTERNAL_DECL duk_hcompfunc *duk_known_hcompfunc(duk_hthread *thr, duk_idx_t idx);
+DUK_INTERNAL_DECL duk_hnatfunc *duk_known_hnatfunc(duk_hthread *thr, duk_idx_t idx);
-DUK_INTERNAL_DECL duk_double_t duk_to_number_tval(duk_context *ctx, duk_tval *tv);
+DUK_INTERNAL_DECL duk_double_t duk_to_number_tval(duk_hthread *thr, duk_tval *tv);
-DUK_INTERNAL_DECL duk_hstring *duk_to_hstring(duk_context *ctx, duk_idx_t idx);
-DUK_INTERNAL_DECL duk_hstring *duk_to_hstring_m1(duk_context *ctx);
-DUK_INTERNAL_DECL duk_hstring *duk_to_hstring_acceptsymbol(duk_context *ctx, duk_idx_t idx);
+DUK_INTERNAL_DECL duk_hstring *duk_to_hstring(duk_hthread *thr, duk_idx_t idx);
+DUK_INTERNAL_DECL duk_hstring *duk_to_hstring_m1(duk_hthread *thr);
+DUK_INTERNAL_DECL duk_hstring *duk_to_hstring_acceptsymbol(duk_hthread *thr, duk_idx_t idx);
-DUK_INTERNAL_DECL duk_hobject *duk_to_hobject(duk_context *ctx, duk_idx_t idx);
+DUK_INTERNAL_DECL duk_hobject *duk_to_hobject(duk_hthread *thr, duk_idx_t idx);
-DUK_INTERNAL_DECL duk_double_t duk_to_number_m1(duk_context *ctx);
-DUK_INTERNAL_DECL duk_double_t duk_to_number_m2(duk_context *ctx);
+DUK_INTERNAL_DECL duk_double_t duk_to_number_m1(duk_hthread *thr);
+DUK_INTERNAL_DECL duk_double_t duk_to_number_m2(duk_hthread *thr);
#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 idx);
+DUK_INTERNAL_DECL duk_hstring *duk_safe_to_hstring(duk_hthread *thr, duk_idx_t idx);
#endif
-DUK_INTERNAL_DECL void duk_push_class_string_tval(duk_context *ctx, duk_tval *tv);
+DUK_INTERNAL_DECL void duk_push_class_string_tval(duk_hthread *thr, duk_tval *tv);
-DUK_INTERNAL_DECL duk_int_t duk_to_int_clamped_raw(duk_context *ctx, duk_idx_t idx, 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 idx, 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 idx, duk_int_t minval, duk_int_t maxval);
+DUK_INTERNAL_DECL duk_int_t duk_to_int_clamped_raw(duk_hthread *thr, duk_idx_t idx, 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_hthread *thr, duk_idx_t idx, duk_int_t minval, duk_int_t maxval);
+DUK_INTERNAL_DECL duk_int_t duk_to_int_check_range(duk_hthread *thr, duk_idx_t idx, 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 idx);
-#endif
-DUK_INTERNAL_DECL duk_hstring *duk_to_property_key_hstring(duk_context *ctx, duk_idx_t idx);
-
-DUK_INTERNAL_DECL duk_hstring *duk_require_hstring(duk_context *ctx, duk_idx_t idx);
-DUK_INTERNAL_DECL duk_hstring *duk_require_hstring_notsymbol(duk_context *ctx, duk_idx_t idx);
-DUK_INTERNAL_DECL const char *duk_require_lstring_notsymbol(duk_context *ctx, duk_idx_t idx, duk_size_t *out_len);
-DUK_INTERNAL_DECL const char *duk_require_string_notsymbol(duk_context *ctx, duk_idx_t idx);
-DUK_INTERNAL_DECL duk_hobject *duk_require_hobject(duk_context *ctx, duk_idx_t idx);
-DUK_INTERNAL_DECL duk_hbuffer *duk_require_hbuffer(duk_context *ctx, duk_idx_t idx);
-DUK_INTERNAL_DECL duk_hthread *duk_require_hthread(duk_context *ctx, duk_idx_t idx);
-DUK_INTERNAL_DECL duk_hcompfunc *duk_require_hcompfunc(duk_context *ctx, duk_idx_t idx);
-DUK_INTERNAL_DECL duk_hnatfunc *duk_require_hnatfunc(duk_context *ctx, duk_idx_t idx);
-
-DUK_INTERNAL_DECL duk_hobject *duk_require_hobject_with_class(duk_context *ctx, duk_idx_t idx, duk_small_uint_t classnum);
-
-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_uint_t stridx);
-DUK_INTERNAL_DECL void duk_push_hstring_empty(duk_context *ctx);
-DUK_INTERNAL_DECL void duk_push_hobject(duk_context *ctx, duk_hobject *h);
-DUK_INTERNAL_DECL void duk_push_hbuffer(duk_context *ctx, duk_hbuffer *h);
-#define duk_push_hthread(ctx,h) \
- duk_push_hobject((ctx), (duk_hobject *) (h))
-#define duk_push_hnatfunc(ctx,h) \
- duk_push_hobject((ctx), (duk_hobject *) (h))
-DUK_INTERNAL_DECL void duk_push_hobject_bidx(duk_context *ctx, duk_small_int_t builtin_idx);
-DUK_INTERNAL_DECL duk_hobject *duk_push_object_helper(duk_context *ctx, duk_uint_t hobject_flags_and_class, duk_small_int_t prototype_bidx);
-DUK_INTERNAL_DECL duk_hobject *duk_push_object_helper_proto(duk_context *ctx, duk_uint_t hobject_flags_and_class, duk_hobject *proto);
-DUK_INTERNAL_DECL duk_hcompfunc *duk_push_hcompfunc(duk_context *ctx);
-DUK_INTERNAL_DECL void duk_push_c_function_noexotic(duk_context *ctx, duk_c_function func, duk_int_t nargs);
-DUK_INTERNAL_DECL void duk_push_c_function_noconstruct_noexotic(duk_context *ctx, duk_c_function func, duk_int_t nargs);
+DUK_INTERNAL_DECL duk_uint8_t duk_to_uint8clamped(duk_hthread *thr, duk_idx_t idx);
+#endif
+DUK_INTERNAL_DECL duk_hstring *duk_to_property_key_hstring(duk_hthread *thr, duk_idx_t idx);
+
+DUK_INTERNAL_DECL duk_hstring *duk_require_hstring(duk_hthread *thr, duk_idx_t idx);
+DUK_INTERNAL_DECL duk_hstring *duk_require_hstring_notsymbol(duk_hthread *thr, duk_idx_t idx);
+DUK_INTERNAL_DECL const char *duk_require_lstring_notsymbol(duk_hthread *thr, duk_idx_t idx, duk_size_t *out_len);
+DUK_INTERNAL_DECL const char *duk_require_string_notsymbol(duk_hthread *thr, duk_idx_t idx);
+DUK_INTERNAL_DECL duk_hobject *duk_require_hobject(duk_hthread *thr, duk_idx_t idx);
+DUK_INTERNAL_DECL duk_hbuffer *duk_require_hbuffer(duk_hthread *thr, duk_idx_t idx);
+DUK_INTERNAL_DECL duk_hthread *duk_require_hthread(duk_hthread *thr, duk_idx_t idx);
+DUK_INTERNAL_DECL duk_hcompfunc *duk_require_hcompfunc(duk_hthread *thr, duk_idx_t idx);
+DUK_INTERNAL_DECL duk_hnatfunc *duk_require_hnatfunc(duk_hthread *thr, duk_idx_t idx);
+
+DUK_INTERNAL_DECL duk_hobject *duk_require_hobject_with_class(duk_hthread *thr, duk_idx_t idx, duk_small_uint_t classnum);
+
+DUK_INTERNAL_DECL void duk_push_hstring(duk_hthread *thr, duk_hstring *h);
+DUK_INTERNAL_DECL void duk_push_hstring_stridx(duk_hthread *thr, duk_small_uint_t stridx);
+DUK_INTERNAL_DECL void duk_push_hstring_empty(duk_hthread *thr);
+DUK_INTERNAL_DECL void duk_push_hobject(duk_hthread *thr, duk_hobject *h);
+DUK_INTERNAL_DECL void duk_push_hbuffer(duk_hthread *thr, duk_hbuffer *h);
+#define duk_push_hthread(thr,h) \
+ duk_push_hobject((thr), (duk_hobject *) (h))
+#define duk_push_hnatfunc(thr,h) \
+ duk_push_hobject((thr), (duk_hobject *) (h))
+DUK_INTERNAL_DECL void duk_push_hobject_bidx(duk_hthread *thr, duk_small_int_t builtin_idx);
+DUK_INTERNAL_DECL duk_hobject *duk_push_object_helper(duk_hthread *thr, duk_uint_t hobject_flags_and_class, duk_small_int_t prototype_bidx);
+DUK_INTERNAL_DECL duk_hobject *duk_push_object_helper_proto(duk_hthread *thr, duk_uint_t hobject_flags_and_class, duk_hobject *proto);
+DUK_INTERNAL_DECL duk_hcompfunc *duk_push_hcompfunc(duk_hthread *thr);
+DUK_INTERNAL_DECL duk_hboundfunc *duk_push_hboundfunc(duk_hthread *thr);
+DUK_INTERNAL_DECL void duk_push_c_function_builtin(duk_hthread *thr, duk_c_function func, duk_int_t nargs);
+DUK_INTERNAL_DECL void duk_push_c_function_builtin_noconstruct(duk_hthread *thr, duk_c_function func, duk_int_t nargs);
/* XXX: duk_push_harray() and duk_push_hcompfunc() are inconsistent with
* duk_push_hobject() etc which don't create a new value.
*/
-DUK_INTERNAL_DECL duk_harray *duk_push_harray(duk_context *ctx);
-DUK_INTERNAL_DECL duk_harray *duk_push_harray_with_size(duk_context *ctx, duk_uint32_t size);
+DUK_INTERNAL_DECL duk_harray *duk_push_harray(duk_hthread *thr);
+DUK_INTERNAL_DECL duk_harray *duk_push_harray_with_size(duk_hthread *thr, duk_uint32_t size);
+DUK_INTERNAL_DECL duk_tval *duk_push_harray_with_size_outptr(duk_hthread *thr, duk_uint32_t size);
-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_raw(duk_context *ctx, duk_c_function func, duk_small_uint_t lf_flags);
-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 void duk_push_string_funcptr(duk_hthread *thr, duk_uint8_t *ptr, duk_size_t sz);
+DUK_INTERNAL_DECL void duk_push_lightfunc_name_raw(duk_hthread *thr, duk_c_function func, duk_small_uint_t lf_flags);
+DUK_INTERNAL_DECL void duk_push_lightfunc_name(duk_hthread *thr, duk_tval *tv);
+DUK_INTERNAL_DECL void duk_push_lightfunc_tostring(duk_hthread *thr, duk_tval *tv);
+#if 0 /* not used yet */
+DUK_INTERNAL_DECL void duk_push_hnatfunc_name(duk_hthread *thr, duk_hnatfunc *h);
+#endif
#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)
-DUK_INTERNAL_DECL duk_hbufobj *duk_push_bufobj_raw(duk_context *ctx, duk_uint_t hobject_flags_and_class, duk_small_int_t prototype_bidx);
+DUK_INTERNAL_DECL duk_hbufobj *duk_push_bufobj_raw(duk_hthread *thr, duk_uint_t hobject_flags_and_class, duk_small_int_t prototype_bidx);
#endif
-DUK_INTERNAL_DECL void *duk_push_fixed_buffer_nozero(duk_context *ctx, duk_size_t len);
-DUK_INTERNAL_DECL void *duk_push_fixed_buffer_zero(duk_context *ctx, duk_size_t len);
+DUK_INTERNAL_DECL void *duk_push_fixed_buffer_nozero(duk_hthread *thr, duk_size_t len);
+DUK_INTERNAL_DECL void *duk_push_fixed_buffer_zero(duk_hthread *thr, duk_size_t len);
-DUK_INTERNAL_DECL const char *duk_push_string_readable(duk_context *ctx, duk_idx_t idx);
-DUK_INTERNAL_DECL const char *duk_push_string_tval_readable(duk_context *ctx, duk_tval *tv);
-DUK_INTERNAL_DECL const char *duk_push_string_tval_readable_error(duk_context *ctx, duk_tval *tv);
+DUK_INTERNAL_DECL const char *duk_push_string_readable(duk_hthread *thr, duk_idx_t idx);
+DUK_INTERNAL_DECL const char *duk_push_string_tval_readable(duk_hthread *thr, duk_tval *tv);
+DUK_INTERNAL_DECL const char *duk_push_string_tval_readable_error(duk_hthread *thr, duk_tval *tv);
/* The duk_xxx_prop_stridx_short() variants expect their arguments to be short
* enough to be packed into a single 32-bit integer argument. Argument limits
@@ -5383,112 +5447,135 @@ DUK_INTERNAL_DECL const char *duk_push_string_tval_readable_error(duk_context *c
* arguments and such call sites are also easiest to verify to be correct.
*/
-DUK_INTERNAL_DECL duk_bool_t duk_get_prop_stridx(duk_context *ctx, duk_idx_t obj_idx, duk_small_uint_t stridx); /* [] -> [val] */
-DUK_INTERNAL_DECL duk_bool_t duk_get_prop_stridx_short_raw(duk_context *ctx, duk_uint_t packed_args);
-#define duk_get_prop_stridx_short(ctx,obj_idx,stridx) \
+DUK_INTERNAL_DECL duk_bool_t duk_get_prop_stridx(duk_hthread *thr, duk_idx_t obj_idx, duk_small_uint_t stridx); /* [] -> [val] */
+DUK_INTERNAL_DECL duk_bool_t duk_get_prop_stridx_short_raw(duk_hthread *thr, duk_uint_t packed_args);
+#define duk_get_prop_stridx_short(thr,obj_idx,stridx) \
(DUK_ASSERT_EXPR((duk_int_t) (obj_idx) >= -0x8000L && (duk_int_t) (obj_idx) <= 0x7fffL), \
DUK_ASSERT_EXPR((duk_int_t) (stridx) >= 0 && (duk_int_t) (stridx) <= 0xffffL), \
- duk_get_prop_stridx_short_raw((ctx), (((duk_uint_t) (obj_idx)) << 16) + ((duk_uint_t) (stridx))))
-DUK_INTERNAL_DECL duk_bool_t duk_get_prop_stridx_boolean(duk_context *ctx, duk_idx_t obj_idx, duk_small_uint_t stridx, duk_bool_t *out_has_prop); /* [] -> [] */
+ duk_get_prop_stridx_short_raw((thr), (((duk_uint_t) (obj_idx)) << 16) + ((duk_uint_t) (stridx))))
+DUK_INTERNAL_DECL duk_bool_t duk_get_prop_stridx_boolean(duk_hthread *thr, duk_idx_t obj_idx, duk_small_uint_t stridx, duk_bool_t *out_has_prop); /* [] -> [] */
-DUK_INTERNAL_DECL duk_bool_t duk_put_prop_stridx(duk_context *ctx, duk_idx_t obj_idx, duk_small_uint_t stridx); /* [val] -> [] */
-DUK_INTERNAL_DECL duk_bool_t duk_put_prop_stridx_short_raw(duk_context *ctx, duk_uint_t packed_args);
-#define duk_put_prop_stridx_short(ctx,obj_idx,stridx) \
+DUK_INTERNAL_DECL duk_bool_t duk_put_prop_stridx(duk_hthread *thr, duk_idx_t obj_idx, duk_small_uint_t stridx); /* [val] -> [] */
+DUK_INTERNAL_DECL duk_bool_t duk_put_prop_stridx_short_raw(duk_hthread *thr, duk_uint_t packed_args);
+#define duk_put_prop_stridx_short(thr,obj_idx,stridx) \
(DUK_ASSERT_EXPR((duk_int_t) (obj_idx) >= -0x8000L && (duk_int_t) (obj_idx) <= 0x7fffL), \
DUK_ASSERT_EXPR((duk_int_t) (stridx) >= 0 && (duk_int_t) (stridx) <= 0xffffL), \
- duk_put_prop_stridx_short_raw((ctx), (((duk_uint_t) (obj_idx)) << 16) + ((duk_uint_t) (stridx))))
+ duk_put_prop_stridx_short_raw((thr), (((duk_uint_t) (obj_idx)) << 16) + ((duk_uint_t) (stridx))))
-DUK_INTERNAL_DECL duk_bool_t duk_del_prop_stridx(duk_context *ctx, duk_idx_t obj_idx, duk_small_uint_t stridx); /* [] -> [] */
+DUK_INTERNAL_DECL duk_bool_t duk_del_prop_stridx(duk_hthread *thr, duk_idx_t obj_idx, duk_small_uint_t stridx); /* [] -> [] */
#if 0 /* Too few call sites to be useful. */
-DUK_INTERNAL_DECL duk_bool_t duk_del_prop_stridx_short_raw(duk_context *ctx, duk_uint_t packed_args);
-#define duk_del_prop_stridx_short(ctx,obj_idx,stridx) \
+DUK_INTERNAL_DECL duk_bool_t duk_del_prop_stridx_short_raw(duk_hthread *thr, duk_uint_t packed_args);
+#define duk_del_prop_stridx_short(thr,obj_idx,stridx) \
(DUK_ASSERT_EXPR((obj_idx) >= -0x8000L && (obj_idx) <= 0x7fffL), \
DUK_ASSERT_EXPR((stridx) >= 0 && (stridx) <= 0xffffL), \
- duk_del_prop_stridx_short_raw((ctx), (((duk_uint_t) (obj_idx)) << 16) + ((duk_uint_t) (stridx))))
+ duk_del_prop_stridx_short_raw((thr), (((duk_uint_t) (obj_idx)) << 16) + ((duk_uint_t) (stridx))))
#endif
-#define duk_del_prop_stridx_short(ctx,obj_idx,stridx) \
- duk_del_prop_stridx((ctx), (obj_idx), (stridx))
+#define duk_del_prop_stridx_short(thr,obj_idx,stridx) \
+ duk_del_prop_stridx((thr), (obj_idx), (stridx))
-DUK_INTERNAL_DECL duk_bool_t duk_has_prop_stridx(duk_context *ctx, duk_idx_t obj_idx, duk_small_uint_t stridx); /* [] -> [] */
+DUK_INTERNAL_DECL duk_bool_t duk_has_prop_stridx(duk_hthread *thr, duk_idx_t obj_idx, duk_small_uint_t stridx); /* [] -> [] */
#if 0 /* Too few call sites to be useful. */
-DUK_INTERNAL_DECL duk_bool_t duk_has_prop_stridx_short_raw(duk_context *ctx, duk_uint_t packed_args);
-#define duk_has_prop_stridx_short(ctx,obj_idx,stridx) \
+DUK_INTERNAL_DECL duk_bool_t duk_has_prop_stridx_short_raw(duk_hthread *thr, duk_uint_t packed_args);
+#define duk_has_prop_stridx_short(thr,obj_idx,stridx) \
(DUK_ASSERT_EXPR((obj_idx) >= -0x8000L && (obj_idx) <= 0x7fffL), \
DUK_ASSERT_EXPR((stridx) >= 0 && (stridx) <= 0xffffL), \
- duk_has_prop_stridx_short_raw((ctx), (((duk_uint_t) (obj_idx)) << 16) + ((duk_uint_t) (stridx))))
+ duk_has_prop_stridx_short_raw((thr), (((duk_uint_t) (obj_idx)) << 16) + ((duk_uint_t) (stridx))))
#endif
-#define duk_has_prop_stridx_short(ctx,obj_idx,stridx) \
- duk_has_prop_stridx((ctx), (obj_idx), (stridx))
+#define duk_has_prop_stridx_short(thr,obj_idx,stridx) \
+ duk_has_prop_stridx((thr), (obj_idx), (stridx))
-DUK_INTERNAL_DECL void duk_xdef_prop(duk_context *ctx, duk_idx_t obj_idx, duk_small_uint_t desc_flags); /* [key val] -> [] */
+DUK_INTERNAL_DECL void duk_xdef_prop(duk_hthread *thr, duk_idx_t obj_idx, duk_small_uint_t desc_flags); /* [key val] -> [] */
-DUK_INTERNAL_DECL void duk_xdef_prop_index(duk_context *ctx, duk_idx_t obj_idx, duk_uarridx_t arr_idx, duk_small_uint_t desc_flags); /* [val] -> [] */
+DUK_INTERNAL_DECL void duk_xdef_prop_index(duk_hthread *thr, duk_idx_t obj_idx, duk_uarridx_t arr_idx, duk_small_uint_t desc_flags); /* [val] -> [] */
/* XXX: Because stridx and desc_flags have a limited range, this call could
* always pack stridx and desc_flags into a single argument.
*/
-DUK_INTERNAL_DECL void duk_xdef_prop_stridx(duk_context *ctx, duk_idx_t obj_idx, duk_small_uint_t stridx, duk_small_uint_t desc_flags); /* [val] -> [] */
-DUK_INTERNAL_DECL void duk_xdef_prop_stridx_short_raw(duk_context *ctx, duk_uint_t packed_args);
-#define duk_xdef_prop_stridx_short(ctx,obj_idx,stridx,desc_flags) \
+DUK_INTERNAL_DECL void duk_xdef_prop_stridx(duk_hthread *thr, duk_idx_t obj_idx, duk_small_uint_t stridx, duk_small_uint_t desc_flags); /* [val] -> [] */
+DUK_INTERNAL_DECL void duk_xdef_prop_stridx_short_raw(duk_hthread *thr, duk_uint_t packed_args);
+#define duk_xdef_prop_stridx_short(thr,obj_idx,stridx,desc_flags) \
(DUK_ASSERT_EXPR((duk_int_t) (obj_idx) >= -0x80L && (duk_int_t) (obj_idx) <= 0x7fL), \
DUK_ASSERT_EXPR((duk_int_t) (stridx) >= 0 && (duk_int_t) (stridx) <= 0xffffL), \
DUK_ASSERT_EXPR((duk_int_t) (desc_flags) >= 0 && (duk_int_t) (desc_flags) <= 0xffL), \
- duk_xdef_prop_stridx_short_raw((ctx), (((duk_uint_t) (obj_idx)) << 24) + (((duk_uint_t) (stridx)) << 8) + (duk_uint_t) (desc_flags)))
+ duk_xdef_prop_stridx_short_raw((thr), (((duk_uint_t) (obj_idx)) << 24) + (((duk_uint_t) (stridx)) << 8) + (duk_uint_t) (desc_flags)))
-#define duk_xdef_prop_wec(ctx,obj_idx) \
- duk_xdef_prop((ctx), (obj_idx), DUK_PROPDESC_FLAGS_WEC)
-#define duk_xdef_prop_index_wec(ctx,obj_idx,arr_idx) \
- duk_xdef_prop_index((ctx), (obj_idx), (arr_idx), DUK_PROPDESC_FLAGS_WEC)
-#define duk_xdef_prop_stridx_wec(ctx,obj_idx,stridx) \
- duk_xdef_prop_stridx((ctx), (obj_idx), (stridx), DUK_PROPDESC_FLAGS_WEC)
-#define duk_xdef_prop_stridx_short_wec(ctx,obj_idx,stridx) \
- duk_xdef_prop_stridx_short((ctx), (obj_idx), (stridx), DUK_PROPDESC_FLAGS_WEC)
+#define duk_xdef_prop_wec(thr,obj_idx) \
+ duk_xdef_prop((thr), (obj_idx), DUK_PROPDESC_FLAGS_WEC)
+#define duk_xdef_prop_index_wec(thr,obj_idx,arr_idx) \
+ duk_xdef_prop_index((thr), (obj_idx), (arr_idx), DUK_PROPDESC_FLAGS_WEC)
+#define duk_xdef_prop_stridx_wec(thr,obj_idx,stridx) \
+ duk_xdef_prop_stridx((thr), (obj_idx), (stridx), DUK_PROPDESC_FLAGS_WEC)
+#define duk_xdef_prop_stridx_short_wec(thr,obj_idx,stridx) \
+ duk_xdef_prop_stridx_short((thr), (obj_idx), (stridx), DUK_PROPDESC_FLAGS_WEC)
-DUK_INTERNAL_DECL void duk_xdef_prop_stridx_builtin(duk_context *ctx, duk_idx_t obj_idx, duk_small_uint_t stridx, duk_small_int_t builtin_idx, duk_small_uint_t desc_flags); /* [] -> [] */
+#if 0 /*unused*/
+DUK_INTERNAL_DECL void duk_xdef_prop_stridx_builtin(duk_hthread *thr, duk_idx_t obj_idx, duk_small_uint_t stridx, duk_small_int_t builtin_idx, duk_small_uint_t desc_flags); /* [] -> [] */
+#endif
-DUK_INTERNAL_DECL void duk_xdef_prop_stridx_thrower(duk_context *ctx, duk_idx_t obj_idx, duk_small_uint_t stridx); /* [] -> [] */
+DUK_INTERNAL_DECL void duk_xdef_prop_stridx_thrower(duk_hthread *thr, duk_idx_t obj_idx, duk_small_uint_t stridx); /* [] -> [] */
-DUK_INTERNAL_DECL void duk_pack(duk_context *ctx, duk_idx_t count);
+DUK_INTERNAL_DECL void duk_pack(duk_hthread *thr, duk_idx_t count);
+DUK_INTERNAL_DECL duk_idx_t duk_unpack_array_like(duk_hthread *thr, duk_idx_t idx);
#if 0
-DUK_INTERNAL_DECL void duk_unpack(duk_context *ctx);
+DUK_INTERNAL_DECL void duk_unpack(duk_hthread *thr);
#endif
-DUK_INTERNAL_DECL void duk_require_constructor_call(duk_context *ctx);
-DUK_INTERNAL_DECL void duk_require_constructable(duk_context *ctx, duk_idx_t idx);
-DUK_INTERNAL_DECL void duk_push_symbol_descriptive_string(duk_context *ctx, duk_hstring *h);
+DUK_INTERNAL_DECL void duk_require_constructor_call(duk_hthread *thr);
+DUK_INTERNAL_DECL void duk_require_constructable(duk_hthread *thr, duk_idx_t idx);
+DUK_INTERNAL_DECL void duk_push_symbol_descriptive_string(duk_hthread *thr, duk_hstring *h);
+
+DUK_INTERNAL_DECL void duk_resolve_nonbound_function(duk_hthread *thr);
+
+DUK_INTERNAL_DECL duk_idx_t duk_get_top_require_min(duk_hthread *thr, duk_idx_t min_top);
+DUK_INTERNAL_DECL duk_idx_t duk_get_top_index_unsafe(duk_hthread *thr);
+
+DUK_INTERNAL_DECL void duk_pop_n_unsafe(duk_hthread *thr, duk_idx_t count);
+DUK_INTERNAL_DECL void duk_pop_unsafe(duk_hthread *thr);
+DUK_INTERNAL_DECL void duk_pop_2_unsafe(duk_hthread *thr);
+DUK_INTERNAL_DECL void duk_pop_3_unsafe(duk_hthread *thr);
+DUK_INTERNAL_DECL void duk_pop_n_nodecref_unsafe(duk_hthread *thr, duk_idx_t count);
+DUK_INTERNAL_DECL void duk_pop_nodecref_unsafe(duk_hthread *thr);
+DUK_INTERNAL_DECL void duk_pop_2_nodecref_unsafe(duk_hthread *thr);
+DUK_INTERNAL_DECL void duk_pop_3_nodecref_unsafe(duk_hthread *thr);
+DUK_INTERNAL_DECL void duk_pop_undefined(duk_hthread *thr);
-DUK_INTERNAL_DECL void duk_resolve_nonbound_function(duk_context *ctx);
+DUK_INTERNAL_DECL void duk_compact_m1(duk_hthread *thr);
-DUK_INTERNAL_DECL duk_idx_t duk_get_top_require_min(duk_context *ctx, duk_idx_t min_top);
-DUK_INTERNAL_DECL duk_idx_t duk_get_top_index_unsafe(duk_context *ctx);
-DUK_INTERNAL_DECL void duk_pop_n_unsafe(duk_context *ctx, duk_idx_t count);
-DUK_INTERNAL_DECL void duk_pop_n_nodecref_unsafe(duk_context *ctx, duk_idx_t count);
-DUK_INTERNAL_DECL void duk_pop_unsafe(duk_context *ctx);
+DUK_INTERNAL_DECL void duk_seal_freeze_raw(duk_hthread *thr, duk_idx_t obj_idx, duk_bool_t is_freeze);
-DUK_INTERNAL_DECL void duk_compact_m1(duk_context *ctx);
+DUK_INTERNAL_DECL void duk_insert_undefined(duk_hthread *thr, duk_idx_t idx);
+DUK_INTERNAL_DECL void duk_insert_undefined_n(duk_hthread *thr, duk_idx_t idx, duk_idx_t count);
+
+DUK_INTERNAL_DECL void duk_concat_2(duk_hthread *thr);
+
+DUK_INTERNAL_DECL duk_int_t duk_pcall_method_flags(duk_hthread *thr, duk_idx_t nargs, duk_small_uint_t call_flags);
/* Raw internal valstack access macros: access is unsafe so call site
* must have a guarantee that the index is valid. When that is the case,
* using these macro results in faster and smaller code than duk_get_tval().
* Both 'ctx' and 'idx' are evaluted multiple times, but only for asserts.
*/
-#define DUK_ASSERT_VALID_NEGIDX(ctx,idx) \
- (DUK_ASSERT_EXPR((duk_int_t) (idx) < 0), DUK_ASSERT_EXPR(duk_is_valid_index((ctx), (idx))))
-#define DUK_ASSERT_VALID_POSIDX(ctx,idx) \
- (DUK_ASSERT_EXPR((duk_int_t) (idx) >= 0), DUK_ASSERT_EXPR(duk_is_valid_index((ctx), (idx))))
-#define DUK_GET_TVAL_NEGIDX(ctx,idx) \
- (DUK_ASSERT_VALID_NEGIDX((ctx),(idx)), ((duk_hthread *) (ctx))->valstack_top + (idx))
-#define DUK_GET_TVAL_POSIDX(ctx,idx) \
- (DUK_ASSERT_VALID_POSIDX((ctx),(idx)), ((duk_hthread *) (ctx))->valstack_bottom + (idx))
-#define DUK_GET_HOBJECT_NEGIDX(ctx,idx) \
- (DUK_ASSERT_VALID_NEGIDX((ctx),(idx)), DUK_TVAL_GET_OBJECT(((duk_hthread *) (ctx))->valstack_top + (idx)))
-#define DUK_GET_HOBJECT_POSIDX(ctx,idx) \
- (DUK_ASSERT_VALID_POSIDX((ctx),(idx)), DUK_TVAL_GET_OBJECT(((duk_hthread *) (ctx))->valstack_bottom + (idx)))
+#define DUK_ASSERT_VALID_NEGIDX(thr,idx) \
+ (DUK_ASSERT_EXPR((duk_int_t) (idx) < 0), DUK_ASSERT_EXPR(duk_is_valid_index((thr), (idx))))
+#define DUK_ASSERT_VALID_POSIDX(thr,idx) \
+ (DUK_ASSERT_EXPR((duk_int_t) (idx) >= 0), DUK_ASSERT_EXPR(duk_is_valid_index((thr), (idx))))
+#define DUK_GET_TVAL_NEGIDX(thr,idx) \
+ (DUK_ASSERT_VALID_NEGIDX((thr),(idx)), ((duk_hthread *) (thr))->valstack_top + (idx))
+#define DUK_GET_TVAL_POSIDX(thr,idx) \
+ (DUK_ASSERT_VALID_POSIDX((thr),(idx)), ((duk_hthread *) (thr))->valstack_bottom + (idx))
+#define DUK_GET_HOBJECT_NEGIDX(thr,idx) \
+ (DUK_ASSERT_VALID_NEGIDX((thr),(idx)), DUK_TVAL_GET_OBJECT(((duk_hthread *) (thr))->valstack_top + (idx)))
+#define DUK_GET_HOBJECT_POSIDX(thr,idx) \
+ (DUK_ASSERT_VALID_POSIDX((thr),(idx)), DUK_TVAL_GET_OBJECT(((duk_hthread *) (thr))->valstack_bottom + (idx)))
#define DUK_GET_THIS_TVAL_PTR(thr) \
(DUK_ASSERT_EXPR((thr)->valstack_bottom > (thr)->valstack), \
(thr)->valstack_bottom - 1)
+DUK_INTERNAL_DECL duk_double_t duk_time_get_ecmascript_time(duk_hthread *thr);
+DUK_INTERNAL_DECL duk_double_t duk_time_get_ecmascript_time_nofrac(duk_hthread *thr);
+DUK_INTERNAL_DECL duk_double_t duk_time_get_monotonic_time(duk_hthread *thr);
+
#endif /* DUK_API_INTERNAL_H_INCLUDED */
/* #include duk_hstring.h */
/*
@@ -5628,7 +5715,9 @@ DUK_INTERNAL_DECL void duk_compact_m1(duk_context *ctx);
#define DUK_HSTRING_GET_DATA_END(x) \
(DUK_HSTRING_GET_DATA((x)) + (x)->blen)
-/* marker value; in E5 2^32-1 is not a valid array index (2^32-2 is highest valid) */
+/* Marker value; in E5 2^32-1 is not a valid array index (2^32-2 is highest
+ * valid).
+ */
#define DUK_HSTRING_NO_ARRAY_INDEX (0xffffffffUL)
#if defined(DUK_USE_HSTRING_ARRIDX)
@@ -5646,10 +5735,19 @@ DUK_INTERNAL_DECL void duk_compact_m1(duk_context *ctx);
(duk_js_to_arrayindex_hstring_fast((h)))
#endif
+/* XXX: these actually fit into duk_hstring */
+#define DUK_SYMBOL_TYPE_HIDDEN 0
+#define DUK_SYMBOL_TYPE_GLOBAL 1
+#define DUK_SYMBOL_TYPE_LOCAL 2
+#define DUK_SYMBOL_TYPE_WELLKNOWN 3
+
/*
* Misc
*/
+#if (DUK_USE_ALIGN_BY == 8) && defined(DUK_USE_PACK_MSVC_PRAGMA)
+#pragma pack(push, 8)
+#endif
struct duk_hstring {
/* Smaller heaphdr than for other objects, because strings are held
* in string intern table which requires no link pointers. Much of
@@ -5694,7 +5792,16 @@ struct duk_hstring {
* for strings, but fields above should guarantee alignment-by-4
* (but not alignment-by-8).
*/
-};
+}
+#if (DUK_USE_ALIGN_BY == 8) && defined(DUK_USE_PACK_GCC_ATTR)
+__attribute__ ((aligned (8)))
+#elif (DUK_USE_ALIGN_BY == 8) && defined(DUK_USE_PACK_CLANG_ATTR)
+__attribute__ ((aligned (8)))
+#endif
+;
+#if (DUK_USE_ALIGN_BY == 8) && defined(DUK_USE_PACK_MSVC_PRAGMA)
+#pragma pack(pop)
+#endif
/* The external string struct is defined even when the feature is inactive. */
struct duk_hstring_external {
@@ -5714,7 +5821,11 @@ struct duk_hstring_external {
*/
DUK_INTERNAL_DECL duk_ucodepoint_t duk_hstring_char_code_at_raw(duk_hthread *thr, duk_hstring *h, duk_uint_t pos, duk_bool_t surrogate_aware);
+DUK_INTERNAL_DECL duk_bool_t duk_hstring_equals_ascii_cstring(duk_hstring *h, const char *cstr);
DUK_INTERNAL_DECL duk_size_t duk_hstring_get_charlen(duk_hstring *h);
+#if !defined(DUK_USE_HSTRING_LAZY_CLEN)
+DUK_INTERNAL_DECL void duk_hstring_init_charlen(duk_hstring *h);
+#endif
#endif /* DUK_HSTRING_H_INCLUDED */
/* #include duk_hobject.h */
@@ -5761,7 +5872,8 @@ DUK_INTERNAL_DECL duk_size_t duk_hstring_get_charlen(duk_hstring *h);
*/
#define DUK_HOBJECT_FLAG_EXTENSIBLE DUK_HEAPHDR_USER_FLAG(0) /* object is extensible */
#define DUK_HOBJECT_FLAG_CONSTRUCTABLE DUK_HEAPHDR_USER_FLAG(1) /* object is constructable */
-#define DUK_HOBJECT_FLAG_BOUNDFUNC DUK_HEAPHDR_USER_FLAG(2) /* object established using Function.prototype.bind() */
+#define DUK_HOBJECT_FLAG_CALLABLE DUK_HEAPHDR_USER_FLAG(2) /* object is callable */
+#define DUK_HOBJECT_FLAG_BOUNDFUNC DUK_HEAPHDR_USER_FLAG(3) /* object established using Function.prototype.bind() */
#define DUK_HOBJECT_FLAG_COMPFUNC DUK_HEAPHDR_USER_FLAG(4) /* object is a compiled function (duk_hcompfunc) */
#define DUK_HOBJECT_FLAG_NATFUNC DUK_HEAPHDR_USER_FLAG(5) /* object is a native function (duk_hnatfunc) */
#define DUK_HOBJECT_FLAG_BUFOBJ DUK_HEAPHDR_USER_FLAG(6) /* object is a buffer object (duk_hbufobj) (always exotic) */
@@ -5772,12 +5884,12 @@ DUK_INTERNAL_DECL duk_size_t duk_hstring_get_charlen(duk_hstring *h);
#define DUK_HOBJECT_FLAG_NEWENV DUK_HEAPHDR_USER_FLAG(11) /* function: create new environment when called (see duk_hcompfunc) */
#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 */
-#define DUK_HOBJECT_FLAG_HAVE_FINALIZER DUK_HEAPHDR_USER_FLAG(14) /* object has a callable finalizer property */
+#define DUK_HOBJECT_FLAG_HAVE_FINALIZER DUK_HEAPHDR_USER_FLAG(14) /* object has a callable (own) finalizer property */
#define DUK_HOBJECT_FLAG_EXOTIC_ARRAY DUK_HEAPHDR_USER_FLAG(15) /* 'Array' object, array length and index exotic behavior */
#define DUK_HOBJECT_FLAG_EXOTIC_STRINGOBJ DUK_HEAPHDR_USER_FLAG(16) /* 'String' object, array index exotic behavior */
#define DUK_HOBJECT_FLAG_EXOTIC_ARGUMENTS DUK_HEAPHDR_USER_FLAG(17) /* 'Arguments' object and has arguments exotic behavior (non-strict callee) */
-#define DUK_HOBJECT_FLAG_EXOTIC_DUKFUNC DUK_HEAPHDR_USER_FLAG(18) /* Duktape/C (nativefunction) object, exotic 'length' */
-#define DUK_HOBJECT_FLAG_EXOTIC_PROXYOBJ DUK_HEAPHDR_USER_FLAG(19) /* 'Proxy' object */
+#define DUK_HOBJECT_FLAG_EXOTIC_PROXYOBJ DUK_HEAPHDR_USER_FLAG(18) /* 'Proxy' object */
+#define DUK_HOBJECT_FLAG_SPECIAL_CALL DUK_HEAPHDR_USER_FLAG(19) /* special casing in call behavior, for .call(), .apply(), etc. */
#define DUK_HOBJECT_FLAG_CLASS_BASE DUK_HEAPHDR_USER_FLAG_NUMBER(20)
#define DUK_HOBJECT_FLAG_CLASS_BITS 5
@@ -5884,8 +5996,17 @@ DUK_INTERNAL_DECL duk_size_t duk_hstring_get_charlen(duk_hstring *h);
#define DUK_HOBJECT_IS_BOUNDFUNC(h) DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_BOUNDFUNC)
#define DUK_HOBJECT_IS_COMPFUNC(h) DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_COMPFUNC)
#define DUK_HOBJECT_IS_NATFUNC(h) DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_NATFUNC)
+#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)
#define DUK_HOBJECT_IS_BUFOBJ(h) DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_BUFOBJ)
+#else
+#define DUK_HOBJECT_IS_BUFOBJ(h) 0
+#endif
#define DUK_HOBJECT_IS_THREAD(h) (DUK_HOBJECT_GET_CLASS_NUMBER((h)) == DUK_HOBJECT_CLASS_THREAD)
+#if defined(DUK_USE_ES6_PROXY)
+#define DUK_HOBJECT_IS_PROXY(h) DUK_HOBJECT_HAS_EXOTIC_PROXYOBJ((h))
+#else
+#define DUK_HOBJECT_IS_PROXY(h) 0
+#endif
#define DUK_HOBJECT_IS_NONBOUND_FUNCTION(h) DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, \
DUK_HOBJECT_FLAG_COMPFUNC | \
@@ -5896,16 +6017,12 @@ DUK_INTERNAL_DECL duk_size_t duk_hstring_get_charlen(duk_hstring *h);
DUK_HOBJECT_FLAG_COMPFUNC | \
DUK_HOBJECT_FLAG_NATFUNC)
-#define DUK_HOBJECT_IS_CALLABLE(h) DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, \
- DUK_HOBJECT_FLAG_BOUNDFUNC | \
- DUK_HOBJECT_FLAG_COMPFUNC | \
- DUK_HOBJECT_FLAG_NATFUNC)
+#define DUK_HOBJECT_IS_CALLABLE(h) DUK_HOBJECT_HAS_CALLABLE((h))
/* Object has any exotic behavior(s). */
#define DUK_HOBJECT_EXOTIC_BEHAVIOR_FLAGS (DUK_HOBJECT_FLAG_EXOTIC_ARRAY | \
DUK_HOBJECT_FLAG_EXOTIC_ARGUMENTS | \
DUK_HOBJECT_FLAG_EXOTIC_STRINGOBJ | \
- DUK_HOBJECT_FLAG_EXOTIC_DUKFUNC | \
DUK_HOBJECT_FLAG_BUFOBJ | \
DUK_HOBJECT_FLAG_EXOTIC_PROXYOBJ)
#define DUK_HOBJECT_HAS_EXOTIC_BEHAVIOR(h) DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_EXOTIC_BEHAVIOR_FLAGS)
@@ -5913,16 +6030,20 @@ DUK_INTERNAL_DECL duk_size_t duk_hstring_get_charlen(duk_hstring *h);
/* Object has any virtual properties (not counting Proxy behavior). */
#define DUK_HOBJECT_VIRTUAL_PROPERTY_FLAGS (DUK_HOBJECT_FLAG_EXOTIC_ARRAY | \
DUK_HOBJECT_FLAG_EXOTIC_STRINGOBJ | \
- DUK_HOBJECT_FLAG_EXOTIC_DUKFUNC | \
DUK_HOBJECT_FLAG_BUFOBJ)
#define DUK_HOBJECT_HAS_VIRTUAL_PROPERTIES(h) DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_VIRTUAL_PROPERTY_FLAGS)
#define DUK_HOBJECT_HAS_EXTENSIBLE(h) DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_EXTENSIBLE)
#define DUK_HOBJECT_HAS_CONSTRUCTABLE(h) DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_CONSTRUCTABLE)
+#define DUK_HOBJECT_HAS_CALLABLE(h) DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_CALLABLE)
#define DUK_HOBJECT_HAS_BOUNDFUNC(h) DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_BOUNDFUNC)
#define DUK_HOBJECT_HAS_COMPFUNC(h) DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_COMPFUNC)
#define DUK_HOBJECT_HAS_NATFUNC(h) DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_NATFUNC)
+#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)
#define DUK_HOBJECT_HAS_BUFOBJ(h) DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_BUFOBJ)
+#else
+#define DUK_HOBJECT_HAS_BUFOBJ(h) 0
+#endif
#define DUK_HOBJECT_HAS_FASTREFS(h) DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_FASTREFS)
#define DUK_HOBJECT_HAS_ARRAY_PART(h) DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_ARRAY_PART)
#define DUK_HOBJECT_HAS_STRICT(h) DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_STRICT)
@@ -5934,15 +6055,22 @@ DUK_INTERNAL_DECL duk_size_t duk_hstring_get_charlen(duk_hstring *h);
#define DUK_HOBJECT_HAS_EXOTIC_ARRAY(h) DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_EXOTIC_ARRAY)
#define DUK_HOBJECT_HAS_EXOTIC_STRINGOBJ(h) DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_EXOTIC_STRINGOBJ)
#define DUK_HOBJECT_HAS_EXOTIC_ARGUMENTS(h) DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_EXOTIC_ARGUMENTS)
-#define DUK_HOBJECT_HAS_EXOTIC_DUKFUNC(h) DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_EXOTIC_DUKFUNC)
+#if defined(DUK_USE_ES6_PROXY)
#define DUK_HOBJECT_HAS_EXOTIC_PROXYOBJ(h) DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_EXOTIC_PROXYOBJ)
+#else
+#define DUK_HOBJECT_HAS_EXOTIC_PROXYOBJ(h) 0
+#endif
+#define DUK_HOBJECT_HAS_SPECIAL_CALL(h) DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_SPECIAL_CALL)
#define DUK_HOBJECT_SET_EXTENSIBLE(h) DUK_HEAPHDR_SET_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_EXTENSIBLE)
#define DUK_HOBJECT_SET_CONSTRUCTABLE(h) DUK_HEAPHDR_SET_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_CONSTRUCTABLE)
+#define DUK_HOBJECT_SET_CALLABLE(h) DUK_HEAPHDR_SET_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_CALLABLE)
#define DUK_HOBJECT_SET_BOUNDFUNC(h) DUK_HEAPHDR_SET_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_BOUNDFUNC)
#define DUK_HOBJECT_SET_COMPFUNC(h) DUK_HEAPHDR_SET_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_COMPFUNC)
#define DUK_HOBJECT_SET_NATFUNC(h) DUK_HEAPHDR_SET_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_NATFUNC)
+#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)
#define DUK_HOBJECT_SET_BUFOBJ(h) DUK_HEAPHDR_SET_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_BUFOBJ)
+#endif
#define DUK_HOBJECT_SET_FASTREFS(h) DUK_HEAPHDR_SET_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_FASTREFS)
#define DUK_HOBJECT_SET_ARRAY_PART(h) DUK_HEAPHDR_SET_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_ARRAY_PART)
#define DUK_HOBJECT_SET_STRICT(h) DUK_HEAPHDR_SET_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_STRICT)
@@ -5954,15 +6082,20 @@ DUK_INTERNAL_DECL duk_size_t duk_hstring_get_charlen(duk_hstring *h);
#define DUK_HOBJECT_SET_EXOTIC_ARRAY(h) DUK_HEAPHDR_SET_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_EXOTIC_ARRAY)
#define DUK_HOBJECT_SET_EXOTIC_STRINGOBJ(h) DUK_HEAPHDR_SET_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_EXOTIC_STRINGOBJ)
#define DUK_HOBJECT_SET_EXOTIC_ARGUMENTS(h) DUK_HEAPHDR_SET_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_EXOTIC_ARGUMENTS)
-#define DUK_HOBJECT_SET_EXOTIC_DUKFUNC(h) DUK_HEAPHDR_SET_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_EXOTIC_DUKFUNC)
+#if defined(DUK_USE_ES6_PROXY)
#define DUK_HOBJECT_SET_EXOTIC_PROXYOBJ(h) DUK_HEAPHDR_SET_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_EXOTIC_PROXYOBJ)
+#endif
+#define DUK_HOBJECT_SET_SPECIAL_CALL(h) DUK_HEAPHDR_SET_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_SPECIAL_CALL)
#define DUK_HOBJECT_CLEAR_EXTENSIBLE(h) DUK_HEAPHDR_CLEAR_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_EXTENSIBLE)
#define DUK_HOBJECT_CLEAR_CONSTRUCTABLE(h) DUK_HEAPHDR_CLEAR_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_CONSTRUCTABLE)
+#define DUK_HOBJECT_CLEAR_CALLABLE(h) DUK_HEAPHDR_CLEAR_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_CALLABLE)
#define DUK_HOBJECT_CLEAR_BOUNDFUNC(h) DUK_HEAPHDR_CLEAR_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_BOUNDFUNC)
#define DUK_HOBJECT_CLEAR_COMPFUNC(h) DUK_HEAPHDR_CLEAR_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_COMPFUNC)
#define DUK_HOBJECT_CLEAR_NATFUNC(h) DUK_HEAPHDR_CLEAR_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_NATFUNC)
+#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)
#define DUK_HOBJECT_CLEAR_BUFOBJ(h) DUK_HEAPHDR_CLEAR_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_BUFOBJ)
+#endif
#define DUK_HOBJECT_CLEAR_FASTREFS(h) DUK_HEAPHDR_CLEAR_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_FASTREFS)
#define DUK_HOBJECT_CLEAR_ARRAY_PART(h) DUK_HEAPHDR_CLEAR_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_ARRAY_PART)
#define DUK_HOBJECT_CLEAR_STRICT(h) DUK_HEAPHDR_CLEAR_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_STRICT)
@@ -5974,25 +6107,29 @@ DUK_INTERNAL_DECL duk_size_t duk_hstring_get_charlen(duk_hstring *h);
#define DUK_HOBJECT_CLEAR_EXOTIC_ARRAY(h) DUK_HEAPHDR_CLEAR_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_EXOTIC_ARRAY)
#define DUK_HOBJECT_CLEAR_EXOTIC_STRINGOBJ(h) DUK_HEAPHDR_CLEAR_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_EXOTIC_STRINGOBJ)
#define DUK_HOBJECT_CLEAR_EXOTIC_ARGUMENTS(h) DUK_HEAPHDR_CLEAR_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_EXOTIC_ARGUMENTS)
-#define DUK_HOBJECT_CLEAR_EXOTIC_DUKFUNC(h) DUK_HEAPHDR_CLEAR_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_EXOTIC_DUKFUNC)
+#if defined(DUK_USE_ES6_PROXY)
#define DUK_HOBJECT_CLEAR_EXOTIC_PROXYOBJ(h) DUK_HEAPHDR_CLEAR_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_EXOTIC_PROXYOBJ)
+#endif
+#define DUK_HOBJECT_CLEAR_SPECIAL_CALL(h) DUK_HEAPHDR_CLEAR_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_SPECIAL_CALL)
/* Object can/cannot use FASTREFS, i.e. has no strong reference fields beyond
- * duk_hobject base header.
+ * duk_hobject base header. This is used just for asserts so doesn't need to
+ * be optimized.
*/
#define DUK_HOBJECT_PROHIBITS_FASTREFS(h) \
(DUK_HOBJECT_IS_COMPFUNC((h)) || DUK_HOBJECT_IS_DECENV((h)) || DUK_HOBJECT_IS_OBJENV((h)) || \
- DUK_HOBJECT_IS_BUFOBJ((h)) || DUK_HOBJECT_IS_THREAD((h)))
+ DUK_HOBJECT_IS_BUFOBJ((h)) || DUK_HOBJECT_IS_THREAD((h)) || DUK_HOBJECT_IS_PROXY((h)) || \
+ DUK_HOBJECT_IS_BOUNDFUNC((h)))
#define DUK_HOBJECT_ALLOWS_FASTREFS(h) (!DUK_HOBJECT_PROHIBITS_FASTREFS((h)))
/* Flags used for property attributes in duk_propdesc and packed flags.
* Must fit into 8 bits.
*/
-#define DUK_PROPDESC_FLAG_WRITABLE (1 << 0) /* E5 Section 8.6.1 */
-#define DUK_PROPDESC_FLAG_ENUMERABLE (1 << 1) /* E5 Section 8.6.1 */
-#define DUK_PROPDESC_FLAG_CONFIGURABLE (1 << 2) /* E5 Section 8.6.1 */
-#define DUK_PROPDESC_FLAG_ACCESSOR (1 << 3) /* accessor */
-#define DUK_PROPDESC_FLAG_VIRTUAL (1 << 4) /* property is virtual: used in duk_propdesc, never stored
+#define DUK_PROPDESC_FLAG_WRITABLE (1U << 0) /* E5 Section 8.6.1 */
+#define DUK_PROPDESC_FLAG_ENUMERABLE (1U << 1) /* E5 Section 8.6.1 */
+#define DUK_PROPDESC_FLAG_CONFIGURABLE (1U << 2) /* E5 Section 8.6.1 */
+#define DUK_PROPDESC_FLAG_ACCESSOR (1U << 3) /* accessor */
+#define DUK_PROPDESC_FLAG_VIRTUAL (1U << 4) /* property is virtual: used in duk_propdesc, never stored
* (used by e.g. buffer virtual properties)
*/
#define DUK_PROPDESC_FLAGS_MASK (DUK_PROPDESC_FLAG_WRITABLE | \
@@ -6003,7 +6140,7 @@ DUK_INTERNAL_DECL duk_size_t duk_hstring_get_charlen(duk_hstring *h);
/* Additional flags which are passed in the same flags argument as property
* flags but are not stored in object properties.
*/
-#define DUK_PROPDESC_FLAG_NO_OVERWRITE (1 << 4) /* internal define property: skip write silently if exists */
+#define DUK_PROPDESC_FLAG_NO_OVERWRITE (1U << 4) /* internal define property: skip write silently if exists */
/* Convenience defines for property attributes. */
#define DUK_PROPDESC_FLAGS_NONE 0
@@ -6018,8 +6155,8 @@ DUK_INTERNAL_DECL duk_size_t duk_hstring_get_charlen(duk_hstring *h);
DUK_PROPDESC_FLAG_CONFIGURABLE)
/* Flags for duk_hobject_get_own_propdesc() and variants. */
-#define DUK_GETDESC_FLAG_PUSH_VALUE (1 << 0) /* push value to stack */
-#define DUK_GETDESC_FLAG_IGNORE_PROTOLOOP (1 << 1) /* don't throw for prototype loop */
+#define DUK_GETDESC_FLAG_PUSH_VALUE (1U << 0) /* push value to stack */
+#define DUK_GETDESC_FLAG_IGNORE_PROTOLOOP (1U << 1) /* don't throw for prototype loop */
/*
* Macro for object validity check
@@ -6328,9 +6465,6 @@ DUK_INTERNAL_DECL duk_size_t duk_hstring_get_charlen(duk_hstring *h);
*/
#define DUK_HOBJECT_PROTOTYPE_CHAIN_SANITY 10000L
-/* Maximum traversal depth for "bound function" chains. */
-#define DUK_HOBJECT_BOUND_CHAIN_SANITY 10000L
-
/*
* Ecmascript [[Class]]
*/
@@ -6362,9 +6496,22 @@ DUK_INTERNAL_DECL duk_size_t duk_hstring_get_charlen(duk_hstring *h);
} while (0)
#endif
-/* note: this updates refcounts */
+/* Set prototype, DECREF earlier value, INCREF new value (tolerating NULLs). */
#define DUK_HOBJECT_SET_PROTOTYPE_UPDREF(thr,h,p) duk_hobject_set_prototype_updref((thr), (h), (p))
+/* Set initial prototype, assume NULL previous prototype, INCREF new value,
+ * tolerate NULL.
+ */
+#define DUK_HOBJECT_SET_PROTOTYPE_INIT_INCREF(thr,h,proto) do { \
+ duk_hthread *duk__thr = (thr); \
+ duk_hobject *duk__obj = (h); \
+ duk_hobject *duk__proto = (proto); \
+ DUK_UNREF(duk__thr); \
+ DUK_ASSERT(DUK_HOBJECT_GET_PROTOTYPE(duk__thr->heap, duk__obj) == NULL); \
+ DUK_HOBJECT_SET_PROTOTYPE(duk__thr->heap, duk__obj, duk__proto); \
+ DUK_HOBJECT_INCREF_ALLOWNULL(duk__thr, duk__proto); \
+ } while (0)
+
/*
* Finalizer check
*/
@@ -6560,6 +6707,7 @@ DUK_INTERNAL_DECL duk_hobject *duk_hobject_alloc(duk_hthread *thr, duk_uint_t ho
DUK_INTERNAL_DECL duk_harray *duk_harray_alloc(duk_hthread *thr, duk_uint_t hobject_flags);
DUK_INTERNAL_DECL duk_hcompfunc *duk_hcompfunc_alloc(duk_hthread *thr, duk_uint_t hobject_flags);
DUK_INTERNAL_DECL duk_hnatfunc *duk_hnatfunc_alloc(duk_hthread *thr, duk_uint_t hobject_flags);
+DUK_INTERNAL_DECL duk_hboundfunc *duk_hboundfunc_alloc(duk_heap *heap, duk_uint_t hobject_flags);
#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)
DUK_INTERNAL_DECL duk_hbufobj *duk_hbufobj_alloc(duk_hthread *thr, duk_uint_t hobject_flags);
#endif
@@ -6567,6 +6715,7 @@ DUK_INTERNAL_DECL duk_hthread *duk_hthread_alloc_unchecked(duk_heap *heap, duk_u
DUK_INTERNAL_DECL duk_hthread *duk_hthread_alloc(duk_hthread *thr, duk_uint_t hobject_flags);
DUK_INTERNAL_DECL duk_hdecenv *duk_hdecenv_alloc(duk_hthread *thr, duk_uint_t hobject_flags);
DUK_INTERNAL_DECL duk_hobjenv *duk_hobjenv_alloc(duk_hthread *thr, duk_uint_t hobject_flags);
+DUK_INTERNAL_DECL duk_hproxy *duk_hproxy_alloc(duk_hthread *thr, duk_uint_t hobject_flags);
/* resize */
DUK_INTERNAL_DECL void duk_hobject_realloc_props(duk_hthread *thr,
@@ -6575,11 +6724,19 @@ DUK_INTERNAL_DECL void duk_hobject_realloc_props(duk_hthread *thr,
duk_uint32_t new_a_size,
duk_uint32_t new_h_size,
duk_bool_t abandon_array);
+DUK_INTERNAL_DECL void duk_hobject_resize_entrypart(duk_hthread *thr,
+ duk_hobject *obj,
+ duk_uint32_t new_e_size);
+#if 0 /*unused*/
+DUK_INTERNAL_DECL void duk_hobject_resize_arraypart(duk_hthread *thr,
+ duk_hobject *obj,
+ duk_uint32_t new_a_size);
+#endif
/* low-level property functions */
-DUK_INTERNAL_DECL void duk_hobject_find_existing_entry(duk_heap *heap, duk_hobject *obj, duk_hstring *key, duk_int_t *e_idx, duk_int_t *h_idx);
+DUK_INTERNAL_DECL duk_bool_t duk_hobject_find_existing_entry(duk_heap *heap, duk_hobject *obj, duk_hstring *key, duk_int_t *e_idx, duk_int_t *h_idx);
DUK_INTERNAL_DECL duk_tval *duk_hobject_find_existing_entry_tval_ptr(duk_heap *heap, duk_hobject *obj, duk_hstring *key);
-DUK_INTERNAL_DECL duk_tval *duk_hobject_find_existing_entry_tval_ptr_and_attrs(duk_heap *heap, duk_hobject *obj, duk_hstring *key, duk_int_t *out_attrs);
+DUK_INTERNAL_DECL duk_tval *duk_hobject_find_existing_entry_tval_ptr_and_attrs(duk_heap *heap, duk_hobject *obj, duk_hstring *key, duk_uint_t *out_attrs);
DUK_INTERNAL_DECL duk_tval *duk_hobject_find_existing_array_entry_tval_ptr(duk_heap *heap, duk_hobject *obj, duk_uarridx_t i);
DUK_INTERNAL_DECL duk_bool_t duk_hobject_get_own_propdesc(duk_hthread *thr, duk_hobject *obj, duk_hstring *key, duk_propdesc *out_desc, duk_small_uint_t flags);
@@ -6596,8 +6753,8 @@ DUK_INTERNAL_DECL duk_bool_t duk_hobject_delprop(duk_hthread *thr, duk_tval *tv_
DUK_INTERNAL_DECL duk_bool_t duk_hobject_hasprop(duk_hthread *thr, duk_tval *tv_obj, duk_tval *tv_key);
/* internal property functions */
-#define DUK_DELPROP_FLAG_THROW (1 << 0)
-#define DUK_DELPROP_FLAG_FORCE (1 << 1)
+#define DUK_DELPROP_FLAG_THROW (1U << 0)
+#define DUK_DELPROP_FLAG_FORCE (1U << 1)
DUK_INTERNAL_DECL duk_bool_t duk_hobject_delprop_raw(duk_hthread *thr, duk_hobject *obj, duk_hstring *key, duk_small_uint_t flags);
DUK_INTERNAL_DECL duk_bool_t duk_hobject_hasprop_raw(duk_hthread *thr, duk_hobject *obj, duk_hstring *key);
DUK_INTERNAL_DECL void duk_hobject_define_property_internal(duk_hthread *thr, duk_hobject *obj, duk_hstring *key, duk_small_uint_t flags);
@@ -6610,28 +6767,26 @@ DUK_INTERNAL_DECL duk_bool_t duk_hobject_has_finalizer_fast_raw(duk_hobject *obj
#endif
/* helpers for defineProperty() and defineProperties() */
-DUK_INTERNAL_DECL
-void duk_hobject_prepare_property_descriptor(duk_context *ctx,
- duk_idx_t idx_in,
- duk_uint_t *out_defprop_flags,
- duk_idx_t *out_idx_value,
- duk_hobject **out_getter,
- duk_hobject **out_setter);
-DUK_INTERNAL_DECL
-duk_bool_t duk_hobject_define_property_helper(duk_context *ctx,
- duk_uint_t defprop_flags,
- duk_hobject *obj,
- duk_hstring *key,
- duk_idx_t idx_value,
- duk_hobject *get,
- duk_hobject *set,
- duk_bool_t throw_flag);
+DUK_INTERNAL_DECL void duk_hobject_prepare_property_descriptor(duk_hthread *thr,
+ duk_idx_t idx_in,
+ duk_uint_t *out_defprop_flags,
+ duk_idx_t *out_idx_value,
+ duk_hobject **out_getter,
+ duk_hobject **out_setter);
+DUK_INTERNAL_DECL duk_bool_t duk_hobject_define_property_helper(duk_hthread *thr,
+ duk_uint_t defprop_flags,
+ duk_hobject *obj,
+ duk_hstring *key,
+ duk_idx_t idx_value,
+ duk_hobject *get,
+ duk_hobject *set,
+ duk_bool_t throw_flag);
/* Object built-in methods */
-DUK_INTERNAL_DECL void duk_hobject_object_get_own_property_descriptor(duk_context *ctx, duk_idx_t obj_idx);
+DUK_INTERNAL_DECL void duk_hobject_object_get_own_property_descriptor(duk_hthread *thr, duk_idx_t obj_idx);
DUK_INTERNAL_DECL void duk_hobject_object_seal_freeze_helper(duk_hthread *thr, duk_hobject *obj, duk_bool_t is_freeze);
DUK_INTERNAL_DECL duk_bool_t duk_hobject_object_is_sealed_frozen_helper(duk_hthread *thr, duk_hobject *obj, duk_bool_t is_frozen);
-DUK_INTERNAL_DECL duk_bool_t duk_hobject_object_ownprop_helper(duk_context *ctx, duk_small_uint_t required_desc_flags);
+DUK_INTERNAL_DECL duk_bool_t duk_hobject_object_ownprop_helper(duk_hthread *thr, duk_small_uint_t required_desc_flags);
/* internal properties */
DUK_INTERNAL_DECL duk_bool_t duk_hobject_get_internal_value(duk_heap *heap, duk_hobject *obj, duk_tval *tv);
@@ -6642,14 +6797,14 @@ DUK_INTERNAL_DECL void duk_hobject_compact_props(duk_hthread *thr, duk_hobject *
/* ES2015 proxy */
#if defined(DUK_USE_ES6_PROXY)
-DUK_INTERNAL_DECL duk_bool_t duk_hobject_proxy_check(duk_hthread *thr, duk_hobject *obj, duk_hobject **out_target, duk_hobject **out_handler);
-DUK_INTERNAL_DECL duk_hobject *duk_hobject_resolve_proxy_target(duk_hthread *thr, duk_hobject *obj);
+DUK_INTERNAL_DECL duk_bool_t duk_hobject_proxy_check(duk_hobject *obj, duk_hobject **out_target, duk_hobject **out_handler);
+DUK_INTERNAL_DECL duk_hobject *duk_hobject_resolve_proxy_target(duk_hobject *obj);
#endif
/* enumeration */
-DUK_INTERNAL_DECL void duk_hobject_enumerator_create(duk_context *ctx, duk_small_uint_t enum_flags);
-DUK_INTERNAL_DECL duk_ret_t duk_hobject_get_enumerated_keys(duk_context *ctx, duk_small_uint_t enum_flags);
-DUK_INTERNAL_DECL duk_bool_t duk_hobject_enumerator_next(duk_context *ctx, duk_bool_t get_value);
+DUK_INTERNAL_DECL void duk_hobject_enumerator_create(duk_hthread *thr, duk_small_uint_t enum_flags);
+DUK_INTERNAL_DECL duk_ret_t duk_hobject_get_enumerated_keys(duk_hthread *thr, duk_small_uint_t enum_flags);
+DUK_INTERNAL_DECL duk_bool_t duk_hobject_enumerator_next(duk_hthread *thr, duk_bool_t get_value);
/* macros */
DUK_INTERNAL_DECL void duk_hobject_set_prototype_updref(duk_hthread *thr, duk_hobject *h, duk_hobject *p);
@@ -6657,7 +6812,7 @@ DUK_INTERNAL_DECL void duk_hobject_set_prototype_updref(duk_hthread *thr, duk_ho
/* pc2line */
#if defined(DUK_USE_PC2LINE)
DUK_INTERNAL_DECL void duk_hobject_pc2line_pack(duk_hthread *thr, duk_compiler_instr *instrs, duk_uint_fast32_t length);
-DUK_INTERNAL_DECL duk_uint_fast32_t duk_hobject_pc2line_query(duk_context *ctx, duk_idx_t idx_func, duk_uint_fast32_t pc);
+DUK_INTERNAL_DECL duk_uint_fast32_t duk_hobject_pc2line_query(duk_hthread *thr, duk_idx_t idx_func, duk_uint_fast32_t pc);
#endif
/* misc */
@@ -6667,8 +6822,8 @@ DUK_INTERNAL_DECL duk_bool_t duk_hobject_prototype_chain_contains(duk_hthread *t
/* These declarations are needed when related built-in is disabled and
* genbuiltins.py won't automatically emit the declerations.
*/
-DUK_INTERNAL_DECL duk_ret_t duk_bi_object_prototype_to_string(duk_context *ctx);
-DUK_INTERNAL_DECL duk_ret_t duk_bi_function_prototype(duk_context *ctx);
+DUK_INTERNAL_DECL duk_ret_t duk_bi_object_prototype_to_string(duk_hthread *thr);
+DUK_INTERNAL_DECL duk_ret_t duk_bi_function_prototype(duk_hthread *thr);
#endif
#endif /* DUK_HOBJECT_H_INCLUDED */
@@ -6802,6 +6957,13 @@ DUK_INTERNAL_DECL duk_ret_t duk_bi_function_prototype(duk_context *ctx);
#define DUK_HCOMPFUNC_GET_CODE_COUNT(heap,h) \
((duk_size_t) (DUK_HCOMPFUNC_GET_CODE_SIZE((heap), (h)) / sizeof(duk_instr_t)))
+/*
+ * Validity assert
+ */
+
+#define DUK_ASSERT_HCOMPFUNC_VALID(h) do { \
+ DUK_ASSERT((h) != NULL); \
+ } while (0)
/*
* Main struct
@@ -6964,11 +7126,52 @@ struct duk_hnatfunc {
* versa.
*
* Note: cannot place nargs/magic into the heaphdr flags, because
- * duk_hobject takes almost all flags already (and needs the spare).
+ * duk_hobject takes almost all flags already.
*/
};
#endif /* DUK_HNATFUNC_H_INCLUDED */
+/* #include duk_hboundfunc.h */
+/*
+ * Bound function representation.
+ */
+
+#if !defined(DUK_HBOUNDFUNC_H_INCLUDED)
+#define DUK_HBOUNDFUNC_H_INCLUDED
+
+/* Artificial limit for args length. Ensures arithmetic won't overflow
+ * 32 bits when combining bound functions.
+ */
+#define DUK_HBOUNDFUNC_MAX_ARGS 0x20000000UL
+
+#define DUK_ASSERT_HBOUNDFUNC_VALID(h) do { \
+ DUK_ASSERT((h) != NULL); \
+ DUK_ASSERT(DUK_HOBJECT_IS_BOUNDFUNC((duk_hobject *) (h))); \
+ DUK_ASSERT(DUK_TVAL_IS_LIGHTFUNC(&(h)->target) || \
+ (DUK_TVAL_IS_OBJECT(&(h)->target) && \
+ DUK_HOBJECT_IS_CALLABLE(DUK_TVAL_GET_OBJECT(&(h)->target)))); \
+ DUK_ASSERT(!DUK_TVAL_IS_UNUSED(&(h)->this_binding)); \
+ DUK_ASSERT((h)->nargs == 0 || (h)->args != NULL); \
+ } while (0)
+
+struct duk_hboundfunc {
+ /* Shared object part. */
+ duk_hobject obj;
+
+ /* Final target function, stored as duk_tval so that lightfunc can be
+ * represented too.
+ */
+ duk_tval target;
+
+ /* This binding. */
+ duk_tval this_binding;
+
+ /* Arguments to prepend. */
+ duk_tval *args; /* Separate allocation. */
+ duk_idx_t nargs;
+};
+
+#endif /* DUK_HBOUNDFUNC_H_INCLUDED */
/* #include duk_hbufobj.h */
/*
* Heap Buffer object representation. Used for all Buffer variants.
@@ -7106,9 +7309,9 @@ struct duk_hbufobj {
DUK_INTERNAL_DECL duk_uint_t duk_hbufobj_clamp_bytelength(duk_hbufobj *h_bufobj, duk_uint_t len);
DUK_INTERNAL_DECL void duk_hbufobj_push_uint8array_from_plain(duk_hthread *thr, duk_hbuffer *h_buf);
-DUK_INTERNAL_DECL void duk_hbufobj_push_validated_read(duk_context *ctx, duk_hbufobj *h_bufobj, duk_uint8_t *p, duk_small_uint_t elem_size);
-DUK_INTERNAL_DECL void duk_hbufobj_validated_write(duk_context *ctx, duk_hbufobj *h_bufobj, duk_uint8_t *p, duk_small_uint_t elem_size);
-DUK_INTERNAL_DECL void duk_hbufobj_promote_plain(duk_context *ctx, duk_idx_t idx);
+DUK_INTERNAL_DECL void duk_hbufobj_push_validated_read(duk_hthread *thr, duk_hbufobj *h_bufobj, duk_uint8_t *p, duk_small_uint_t elem_size);
+DUK_INTERNAL_DECL void duk_hbufobj_validated_write(duk_hthread *thr, duk_hbufobj *h_bufobj, duk_uint8_t *p, duk_small_uint_t elem_size);
+DUK_INTERNAL_DECL void duk_hbufobj_promote_plain(duk_hthread *thr, duk_idx_t idx);
#endif /* DUK_USE_BUFFEROBJECT_SUPPORT */
#endif /* DUK_HBUFOBJ_H_INCLUDED */
@@ -7116,8 +7319,9 @@ DUK_INTERNAL_DECL void duk_hbufobj_promote_plain(duk_context *ctx, duk_idx_t idx
/*
* Heap thread object representation.
*
- * duk_hthread is also the 'context' (duk_context) for exposed APIs
- * which mostly operate on the topmost frame of the value stack.
+ * duk_hthread is also the 'context' for public API functions via a
+ * different typedef. Most API calls operate on the topmost frame
+ * of the value stack only.
*/
#if !defined(DUK_HTHREAD_H_INCLUDED)
@@ -7127,61 +7331,46 @@ DUK_INTERNAL_DECL void duk_hbufobj_promote_plain(duk_context *ctx, duk_idx_t idx
* Stack constants
*/
-#define DUK_VALSTACK_GROW_STEP 128 /* roughly 1 kiB */
-#define DUK_VALSTACK_SHRINK_THRESHOLD 256 /* roughly 2 kiB */
-#define DUK_VALSTACK_SHRINK_SPARE 64 /* roughly 0.5 kiB */
-#define DUK_VALSTACK_INITIAL_SIZE 128 /* roughly 1.0 kiB -> but rounds up to DUK_VALSTACK_GROW_STEP in practice */
-#define DUK_VALSTACK_INTERNAL_EXTRA 64 /* internal extra elements assumed on function entry,
- * always added to user-defined 'extra' for e.g. the
- * duk_check_stack() call.
- */
-#define DUK_VALSTACK_API_ENTRY_MINIMUM DUK_API_ENTRY_STACK
- /* number of elements guaranteed to be user accessible
- * (in addition to call arguments) on Duktape/C function entry.
- */
+/* Initial valstack size, roughly 0.7kiB. */
+#define DUK_VALSTACK_INITIAL_SIZE 96U
-/* Note: DUK_VALSTACK_INITIAL_SIZE must be >= DUK_VALSTACK_API_ENTRY_MINIMUM
- * + DUK_VALSTACK_INTERNAL_EXTRA so that the initial stack conforms to spare
- * requirements.
+/* Internal extra elements assumed on function entry, always added to
+ * user-defined 'extra' for e.g. the duk_check_stack() call.
*/
+#define DUK_VALSTACK_INTERNAL_EXTRA 32U
-#define DUK_VALSTACK_DEFAULT_MAX 1000000L
-
-#define DUK_CALLSTACK_GROW_STEP 8 /* roughly 256 bytes */
-#define DUK_CALLSTACK_SHRINK_THRESHOLD 16 /* roughly 512 bytes */
-#define DUK_CALLSTACK_SHRINK_SPARE 8 /* roughly 256 bytes */
-#define DUK_CALLSTACK_INITIAL_SIZE 8
-#define DUK_CALLSTACK_DEFAULT_MAX 10000L
-
-#define DUK_CATCHSTACK_GROW_STEP 4 /* roughly 64 bytes */
-#define DUK_CATCHSTACK_SHRINK_THRESHOLD 8 /* roughly 128 bytes */
-#define DUK_CATCHSTACK_SHRINK_SPARE 4 /* roughly 64 bytes */
-#define DUK_CATCHSTACK_INITIAL_SIZE 4
-#define DUK_CATCHSTACK_DEFAULT_MAX 10000L
+/* Number of elements guaranteed to be user accessible (in addition to call
+ * arguments) on Duktape/C function entry. This is the major public API
+ * commitment.
+ */
+#define DUK_VALSTACK_API_ENTRY_MINIMUM DUK_API_ENTRY_STACK
/*
* Activation defines
*/
-#define DUK_ACT_FLAG_STRICT (1 << 0) /* function executes in strict mode */
-#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 */
-#define DUK_ACT_FLAG_BREAKPOINT_ACTIVE (1 << 5) /* activation has active breakpoint(s) */
+#define DUK_ACT_FLAG_STRICT (1U << 0) /* function executes in strict mode */
+#define DUK_ACT_FLAG_TAILCALLED (1U << 1) /* activation has tail called one or more times */
+#define DUK_ACT_FLAG_CONSTRUCT (1U << 2) /* function executes as a constructor (called via "new") */
+#define DUK_ACT_FLAG_PREVENT_YIELD (1U << 3) /* activation prevents yield (native call or "new") */
+#define DUK_ACT_FLAG_DIRECT_EVAL (1U << 4) /* activation is a direct eval call */
+#define DUK_ACT_FLAG_CONSTRUCT_PROXY (1U << 5) /* activation is for Proxy 'construct' call, special return value handling */
+#define DUK_ACT_FLAG_BREAKPOINT_ACTIVE (1U << 6) /* activation has active breakpoint(s) */
-#define DUK_ACT_GET_FUNC(act) ((act)->func)
+#define DUK_ACT_GET_FUNC(act) ((act)->func)
/*
* Flags for __FILE__ / __LINE__ registered into tracedata
*/
-#define DUK_TB_FLAG_NOBLAME_FILELINE (1 << 0) /* don't report __FILE__ / __LINE__ as fileName/lineNumber */
+#define DUK_TB_FLAG_NOBLAME_FILELINE (1U << 0) /* don't report __FILE__ / __LINE__ as fileName/lineNumber */
/*
* Catcher defines
*/
+/* XXX: remove catcher type entirely */
+
/* flags field: LLLLLLFT, L = label (24 bits), F = flags (4 bits), T = type (4 bits) */
#define DUK_CAT_TYPE_MASK 0x0000000fUL
#define DUK_CAT_TYPE_BITS 4
@@ -7189,10 +7378,10 @@ DUK_INTERNAL_DECL void duk_hbufobj_promote_plain(duk_context *ctx, duk_idx_t idx
#define DUK_CAT_LABEL_BITS 24
#define DUK_CAT_LABEL_SHIFT 8
-#define DUK_CAT_FLAG_CATCH_ENABLED (1 << 4) /* catch part will catch */
-#define DUK_CAT_FLAG_FINALLY_ENABLED (1 << 5) /* finally part will catch */
-#define DUK_CAT_FLAG_CATCH_BINDING_ENABLED (1 << 6) /* request to create catch binding */
-#define DUK_CAT_FLAG_LEXENV_ACTIVE (1 << 7) /* catch or with binding is currently active */
+#define DUK_CAT_FLAG_CATCH_ENABLED (1U << 4) /* catch part will catch */
+#define DUK_CAT_FLAG_FINALLY_ENABLED (1U << 5) /* finally part will catch */
+#define DUK_CAT_FLAG_CATCH_BINDING_ENABLED (1U << 6) /* request to create catch binding */
+#define DUK_CAT_FLAG_LEXENV_ACTIVE (1U << 7) /* catch or with binding is currently active */
#define DUK_CAT_TYPE_UNKNOWN 0
#define DUK_CAT_TYPE_TCF 1
@@ -7273,25 +7462,39 @@ DUK_INTERNAL_DECL void duk_hbufobj_promote_plain(duk_context *ctx, duk_idx_t idx
* 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); \
- DUK_ASSERT(DUK_HOBJECT_IS_THREAD((duk_hobject *) (ctx))); \
- DUK_ASSERT(((duk_hthread *) (ctx))->unused1 == 0); \
- DUK_ASSERT(((duk_hthread *) (ctx))->unused2 == 0); \
- DUK_ASSERT(((duk_hthread *) (ctx))->valstack != NULL); \
- 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)); \
+/* Assertions for internals. */
+#define DUK_ASSERT_HTHREAD_VALID(thr) do { \
+ DUK_ASSERT((thr) != NULL); \
+ DUK_ASSERT(DUK_HEAPHDR_GET_TYPE((duk_heaphdr *) (thr)) == DUK_HTYPE_OBJECT); \
+ DUK_ASSERT(DUK_HOBJECT_IS_THREAD((duk_hobject *) (thr))); \
+ DUK_ASSERT((thr)->unused1 == 0); \
+ DUK_ASSERT((thr)->unused2 == 0); \
+ } while (0)
+
+/* Assertions for public API calls; a bit stronger. */
+#define DUK_ASSERT_CTX_VALID(thr) do { \
+ DUK_ASSERT((thr) != NULL); \
+ DUK_ASSERT_HTHREAD_VALID((thr)); \
+ DUK_ASSERT((thr)->valstack != NULL); \
+ DUK_ASSERT((thr)->valstack_bottom != NULL); \
+ DUK_ASSERT((thr)->valstack_top != NULL); \
+ DUK_ASSERT((thr)->valstack_end != NULL); \
+ DUK_ASSERT((thr)->valstack_alloc_end != NULL); \
+ DUK_ASSERT((thr)->valstack_alloc_end >= (thr)->valstack); \
+ DUK_ASSERT((thr)->valstack_end >= (thr)->valstack); \
+ DUK_ASSERT((thr)->valstack_top >= (thr)->valstack); \
+ DUK_ASSERT((thr)->valstack_top >= (thr)->valstack_bottom); \
+ DUK_ASSERT((thr)->valstack_end >= (thr)->valstack_top); \
+ DUK_ASSERT((thr)->valstack_alloc_end >= (thr)->valstack_end); \
+ } while (0)
+
+/* Assertions for API call entry specifically. Checks 'ctx' but also may
+ * check internal state (e.g. not in a debugger transport callback).
+ */
+#define DUK_ASSERT_API_ENTRY(thr) do { \
+ DUK_ASSERT_CTX_VALID((thr)); \
+ DUK_ASSERT((thr)->heap != NULL); \
+ DUK_ASSERT((thr)->heap->dbg_calling_transport == 0); \
} while (0)
/*
@@ -7318,16 +7521,15 @@ DUK_INTERNAL_DECL void duk_hbufobj_promote_plain(duk_context *ctx, duk_idx_t idx
* Struct defines
*/
-/* XXX: for a memory-code tradeoff, remove 'func' and make it's access either a function
- * or a macro. This would make the activation 32 bytes long on 32-bit platforms again.
- */
-
-/* Note: it's nice if size is 2^N (at least for 32-bit platforms). */
+/* Fields are ordered for alignment/packing. */
struct duk_activation {
duk_tval tv_func; /* borrowed: full duk_tval for function being executed; for lightfuncs */
duk_hobject *func; /* borrowed: function being executed; for bound function calls, this is the final, real function, NULL for lightfuncs */
+ duk_activation *parent; /* previous (parent) activation (or NULL if none) */
duk_hobject *var_env; /* current variable environment (may be NULL if delayed) */
duk_hobject *lex_env; /* current lexical environment (may be NULL if delayed) */
+ duk_catcher *cat; /* current catcher (or NULL) */
+
#if defined(DUK_USE_NONSTD_FUNC_CALLER_PROPERTY)
/* Previous value of 'func' caller, restored when unwound. Only in use
* when 'func' is non-strict.
@@ -7336,52 +7538,61 @@ struct duk_activation {
#endif
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
- * function properly. They are duk_size_t to match the convention
- * that value stack sizes are duk_size_t and local frame indices
- * are duk_idx_t.
+ /* bottom_byteoff and retval_byteoff are only used for book-keeping
+ * of Ecmascript-initiated calls, to allow returning to an Ecmascript
+ * function properly.
*/
/* Bottom of valstack for this activation, used to reset
- * valstack_bottom on return; index is absolute. Note:
- * idx_top not needed because top is set to 'nregs' always
- * when returning to an Ecmascript activation.
+ * valstack_bottom on return; offset is absolute. There's
+ * no need to track 'top' because native call handling deals
+ * with that using locals, and for Ecmascript returns 'nregs'
+ * indicates the necessary top.
*/
- duk_size_t idx_bottom;
+ duk_size_t bottom_byteoff;
/* Return value when returning to this activation (points to caller
- * reg, not callee reg); index is absolute (only set if activation is
+ * reg, not callee reg); offset is absolute (only set if activation is
* not topmost).
*
- * Note: idx_bottom is always set, while idx_retval is only applicable
- * for activations below the topmost one. Currently idx_retval for
- * the topmost activation is considered garbage (and it not initialized
- * on entry or cleared on return; may contain previous or garbage
- * values).
+ * Note: bottom_byteoff is always set, while retval_byteoff is only
+ * applicable for activations below the topmost one. Currently
+ * retval_byteoff for the topmost activation is considered garbage
+ * (and it not initialized on entry or cleared on return; may contain
+ * previous or garbage values).
*/
- duk_size_t idx_retval;
+ duk_size_t retval_byteoff;
- /* Current 'this' binding is the value just below idx_bottom.
+ /* Current 'this' binding is the value just below bottom.
* Previously, 'this' binding was handled with an index to the
* (calling) valstack. This works for everything except tail
- * calls, which must not "cumulate" valstack temps.
+ * calls, which must not "accumulate" valstack temps.
+ */
+
+ /* Value stack reserve (valstack_end) byte offset to be restored
+ * when returning to this activation. Only used by the bytecode
+ * executor.
*/
+ duk_size_t reserve_byteoff;
+
+#if defined(DUK_USE_DEBUGGER_SUPPORT)
+ duk_uint32_t prev_line; /* needed for stepping */
+#endif
+
+ duk_small_uint_t flags;
};
-/* Note: it's nice if size is 2^N (not 4x4 = 16 bytes on 32 bit) */
struct duk_catcher {
+ duk_catcher *parent; /* previous (parent) catcher (or NULL if none) */
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 flags; /* type and control flags, label number */
+ /* XXX: could pack 'flags' and 'idx_base' to same value in practice,
+ * on 32-bit targets this would make duk_catcher 16 bytes.
+ */
};
struct duk_hthread {
@@ -7406,40 +7617,49 @@ struct duk_hthread {
duk_uint8_t unused1;
duk_uint8_t unused2;
- /* 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
- * to have non-NULL pointers. Relaxing this would not lead to big
- * benefits (except perhaps for terminated threads).
+ /* XXX: Valstack and callstack 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.
- * [valstack,valstack_top[ is GC-reachable, [valstack_top,valstack_end[ is
- * not GC-reachable but kept initialized as 'undefined'.
+ /* Value stack: these are expressed as pointers for faster stack
+ * manipulation. [valstack,valstack_top[ is GC-reachable,
+ * [valstack_top,valstack_alloc_end[ is not GC-reachable but kept
+ * initialized as 'undefined'. [valstack,valstack_end[ is the
+ * guaranteed/reserved space and the valstack cannot be resized to
+ * a smaller size. [valstack_end,valstack_alloc_end[ is currently
+ * allocated slack that can be used to grow the current guaranteed
+ * space but may be shrunk away without notice.
+ *
+ *
+ * <----------------------- guaranteed --->
+ * <---- slack --->
+ * <--- frame --->
+ * .-------------+=============+----------+--------------.
+ * |xxxxxxxxxxxxx|yyyyyyyyyyyyy|uuuuuuuuuu|uuuuuuuuuuuuuu|
+ * `-------------+=============+----------+--------------'
+ *
+ * ^ ^ ^ ^ ^
+ * | | | | |
+ * valstack bottom top end alloc_end
+ *
+ * xxx = arbitrary values, below current frame
+ * yyy = arbitrary values, inside current frame
+ * uuu = outside active value stack, initialized to 'undefined'
*/
duk_tval *valstack; /* start of valstack allocation */
- duk_tval *valstack_end; /* end of valstack allocation (exclusive) */
+ duk_tval *valstack_end; /* end of valstack reservation/guarantee (exclusive) */
+ duk_tval *valstack_alloc_end; /* end of valstack allocation */
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. [0,callstack_top[ is GC reachable. */
- duk_activation *callstack;
+ /* Call stack, represented as a linked list starting from the current
+ * activation (or NULL if nothing is active).
+ */
duk_activation *callstack_curr; /* current activation (or NULL if none) */
- duk_size_t callstack_size; /* allocation size */
- duk_size_t callstack_top; /* next to use, highest used is top - 1 (or none if top == 0) */
+ duk_size_t callstack_top; /* number of activation records in callstack (0 if none) */
duk_size_t callstack_preventcount; /* number of activation records in callstack preventing a yield */
- /* 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. */
duk_hthread *resumer; /* who resumed us (if any) */
@@ -7492,24 +7712,22 @@ DUK_INTERNAL_DECL void duk_hthread_create_builtin_objects(duk_hthread *thr);
DUK_INTERNAL_DECL duk_bool_t duk_hthread_init_stacks(duk_heap *heap, duk_hthread *thr);
DUK_INTERNAL_DECL void duk_hthread_terminate(duk_hthread *thr);
-DUK_INTERNAL_DECL void duk_hthread_callstack_grow(duk_hthread *thr);
-DUK_INTERNAL_DECL void duk_hthread_callstack_shrink_check(duk_hthread *thr);
-DUK_INTERNAL_DECL void duk_hthread_callstack_unwind_norz(duk_hthread *thr, duk_size_t new_top);
-DUK_INTERNAL_DECL void duk_hthread_callstack_unwind(duk_hthread *thr, duk_size_t new_top);
-DUK_INTERNAL_DECL void duk_hthread_catchstack_grow(duk_hthread *thr);
-DUK_INTERNAL_DECL void duk_hthread_catchstack_shrink_check(duk_hthread *thr);
-DUK_INTERNAL_DECL void duk_hthread_catchstack_unwind_norz(duk_hthread *thr, duk_size_t new_top);
-DUK_INTERNAL_DECL void duk_hthread_catchstack_unwind(duk_hthread *thr, duk_size_t new_top);
+DUK_INTERNAL_DECL DUK_INLINE duk_activation *duk_hthread_activation_alloc(duk_hthread *thr);
+DUK_INTERNAL_DECL void duk_hthread_activation_free(duk_hthread *thr, duk_activation *act);
+DUK_INTERNAL_DECL void duk_hthread_activation_unwind_norz(duk_hthread *thr);
+DUK_INTERNAL_DECL void duk_hthread_activation_unwind_reuse_norz(duk_hthread *thr);
+DUK_INTERNAL_DECL duk_activation *duk_hthread_get_activation_for_level(duk_hthread *thr, duk_int_t level);
+
+DUK_INTERNAL_DECL DUK_INLINE duk_catcher *duk_hthread_catcher_alloc(duk_hthread *thr);
+DUK_INTERNAL_DECL void duk_hthread_catcher_free(duk_hthread *thr, duk_catcher *cat);
+DUK_INTERNAL_DECL void duk_hthread_catcher_unwind_norz(duk_hthread *thr, duk_activation *act);
+DUK_INTERNAL_DECL void duk_hthread_catcher_unwind_nolexenv_norz(duk_hthread *thr, duk_activation *act);
#if defined(DUK_USE_FINALIZER_TORTURE)
DUK_INTERNAL_DECL void duk_hthread_valstack_torture_realloc(duk_hthread *thr);
-DUK_INTERNAL_DECL void duk_hthread_callstack_torture_realloc(duk_hthread *thr);
-DUK_INTERNAL_DECL void duk_hthread_catchstack_torture_realloc(duk_hthread *thr);
#endif
DUK_INTERNAL_DECL void *duk_hthread_get_valstack_ptr(duk_heap *heap, void *ud); /* indirect allocs */
-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);
@@ -7521,7 +7739,7 @@ DUK_INTERNAL_DECL void duk_hthread_sync_and_null_currpc(duk_hthread *thr);
#endif /* DUK_HTHREAD_H_INCLUDED */
/* #include duk_harray.h */
/*
- * Heap Array object representation. Used for actual Array instances.
+ * Array object representation, used for actual Array instances.
*
* All objects with the exotic array behavior (which must coincide with having
* internal class array) MUST be duk_harrays. No other object can be a
@@ -7598,7 +7816,7 @@ struct duk_hdecenv {
*/
duk_hthread *thread;
duk_hobject *varmap;
- duk_size_t regbase;
+ duk_size_t regbase_byteoff;
};
struct duk_hobjenv {
@@ -7674,9 +7892,6 @@ struct duk_hobjenv {
* Field access
*/
-/* Get/set the current user visible size, without accounting for a dynamic
- * buffer's "spare" (= usable size).
- */
#if defined(DUK_USE_BUFLEN16)
/* size stored in duk_heaphdr unused flag bits */
#define DUK_HBUFFER_GET_SIZE(x) ((x)->hdr.h_flags >> 16)
@@ -7796,7 +8011,7 @@ struct duk_hbuffer {
* it is useful for writing robust native code.
*/
- /* Current size (not counting a dynamic buffer's "spare"). */
+ /* Current size. */
#if defined(DUK_USE_BUFLEN16)
/* Stored in duk_heaphdr unused flags. */
#else
@@ -7945,6 +8160,33 @@ DUK_INTERNAL_DECL void duk_hbuffer_resize(duk_hthread *thr, duk_hbuffer_dynamic
DUK_INTERNAL_DECL void duk_hbuffer_reset(duk_hthread *thr, duk_hbuffer_dynamic *buf);
#endif /* DUK_HBUFFER_H_INCLUDED */
+/* #include duk_hproxy.h */
+/*
+ * Proxy object representation.
+ */
+
+#if !defined(DUK_HPROXY_H_INCLUDED)
+#define DUK_HPROXY_H_INCLUDED
+
+#define DUK_ASSERT_HPROXY_VALID(h) do { \
+ DUK_ASSERT((h) != NULL); \
+ DUK_ASSERT((h)->target != NULL); \
+ DUK_ASSERT((h)->handler != NULL); \
+ DUK_ASSERT(DUK_HOBJECT_HAS_EXOTIC_PROXYOBJ((duk_hobject *) (h))); \
+ } while (0)
+
+struct duk_hproxy {
+ /* Shared object part. */
+ duk_hobject obj;
+
+ /* Proxy target object. */
+ duk_hobject *target;
+
+ /* Proxy handlers (traps). */
+ duk_hobject *handler;
+};
+
+#endif /* DUK_HPROXY_H_INCLUDED */
/* #include duk_heap.h */
/*
* Heap structure.
@@ -7962,11 +8204,10 @@ DUK_INTERNAL_DECL void duk_hbuffer_reset(duk_hthread *thr, duk_hbuffer_dynamic *
* Heap flags
*/
-#define DUK_HEAP_FLAG_MARKANDSWEEP_RECLIMIT_REACHED (1 << 0) /* mark-and-sweep marking reached a recursion limit and must use multi-pass marking */
-#define DUK_HEAP_FLAG_ERRHANDLER_RUNNING (1 << 1) /* an error handler (user callback to augment/replace error) is running */
-#define DUK_HEAP_FLAG_INTERRUPT_RUNNING (1 << 2) /* executor interrupt running (used to avoid nested interrupts) */
-#define DUK_HEAP_FLAG_FINALIZER_NORESCUE (1 << 3) /* heap destruction ongoing, finalizer rescue no longer possible */
-#define DUK_HEAP_FLAG_DEBUGGER_PAUSED (1 << 4) /* debugger is paused: talk with debug client until step/resume */
+#define DUK_HEAP_FLAG_MARKANDSWEEP_RECLIMIT_REACHED (1U << 0) /* mark-and-sweep marking reached a recursion limit and must use multi-pass marking */
+#define DUK_HEAP_FLAG_INTERRUPT_RUNNING (1U << 1) /* executor interrupt running (used to avoid nested interrupts) */
+#define DUK_HEAP_FLAG_FINALIZER_NORESCUE (1U << 2) /* heap destruction ongoing, finalizer rescue no longer possible */
+#define DUK_HEAP_FLAG_DEBUGGER_PAUSED (1U << 3) /* debugger is paused: talk with debug client until step/resume */
#define DUK__HEAP_HAS_FLAGS(heap,bits) ((heap)->flags & (bits))
#define DUK__HEAP_SET_FLAGS(heap,bits) do { \
@@ -7977,19 +8218,16 @@ DUK_INTERNAL_DECL void duk_hbuffer_reset(duk_hthread *thr, duk_hbuffer_dynamic *
} while (0)
#define DUK_HEAP_HAS_MARKANDSWEEP_RECLIMIT_REACHED(heap) DUK__HEAP_HAS_FLAGS((heap), DUK_HEAP_FLAG_MARKANDSWEEP_RECLIMIT_REACHED)
-#define DUK_HEAP_HAS_ERRHANDLER_RUNNING(heap) DUK__HEAP_HAS_FLAGS((heap), DUK_HEAP_FLAG_ERRHANDLER_RUNNING)
#define DUK_HEAP_HAS_INTERRUPT_RUNNING(heap) DUK__HEAP_HAS_FLAGS((heap), DUK_HEAP_FLAG_INTERRUPT_RUNNING)
#define DUK_HEAP_HAS_FINALIZER_NORESCUE(heap) DUK__HEAP_HAS_FLAGS((heap), DUK_HEAP_FLAG_FINALIZER_NORESCUE)
#define DUK_HEAP_HAS_DEBUGGER_PAUSED(heap) DUK__HEAP_HAS_FLAGS((heap), DUK_HEAP_FLAG_DEBUGGER_PAUSED)
#define DUK_HEAP_SET_MARKANDSWEEP_RECLIMIT_REACHED(heap) DUK__HEAP_SET_FLAGS((heap), DUK_HEAP_FLAG_MARKANDSWEEP_RECLIMIT_REACHED)
-#define DUK_HEAP_SET_ERRHANDLER_RUNNING(heap) DUK__HEAP_SET_FLAGS((heap), DUK_HEAP_FLAG_ERRHANDLER_RUNNING)
#define DUK_HEAP_SET_INTERRUPT_RUNNING(heap) DUK__HEAP_SET_FLAGS((heap), DUK_HEAP_FLAG_INTERRUPT_RUNNING)
#define DUK_HEAP_SET_FINALIZER_NORESCUE(heap) DUK__HEAP_SET_FLAGS((heap), DUK_HEAP_FLAG_FINALIZER_NORESCUE)
#define DUK_HEAP_SET_DEBUGGER_PAUSED(heap) DUK__HEAP_SET_FLAGS((heap), DUK_HEAP_FLAG_DEBUGGER_PAUSED)
#define DUK_HEAP_CLEAR_MARKANDSWEEP_RECLIMIT_REACHED(heap) DUK__HEAP_CLEAR_FLAGS((heap), DUK_HEAP_FLAG_MARKANDSWEEP_RECLIMIT_REACHED)
-#define DUK_HEAP_CLEAR_ERRHANDLER_RUNNING(heap) DUK__HEAP_CLEAR_FLAGS((heap), DUK_HEAP_FLAG_ERRHANDLER_RUNNING)
#define DUK_HEAP_CLEAR_INTERRUPT_RUNNING(heap) DUK__HEAP_CLEAR_FLAGS((heap), DUK_HEAP_FLAG_INTERRUPT_RUNNING)
#define DUK_HEAP_CLEAR_FINALIZER_NORESCUE(heap) DUK__HEAP_CLEAR_FLAGS((heap), DUK_HEAP_FLAG_FINALIZER_NORESCUE)
#define DUK_HEAP_CLEAR_DEBUGGER_PAUSED(heap) DUK__HEAP_CLEAR_FLAGS((heap), DUK_HEAP_FLAG_DEBUGGER_PAUSED)
@@ -8018,22 +8256,22 @@ DUK_INTERNAL_DECL void duk_hbuffer_reset(duk_hthread *thr, duk_hbuffer_dynamic *
/* Emergency mark-and-sweep: try extra hard, even at the cost of
* performance.
*/
-#define DUK_MS_FLAG_EMERGENCY (1 << 0)
+#define DUK_MS_FLAG_EMERGENCY (1U << 0)
/* Voluntary mark-and-sweep: triggered periodically. */
-#define DUK_MS_FLAG_VOLUNTARY (1 << 1)
+#define DUK_MS_FLAG_VOLUNTARY (1U << 1)
/* Postpone rescue decisions for reachable objects with FINALIZED set.
* Used during finalize_list processing to avoid incorrect rescue
* decisions due to finalize_list being a reachability root.
*/
-#define DUK_MS_FLAG_POSTPONE_RESCUE (1 << 2)
+#define DUK_MS_FLAG_POSTPONE_RESCUE (1U << 2)
/* Don't compact objects; needed during object property table resize
* to prevent a recursive resize. It would suffice to protect only the
* current object being resized, but this is not yet implemented.
*/
-#define DUK_MS_FLAG_NO_OBJECT_COMPACTION (1 << 2)
+#define DUK_MS_FLAG_NO_OBJECT_COMPACTION (1U << 3)
/*
* Thread switching
@@ -8052,6 +8290,18 @@ DUK_INTERNAL_DECL void duk_hbuffer_reset(duk_hthread *thr, duk_hbuffer_dynamic *
#endif
/*
+ * Stats
+ */
+
+#if defined(DUK_USE_DEBUG)
+#define DUK_STATS_INC(heap,fieldname) do { \
+ (heap)->fieldname += 1; \
+ } while (0)
+#else
+#define DUK_STATS_INC(heap,fieldname) do {} while (0)
+#endif
+
+/*
* Other heap related defines
*/
@@ -8168,10 +8418,14 @@ typedef void *(*duk_mem_getptr)(duk_heap *heap, void *ud);
/*
* Checked allocation, relative to a thread
+ *
+ * DUK_FREE_CHECKED() doesn't actually throw, but accepts a 'thr' argument
+ * for convenience.
*/
#define DUK_ALLOC_CHECKED(thr,size) duk_heap_mem_alloc_checked((thr), (size))
#define DUK_ALLOC_CHECKED_ZEROED(thr,size) duk_heap_mem_alloc_checked_zeroed((thr), (size))
+#define DUK_FREE_CHECKED(thr,ptr) duk_heap_mem_free((thr)->heap, (ptr))
/*
* Memory constants
@@ -8207,11 +8461,14 @@ typedef void *(*duk_mem_getptr)(duk_heap *heap, void *ud);
/* Milliseconds between status notify and transport peeks. */
#define DUK_HEAP_DBG_RATELIMIT_MILLISECS 200
-/* Step types */
-#define DUK_STEP_TYPE_NONE 0
-#define DUK_STEP_TYPE_INTO 1
-#define DUK_STEP_TYPE_OVER 2
-#define DUK_STEP_TYPE_OUT 3
+/* Debugger pause flags. */
+#define DUK_PAUSE_FLAG_ONE_OPCODE (1U << 0) /* pause when a single opcode has been executed */
+#define DUK_PAUSE_FLAG_ONE_OPCODE_ACTIVE (1U << 1) /* one opcode pause actually active; artifact of current implementation */
+#define DUK_PAUSE_FLAG_LINE_CHANGE (1U << 2) /* pause when current line number changes */
+#define DUK_PAUSE_FLAG_FUNC_ENTRY (1U << 3) /* pause when entering a function */
+#define DUK_PAUSE_FLAG_FUNC_EXIT (1U << 4) /* pause when exiting current function */
+#define DUK_PAUSE_FLAG_CAUGHT_ERROR (1U << 5) /* pause when about to throw an error that is caught */
+#define DUK_PAUSE_FLAG_UNCAUGHT_ERROR (1U << 6) /* pause when about to throw an error that won't be caught */
struct duk_breakpoint {
duk_hstring *filename;
@@ -8307,6 +8564,14 @@ struct duk_heap {
#endif
#endif
+ /* Freelist for duk_activations and duk_catchers. */
+#if defined(DUK_USE_CACHE_ACTIVATION)
+ duk_activation *activation_free;
+#endif
+#if defined(DUK_USE_CACHE_CATCHER)
+ duk_catcher *catcher_free;
+#endif
+
/* Voluntary mark-and-sweep trigger counter. Intentionally signed
* because we continue decreasing the value when voluntary GC cannot
* run.
@@ -8370,6 +8635,14 @@ struct duk_heap {
*/
duk_bool_t creating_error;
+ /* Marker for indicating we're calling a user error augmentation
+ * (errCreate/errThrow) function. Errors created/thrown during
+ * such a call are not augmented.
+ */
+#if defined(DUK_USE_AUGMENT_ERROR_THROW) || defined(DUK_USE_AUGMENT_ERROR_CREATE)
+ duk_bool_t augmenting_error;
+#endif
+
/* Longjmp state. */
duk_ljstate lj;
@@ -8431,23 +8704,25 @@ struct duk_heap {
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_bool_t dbg_detaching; /* debugger detaching; used to avoid calling detach handler recursively */
- 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 */
- duk_uint32_t dbg_step_startline; /* starting line number */
+ duk_small_uint_t dbg_pause_flags; /* flags for automatic pause behavior */
+ duk_activation *dbg_pause_act; /* activation related to pause behavior (pause on line change, function entry/exit) */
+ duk_uint32_t dbg_pause_startline; /* starting line number for line change related pause behavior */
duk_breakpoint dbg_breakpoints[DUK_HEAP_MAX_BREAKPOINTS]; /* breakpoints: [0,breakpoint_count[ gc reachable */
duk_small_uint_t dbg_breakpoint_count;
duk_breakpoint *dbg_breakpoints_active[DUK_HEAP_MAX_BREAKPOINTS + 1]; /* currently active breakpoints: NULL term, borrowed pointers */
/* XXX: make active breakpoints actual copies instead of pointers? */
/* These are for rate limiting Status notifications and transport peeking. */
- duk_uint32_t dbg_exec_counter; /* cumulative opcode execution count (overflows are OK) */
- duk_uint32_t dbg_last_counter; /* value of dbg_exec_counter when we last did a Date-based check */
+ duk_uint_t dbg_exec_counter; /* cumulative opcode execution count (overflows are OK) */
+ duk_uint_t dbg_last_counter; /* value of dbg_exec_counter when we last did a Date-based check */
duk_double_t dbg_last_time; /* time when status/peek was last done (Date-based rate limit) */
/* Used to support single-byte stream lookahead. */
duk_bool_t dbg_have_next_byte;
duk_uint8_t dbg_next_byte;
+#endif /* DUK_USE_DEBUGGER_SUPPORT */
+#if defined(DUK_USE_ASSERTIONS)
+ duk_bool_t dbg_calling_transport; /* transport call in progress, calling into Duktape forbidden */
#endif
/* String intern table (weak refs). */
@@ -8478,6 +8753,51 @@ struct duk_heap {
duk_hstring *strs[DUK_HEAP_NUM_STRINGS];
#endif
#endif
+
+ /* Stats. */
+#if defined(DUK_USE_DEBUG)
+ duk_int_t stats_exec_opcodes;
+ duk_int_t stats_exec_interrupt;
+ duk_int_t stats_exec_throw;
+ duk_int_t stats_call_all;
+ duk_int_t stats_call_tailcall;
+ duk_int_t stats_call_ecmatoecma;
+ duk_int_t stats_safecall_all;
+ duk_int_t stats_safecall_nothrow;
+ duk_int_t stats_safecall_throw;
+ duk_int_t stats_ms_try_count;
+ duk_int_t stats_ms_skip_count;
+ duk_int_t stats_ms_emergency_count;
+ duk_int_t stats_strtab_intern_hit;
+ duk_int_t stats_strtab_intern_miss;
+ duk_int_t stats_strtab_resize_check;
+ duk_int_t stats_strtab_resize_grow;
+ duk_int_t stats_strtab_resize_shrink;
+ duk_int_t stats_object_realloc_props;
+ duk_int_t stats_object_abandon_array;
+ duk_int_t stats_getownpropdesc_count;
+ duk_int_t stats_getownpropdesc_hit;
+ duk_int_t stats_getownpropdesc_miss;
+ duk_int_t stats_getpropdesc_count;
+ duk_int_t stats_getpropdesc_hit;
+ duk_int_t stats_getpropdesc_miss;
+ duk_int_t stats_getprop_all;
+ duk_int_t stats_getprop_arrayidx;
+ duk_int_t stats_getprop_bufobjidx;
+ duk_int_t stats_getprop_bufferidx;
+ duk_int_t stats_getprop_bufferlen;
+ duk_int_t stats_getprop_stringidx;
+ duk_int_t stats_getprop_stringlen;
+ duk_int_t stats_getprop_proxy;
+ duk_int_t stats_getprop_arguments;
+ duk_int_t stats_putprop_all;
+ duk_int_t stats_putprop_arrayidx;
+ duk_int_t stats_putprop_bufobjidx;
+ duk_int_t stats_putprop_bufferidx;
+ duk_int_t stats_putprop_proxy;
+ duk_int_t stats_getvar_all;
+ duk_int_t stats_putvar_all;
+#endif
};
/*
@@ -8542,6 +8862,8 @@ DUK_INTERNAL_DECL void *duk_heap_mem_realloc(duk_heap *heap, void *ptr, duk_size
DUK_INTERNAL_DECL void *duk_heap_mem_realloc_indirect(duk_heap *heap, duk_mem_getptr cb, void *ud, duk_size_t newsize);
DUK_INTERNAL_DECL void duk_heap_mem_free(duk_heap *heap, void *ptr);
+DUK_INTERNAL_DECL void duk_heap_free_freelists(duk_heap *heap);
+
#if defined(DUK_USE_FINALIZER_SUPPORT)
DUK_INTERNAL_DECL void duk_heap_run_finalizer(duk_heap *heap, duk_hobject *obj);
DUK_INTERNAL_DECL void duk_heap_process_finalize_list(duk_heap *heap);
@@ -8628,8 +8950,8 @@ DUK_INTERNAL_DECL duk_uint32_t duk_heap_hashstring(duk_heap *heap, const duk_uin
/* The low 8 bits map directly to duk_hobject.h DUK_PROPDESC_FLAG_xxx.
* The remaining flags are specific to the debugger.
*/
-#define DUK_DBG_PROPFLAG_SYMBOL (1 << 8)
-#define DUK_DBG_PROPFLAG_HIDDEN (1 << 9)
+#define DUK_DBG_PROPFLAG_SYMBOL (1U << 8)
+#define DUK_DBG_PROPFLAG_HIDDEN (1U << 9)
#if defined(DUK_USE_DEBUGGER_SUPPORT)
DUK_INTERNAL_DECL void duk_debug_do_detach(duk_heap *heap);
@@ -8700,7 +9022,7 @@ DUK_INTERNAL_DECL duk_bool_t duk_debug_is_attached(duk_heap *heap);
DUK_INTERNAL_DECL duk_bool_t duk_debug_is_paused(duk_heap *heap);
DUK_INTERNAL_DECL void duk_debug_set_paused(duk_heap *heap);
DUK_INTERNAL_DECL void duk_debug_clear_paused(duk_heap *heap);
-DUK_INTERNAL_DECL void duk_debug_clear_step_state(duk_heap *heap);
+DUK_INTERNAL_DECL void duk_debug_clear_pause_state(duk_heap *heap);
#endif /* DUK_USE_DEBUGGER_SUPPORT */
#endif /* DUK_DEBUGGER_H_INCLUDED */
@@ -9063,6 +9385,10 @@ DUK_INTERNAL_DECL duk_bool_t duk_fb_is_full(duk_fixedbuffer *fb);
#define DUK_ERROR_INTERNAL(thr) do { \
duk_err_error_internal((thr), DUK_FILE_MACRO, (duk_int_t) DUK_LINE_MACRO); \
} while (0)
+#define DUK_DCERROR_INTERNAL(thr) do { \
+ DUK_ERROR_INTERNAL((thr)); \
+ return 0; \
+ } while (0)
#define DUK_ERROR_ALLOC_FAILED(thr) do { \
duk_err_error_alloc_failed((thr), DUK_FILE_MACRO, (duk_int_t) DUK_LINE_MACRO); \
} while (0)
@@ -9088,6 +9414,10 @@ DUK_INTERNAL_DECL duk_bool_t duk_fb_is_full(duk_fixedbuffer *fb);
#define DUK_ERROR_RANGE_INVALID_COUNT(thr) do { \
DUK_ERROR_RANGE((thr), DUK_STR_INVALID_COUNT); \
} while (0)
+#define DUK_DCERROR_RANGE_INVALID_COUNT(thr) do { \
+ DUK_ERROR_RANGE_INVALID_COUNT((thr)); \
+ return 0; \
+ } while (0)
#define DUK_ERROR_RANGE_INVALID_LENGTH(thr) do { \
DUK_ERROR_RANGE((thr), DUK_STR_INVALID_LENGTH); \
} while (0)
@@ -9143,6 +9473,10 @@ DUK_INTERNAL_DECL duk_bool_t duk_fb_is_full(duk_fixedbuffer *fb);
#define DUK_ERROR_INTERNAL(thr) do { \
duk_err_error((thr)); \
} while (0)
+#define DUK_DCERROR_INTERNAL(thr) do { \
+ DUK_UNREF((thr)); \
+ return DUK_RET_ERROR; \
+ } while (0)
#define DUK_ERROR_ALLOC_FAILED(thr) do { \
duk_err_error((thr)); \
} while (0)
@@ -9168,6 +9502,10 @@ DUK_INTERNAL_DECL duk_bool_t duk_fb_is_full(duk_fixedbuffer *fb);
#define DUK_ERROR_RANGE_INVALID_COUNT(thr) do { \
duk_err_range((thr)); \
} while (0)
+#define DUK_DCERROR_RANGE_INVALID_COUNT(thr) do { \
+ DUK_UNREF((thr)); \
+ return DUK_RET_RANGE_ERROR; \
+ } while (0)
#define DUK_ERROR_RANGE_INVALID_LENGTH(thr) do { \
duk_err_range((thr)); \
} while (0)
@@ -9293,6 +9631,19 @@ DUK_INTERNAL_DECL duk_bool_t duk_fb_is_full(duk_fixedbuffer *fb);
DUK_ASSERT(thr->valstack_top < thr->valstack_end)
/*
+ * Helper to initialize a memory area (e.g. struct) with garbage when
+ * assertions enabled.
+ */
+
+#if defined(DUK_USE_ASSERTIONS)
+#define DUK_ASSERT_SET_GARBAGE(ptr,size) do { \
+ DUK_MEMSET((void *) (ptr), 0x5a, size); \
+ } while (0)
+#else
+#define DUK_ASSERT_SET_GARBAGE(ptr,size) do {} while (0)
+#endif
+
+/*
* Helper for valstack space
*
* Caller of DUK_ASSERT_VALSTACK_SPACE() estimates the number of free stack entries
@@ -9331,8 +9682,11 @@ DUK_NORETURN(DUK_INTERNAL_DECL void duk_err_create_and_throw(duk_hthread *thr, d
DUK_NORETURN(DUK_INTERNAL_DECL void duk_error_throw_from_negative_rc(duk_hthread *thr, duk_ret_t rc));
+#define DUK_AUGMENT_FLAG_NOBLAME_FILELINE (1U << 0) /* if set, don't blame C file/line for .fileName and .lineNumber */
+#define DUK_AUGMENT_FLAG_SKIP_ONE (1U << 1) /* if set, skip topmost activation in traceback construction */
+
#if defined(DUK_USE_AUGMENT_ERROR_CREATE)
-DUK_INTERNAL_DECL void duk_err_augment_error_create(duk_hthread *thr, duk_hthread *thr_callstack, const char *filename, duk_int_t line, duk_bool_t noblame_fileline);
+DUK_INTERNAL_DECL void duk_err_augment_error_create(duk_hthread *thr, duk_hthread *thr_callstack, const char *filename, duk_int_t line, duk_small_uint_t flags);
#endif
#if defined(DUK_USE_AUGMENT_ERROR_THROW)
DUK_INTERNAL_DECL void duk_err_augment_error_throw(duk_hthread *thr);
@@ -9613,6 +9967,17 @@ extern const duk_uint8_t duk_unicode_caseconv_lc[680];
extern const duk_uint16_t duk_unicode_re_canon_lookup[65536];
#endif
+#if defined(DUK_USE_REGEXP_CANON_BITMAP)
+/*
+ * Automatically generated by extract_caseconv.py, do not edit!
+ */
+
+#define DUK_CANON_BITMAP_BLKSIZE 32
+#define DUK_CANON_BITMAP_BLKSHIFT 5
+#define DUK_CANON_BITMAP_BLKMASK 31
+extern const duk_uint8_t duk_unicode_re_canon_bitmap[256];
+#endif
+
/*
* Extern
*/
@@ -9663,10 +10028,10 @@ DUK_INTERNAL_DECL duk_small_int_t duk_unicode_re_is_wordchar(duk_codepoint_t cp)
#define DUK_JSON_H_INCLUDED
/* 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 */
-#define DUK_JSON_FLAG_EXT_CUSTOM (1 << 2) /* extended types: custom encoding */
-#define DUK_JSON_FLAG_EXT_COMPATIBLE (1 << 3) /* extended types: compatible encoding */
+#define DUK_JSON_FLAG_ASCII_ONLY (1U << 0) /* escape any non-ASCII characters */
+#define DUK_JSON_FLAG_AVOID_KEY_QUOTES (1U << 1) /* avoid key quotes when key is an ASCII Identifier */
+#define DUK_JSON_FLAG_EXT_CUSTOM (1U << 2) /* extended types: custom encoding */
+#define DUK_JSON_FLAG_EXT_COMPATIBLE (1U << 3) /* extended types: compatible encoding */
/* How much stack to require on entry to object/array encode */
#define DUK_JSON_ENC_REQSTACK 32
@@ -9693,8 +10058,8 @@ typedef struct {
duk_small_uint_t flag_ext_compatible;
duk_small_uint_t flag_ext_custom_or_compatible;
#endif
- duk_int_t recursion_depth;
- duk_int_t recursion_limit;
+ duk_uint_t recursion_depth;
+ duk_uint_t recursion_limit;
duk_uint_t mask_for_undefined; /* type bit mask: types which certainly produce 'undefined' */
#if defined(DUK_USE_JX) || defined(DUK_USE_JC)
duk_small_uint_t stridx_custom_undefined;
@@ -9731,20 +10096,22 @@ typedef struct {
#if !defined(DUK_JS_H_INCLUDED)
#define DUK_JS_H_INCLUDED
-/* Flags for call handling. */
-#define DUK_CALL_FLAG_IGNORE_RECLIMIT (1 << 0) /* duk_handle_call_xxx: call ignores C recursion limit (for errhandler calls) */
-#define DUK_CALL_FLAG_CONSTRUCTOR_CALL (1 << 1) /* duk_handle_call_xxx: constructor call (i.e. called as 'new Foo()') */
-#define DUK_CALL_FLAG_IS_RESUME (1 << 2) /* duk_handle_ecma_call_setup: setup for a resume() */
-#define DUK_CALL_FLAG_IS_TAILCALL (1 << 3) /* duk_handle_ecma_call_setup: setup for a tail call */
-#define DUK_CALL_FLAG_DIRECT_EVAL (1 << 4) /* call is a direct eval call */
+/* Flags for call handling. Lowest flags must match bytecode DUK_BC_CALL_FLAG_xxx 1:1. */
+#define DUK_CALL_FLAG_TAILCALL (1U << 0) /* setup for a tail call */
+#define DUK_CALL_FLAG_CONSTRUCT (1U << 1) /* constructor call (i.e. called as 'new Foo()') */
+#define DUK_CALL_FLAG_CALLED_AS_EVAL (1U << 2) /* call was made using the identifier 'eval' */
+#define DUK_CALL_FLAG_ALLOW_ECMATOECMA (1U << 3) /* ecma-to-ecma call with executor reuse is possible */
+#define DUK_CALL_FLAG_DIRECT_EVAL (1U << 4) /* call is a direct eval call */
+#define DUK_CALL_FLAG_CONSTRUCT_PROXY (1U << 5) /* handled via 'construct' proxy trap, check return value invariant(s) */
+#define DUK_CALL_FLAG_DEFAULT_INSTANCE_UPDATED (1U << 6) /* prototype of 'default instance' updated, temporary flag in call handling */
/* Flags for duk_js_equals_helper(). */
-#define DUK_EQUALS_FLAG_SAMEVALUE (1 << 0) /* use SameValue instead of non-strict equality */
-#define DUK_EQUALS_FLAG_STRICT (1 << 1) /* use strict equality instead of non-strict equality */
+#define DUK_EQUALS_FLAG_SAMEVALUE (1U << 0) /* use SameValue instead of non-strict equality */
+#define DUK_EQUALS_FLAG_STRICT (1U << 1) /* use strict equality instead of non-strict equality */
/* Flags for duk_js_compare_helper(). */
-#define DUK_COMPARE_FLAG_NEGATE (1 << 0) /* negate result */
-#define DUK_COMPARE_FLAG_EVAL_LEFT_FIRST (1 << 1) /* eval left argument first */
+#define DUK_COMPARE_FLAG_NEGATE (1U << 0) /* negate result */
+#define DUK_COMPARE_FLAG_EVAL_LEFT_FIRST (1U << 1) /* eval left argument first */
/* conversions, coercions, comparison, etc */
DUK_INTERNAL_DECL duk_bool_t duk_js_toboolean(duk_tval *tv);
@@ -9759,13 +10126,13 @@ DUK_INTERNAL_DECL duk_uarridx_t duk_js_to_arrayindex_string(const duk_uint8_t *s
DUK_INTERNAL_DECL duk_uarridx_t duk_js_to_arrayindex_hstring_fast_known(duk_hstring *h);
DUK_INTERNAL_DECL duk_uarridx_t duk_js_to_arrayindex_hstring_fast(duk_hstring *h);
#endif
-DUK_INTERNAL_DECL duk_bool_t duk_js_equals_helper(duk_hthread *thr, duk_tval *tv_x, duk_tval *tv_y, duk_small_int_t flags);
+DUK_INTERNAL_DECL duk_bool_t duk_js_equals_helper(duk_hthread *thr, duk_tval *tv_x, duk_tval *tv_y, duk_small_uint_t flags);
DUK_INTERNAL_DECL duk_small_int_t duk_js_data_compare(const duk_uint8_t *buf1, const duk_uint8_t *buf2, duk_size_t len1, duk_size_t len2);
DUK_INTERNAL_DECL duk_small_int_t duk_js_string_compare(duk_hstring *h1, duk_hstring *h2);
#if 0 /* unused */
DUK_INTERNAL_DECL duk_small_int_t duk_js_buffer_compare(duk_heap *heap, duk_hbuffer *h1, duk_hbuffer *h2);
#endif
-DUK_INTERNAL_DECL duk_bool_t duk_js_compare_helper(duk_hthread *thr, duk_tval *tv_x, duk_tval *tv_y, duk_small_int_t flags);
+DUK_INTERNAL_DECL duk_bool_t duk_js_compare_helper(duk_hthread *thr, duk_tval *tv_x, duk_tval *tv_y, duk_small_uint_t flags);
DUK_INTERNAL_DECL duk_bool_t duk_js_instanceof(duk_hthread *thr, duk_tval *tv_x, duk_tval *tv_y);
DUK_INTERNAL_DECL duk_bool_t duk_js_in(duk_hthread *thr, duk_tval *tv_x, duk_tval *tv_y);
DUK_INTERNAL_DECL duk_small_uint_t duk_js_typeof_stridx(duk_tval *tv_x);
@@ -9809,22 +10176,24 @@ DUK_INTERNAL_DECL void duk_js_putvar_activation(duk_hthread *thr, duk_activation
DUK_INTERNAL_DECL duk_bool_t duk_js_delvar_envrec(duk_hthread *thr, duk_hobject *env, duk_hstring *name);
#endif
DUK_INTERNAL_DECL duk_bool_t duk_js_delvar_activation(duk_hthread *thr, duk_activation *act, duk_hstring *name);
-DUK_INTERNAL_DECL duk_bool_t duk_js_declvar_activation(duk_hthread *thr, duk_activation *act, duk_hstring *name, duk_tval *val, duk_small_int_t prop_flags, duk_bool_t is_func_decl);
+DUK_INTERNAL_DECL duk_bool_t duk_js_declvar_activation(duk_hthread *thr, duk_activation *act, duk_hstring *name, duk_tval *val, duk_small_uint_t prop_flags, duk_bool_t is_func_decl);
DUK_INTERNAL_DECL void duk_js_init_activation_environment_records_delayed(duk_hthread *thr, duk_activation *act);
DUK_INTERNAL_DECL void duk_js_close_environment_record(duk_hthread *thr, duk_hobject *env);
-DUK_INTERNAL_DECL duk_hobject *duk_create_activation_environment_record(duk_hthread *thr, duk_hobject *func, duk_size_t idx_bottom);
-DUK_INTERNAL_DECL
-void duk_js_push_closure(duk_hthread *thr,
- duk_hcompfunc *fun_temp,
- duk_hobject *outer_var_env,
- duk_hobject *outer_lex_env,
- duk_bool_t add_auto_proto);
+DUK_INTERNAL_DECL duk_hobject *duk_create_activation_environment_record(duk_hthread *thr, duk_hobject *func, duk_size_t bottom_byteoff);
+DUK_INTERNAL_DECL void duk_js_push_closure(duk_hthread *thr,
+ duk_hcompfunc *fun_temp,
+ duk_hobject *outer_var_env,
+ duk_hobject *outer_lex_env,
+ duk_bool_t add_auto_proto);
/* call handling */
-DUK_INTERNAL_DECL duk_int_t duk_handle_call_protected(duk_hthread *thr, duk_idx_t num_stack_args, duk_small_uint_t call_flags);
-DUK_INTERNAL_DECL void duk_handle_call_unprotected(duk_hthread *thr, duk_idx_t num_stack_args, duk_small_uint_t call_flags);
+DUK_INTERNAL_DECL duk_int_t duk_handle_call_unprotected(duk_hthread *thr, duk_idx_t idx_func, duk_small_uint_t call_flags);
+DUK_INTERNAL_DECL duk_int_t duk_handle_call_unprotected_nargs(duk_hthread *thr, duk_idx_t nargs, duk_small_uint_t call_flags);
DUK_INTERNAL_DECL duk_int_t duk_handle_safe_call(duk_hthread *thr, duk_safe_call_function func, void *udata, duk_idx_t num_stack_args, duk_idx_t num_stack_res);
-DUK_INTERNAL_DECL duk_bool_t duk_handle_ecma_call_setup(duk_hthread *thr, duk_idx_t num_stack_args, duk_small_uint_t call_flags);
+DUK_INTERNAL_DECL void duk_call_construct_postprocess(duk_hthread *thr, duk_small_uint_t proxy_invariant);
+#if defined(DUK_USE_VERBOSE_ERRORS)
+DUK_INTERNAL_DECL void duk_call_setup_propcall_error(duk_hthread *thr, duk_tval *tv_targ, duk_tval *tv_base, duk_tval *tv_key);
+#endif
/* bytecode execution */
DUK_INTERNAL_DECL void duk_js_execute_bytecode(duk_hthread *exec_thr);
@@ -9842,23 +10211,23 @@ DUK_INTERNAL_DECL void duk_js_execute_bytecode(duk_hthread *exec_thr);
/* Output a specified number of digits instead of using the shortest
* form. Used for toPrecision() and toFixed().
*/
-#define DUK_N2S_FLAG_FIXED_FORMAT (1 << 0)
+#define DUK_N2S_FLAG_FIXED_FORMAT (1U << 0)
/* Force exponential format. Used for toExponential(). */
-#define DUK_N2S_FLAG_FORCE_EXP (1 << 1)
+#define DUK_N2S_FLAG_FORCE_EXP (1U << 1)
/* If number would need zero padding (for whole number part), use
* exponential format instead. E.g. if input number is 12300, 3
* digits are generated ("123"), output "1.23e+4" instead of "12300".
* Used for toPrecision().
*/
-#define DUK_N2S_FLAG_NO_ZERO_PAD (1 << 2)
+#define DUK_N2S_FLAG_NO_ZERO_PAD (1U << 2)
/* Digit count indicates number of fractions (i.e. an absolute
* digit index instead of a relative one). Used together with
* DUK_N2S_FLAG_FIXED_FORMAT for toFixed().
*/
-#define DUK_N2S_FLAG_FRACTION_DIGITS (1 << 3)
+#define DUK_N2S_FLAG_FRACTION_DIGITS (1U << 3)
/*
* String-to-number conversion
@@ -9871,64 +10240,64 @@ DUK_INTERNAL_DECL void duk_js_execute_bytecode(duk_hthread *exec_thr);
#define DUK_S2N_MAX_EXPONENT 1000000000
/* Trim white space (= allow leading and trailing whitespace) */
-#define DUK_S2N_FLAG_TRIM_WHITE (1 << 0)
+#define DUK_S2N_FLAG_TRIM_WHITE (1U << 0)
/* Allow exponent */
-#define DUK_S2N_FLAG_ALLOW_EXP (1 << 1)
+#define DUK_S2N_FLAG_ALLOW_EXP (1U << 1)
/* Allow trailing garbage (e.g. treat "123foo" as "123) */
-#define DUK_S2N_FLAG_ALLOW_GARBAGE (1 << 2)
+#define DUK_S2N_FLAG_ALLOW_GARBAGE (1U << 2)
/* Allow leading plus sign */
-#define DUK_S2N_FLAG_ALLOW_PLUS (1 << 3)
+#define DUK_S2N_FLAG_ALLOW_PLUS (1U << 3)
/* Allow leading minus sign */
-#define DUK_S2N_FLAG_ALLOW_MINUS (1 << 4)
+#define DUK_S2N_FLAG_ALLOW_MINUS (1U << 4)
/* Allow 'Infinity' */
-#define DUK_S2N_FLAG_ALLOW_INF (1 << 5)
+#define DUK_S2N_FLAG_ALLOW_INF (1U << 5)
/* Allow fraction part */
-#define DUK_S2N_FLAG_ALLOW_FRAC (1 << 6)
+#define DUK_S2N_FLAG_ALLOW_FRAC (1U << 6)
/* Allow naked fraction (e.g. ".123") */
-#define DUK_S2N_FLAG_ALLOW_NAKED_FRAC (1 << 7)
+#define DUK_S2N_FLAG_ALLOW_NAKED_FRAC (1U << 7)
/* Allow empty fraction (e.g. "123.") */
-#define DUK_S2N_FLAG_ALLOW_EMPTY_FRAC (1 << 8)
+#define DUK_S2N_FLAG_ALLOW_EMPTY_FRAC (1U << 8)
/* Allow empty string to be interpreted as 0 */
-#define DUK_S2N_FLAG_ALLOW_EMPTY_AS_ZERO (1 << 9)
+#define DUK_S2N_FLAG_ALLOW_EMPTY_AS_ZERO (1U << 9)
/* Allow leading zeroes (e.g. "0123" -> "123") */
-#define DUK_S2N_FLAG_ALLOW_LEADING_ZERO (1 << 10)
+#define DUK_S2N_FLAG_ALLOW_LEADING_ZERO (1U << 10)
/* Allow automatic detection of hex base ("0x" or "0X" prefix),
* overrides radix argument and forces integer mode.
*/
-#define DUK_S2N_FLAG_ALLOW_AUTO_HEX_INT (1 << 11)
+#define DUK_S2N_FLAG_ALLOW_AUTO_HEX_INT (1U << 11)
/* Allow automatic detection of legacy octal base ("0n"),
* overrides radix argument and forces integer mode.
*/
-#define DUK_S2N_FLAG_ALLOW_AUTO_LEGACY_OCT_INT (1 << 12)
+#define DUK_S2N_FLAG_ALLOW_AUTO_LEGACY_OCT_INT (1U << 12)
/* Allow automatic detection of ES2015 octal base ("0o123"),
* overrides radix argument and forces integer mode.
*/
-#define DUK_S2N_FLAG_ALLOW_AUTO_OCT_INT (1 << 13)
+#define DUK_S2N_FLAG_ALLOW_AUTO_OCT_INT (1U << 13)
/* Allow automatic detection of ES2015 binary base ("0b10001"),
* overrides radix argument and forces integer mode.
*/
-#define DUK_S2N_FLAG_ALLOW_AUTO_BIN_INT (1 << 14)
+#define DUK_S2N_FLAG_ALLOW_AUTO_BIN_INT (1U << 14)
/*
* Prototypes
*/
-DUK_INTERNAL_DECL void duk_numconv_stringify(duk_context *ctx, duk_small_int_t radix, duk_small_int_t digits, duk_small_uint_t flags);
-DUK_INTERNAL_DECL void duk_numconv_parse(duk_context *ctx, duk_small_int_t radix, duk_small_uint_t flags);
+DUK_INTERNAL_DECL void duk_numconv_stringify(duk_hthread *thr, duk_small_int_t radix, duk_small_int_t digits, duk_small_uint_t flags);
+DUK_INTERNAL_DECL void duk_numconv_parse(duk_hthread *thr, duk_small_int_t radix, duk_small_uint_t flags);
#endif /* DUK_NUMCONV_H_INCLUDED */
/* #include duk_bi_protos.h */
@@ -9957,13 +10326,16 @@ DUK_INTERNAL_DECL duk_bool_t duk_bi_date_year_in_valid_range(duk_double_t year);
DUK_INTERNAL_DECL duk_bool_t duk_bi_date_timeval_in_leeway_range(duk_double_t x);
/* Built-in providers */
#if defined(DUK_USE_DATE_NOW_GETTIMEOFDAY)
-DUK_INTERNAL_DECL duk_double_t duk_bi_date_get_now_gettimeofday(duk_context *ctx);
+DUK_INTERNAL_DECL duk_double_t duk_bi_date_get_now_gettimeofday(void);
#endif
#if defined(DUK_USE_DATE_NOW_TIME)
-DUK_INTERNAL_DECL duk_double_t duk_bi_date_get_now_time(duk_context *ctx);
+DUK_INTERNAL_DECL duk_double_t duk_bi_date_get_now_time(void);
#endif
#if defined(DUK_USE_DATE_NOW_WINDOWS)
-DUK_INTERNAL_DECL duk_double_t duk_bi_date_get_now_windows(duk_context *ctx);
+DUK_INTERNAL_DECL duk_double_t duk_bi_date_get_now_windows(void);
+#endif
+#if defined(DUK_USE_DATE_NOW_WINDOWS_SUBMS)
+DUK_INTERNAL_DECL duk_double_t duk_bi_date_get_now_windows_subms(void);
#endif
#if defined(DUK_USE_DATE_TZO_GMTIME_R) || defined(DUK_USE_DATE_TZO_GMTIME_S) || defined(DUK_USE_DATE_TZO_GMTIME)
DUK_INTERNAL_DECL duk_int_t duk_bi_date_get_local_tzoffset_gmtime(duk_double_t d);
@@ -9975,31 +10347,38 @@ DUK_INTERNAL_DECL duk_int_t duk_bi_date_get_local_tzoffset_windows(duk_double_t
DUK_INTERNAL_DECL duk_int_t duk_bi_date_get_local_tzoffset_windows_no_dst(duk_double_t d);
#endif
#if defined(DUK_USE_DATE_PRS_STRPTIME)
-DUK_INTERNAL_DECL duk_bool_t duk_bi_date_parse_string_strptime(duk_context *ctx, const char *str);
+DUK_INTERNAL_DECL duk_bool_t duk_bi_date_parse_string_strptime(duk_hthread *thr, const char *str);
#endif
#if defined(DUK_USE_DATE_PRS_GETDATE)
-DUK_INTERNAL_DECL duk_bool_t duk_bi_date_parse_string_getdate(duk_context *ctx, const char *str);
+DUK_INTERNAL_DECL duk_bool_t duk_bi_date_parse_string_getdate(duk_hthread *thr, const char *str);
#endif
#if defined(DUK_USE_DATE_FMT_STRFTIME)
-DUK_INTERNAL_DECL duk_bool_t duk_bi_date_format_parts_strftime(duk_context *ctx, duk_int_t *parts, duk_int_t tzoffset, duk_small_uint_t flags);
+DUK_INTERNAL_DECL duk_bool_t duk_bi_date_format_parts_strftime(duk_hthread *thr, duk_int_t *parts, duk_int_t tzoffset, duk_small_uint_t flags);
+#endif
+
+#if defined(DUK_USE_GET_MONOTONIC_TIME_CLOCK_GETTIME)
+DUK_INTERNAL_DECL duk_double_t duk_bi_date_get_monotonic_time_clock_gettime(void);
+#endif
+#if defined(DUK_USE_GET_MONOTONIC_TIME_WINDOWS_QPC)
+DUK_INTERNAL_DECL duk_double_t duk_bi_date_get_monotonic_time_windows_qpc(void);
#endif
DUK_INTERNAL_DECL
-void duk_bi_json_parse_helper(duk_context *ctx,
+void duk_bi_json_parse_helper(duk_hthread *thr,
duk_idx_t idx_value,
duk_idx_t idx_reviver,
duk_small_uint_t flags);
DUK_INTERNAL_DECL
-void duk_bi_json_stringify_helper(duk_context *ctx,
+void duk_bi_json_stringify_helper(duk_hthread *thr,
duk_idx_t idx_value,
duk_idx_t idx_replacer,
duk_idx_t idx_space,
duk_small_uint_t flags);
-DUK_INTERNAL_DECL duk_ret_t duk_textdecoder_decode_utf8_nodejs(duk_context *ctx);
+DUK_INTERNAL_DECL duk_ret_t duk_textdecoder_decode_utf8_nodejs(duk_hthread *thr);
#if defined(DUK_USE_ES6_PROXY)
-DUK_INTERNAL_DECL void duk_proxy_ownkeys_postprocess(duk_context *ctx, duk_hobject *h_proxy_target, duk_uint_t flags);
+DUK_INTERNAL_DECL void duk_proxy_ownkeys_postprocess(duk_hthread *thr, duk_hobject *h_proxy_target, duk_uint_t flags);
#endif
#endif /* DUK_BUILTIN_PROTOS_H_INCLUDED */
@@ -10200,7 +10579,7 @@ DUK_INTERNAL void duk_debug_log(const char *fmt, ...) {
#if defined(DUK_USE_ROM_STRINGS)
#error ROM support not enabled, rerun configure.py with --rom-support
#else /* DUK_USE_ROM_STRINGS */
-DUK_INTERNAL const duk_uint8_t duk_strings_data[903] = {
+DUK_INTERNAL const duk_uint8_t duk_strings_data[892] = {
79,40,209,144,168,105,6,78,54,139,89,185,44,48,46,90,120,8,154,140,35,103,
35,113,193,73,5,52,112,180,104,166,135,52,188,4,98,12,27,146,156,80,211,31,
129,115,150,64,52,220,109,24,18,68,156,24,38,67,114,36,55,9,119,151,132,
@@ -10221,38 +10600,37 @@ DUK_INTERNAL const duk_uint8_t duk_strings_data[903] = {
67,72,49,241,160,227,81,196,52,168,106,39,132,252,183,136,105,80,212,79,2,
249,110,128,126,88,95,133,109,237,237,237,151,235,127,46,249,119,203,190,
186,206,33,181,2,208,61,190,12,19,34,65,19,81,132,108,228,97,1,107,33,12,
-32,45,100,139,134,69,146,100,227,226,231,146,51,192,204,73,140,224,145,221,
-102,241,68,196,157,34,79,143,139,166,233,225,228,227,138,157,173,167,197,
-211,118,214,210,38,238,74,113,67,76,105,187,169,147,154,73,225,228,32,193,
-48,25,100,105,166,113,200,147,44,166,1,40,79,18,150,134,147,141,163,2,72,
-171,115,147,136,4,65,130,96,35,64,194,32,168,89,56,208,48,135,123,144,217,
-146,38,220,229,64,186,16,187,156,105,47,52,238,112,56,153,4,225,145,27,156,
-43,162,192,46,71,220,229,65,22,1,231,220,228,157,72,136,136,220,227,197,
-164,180,52,133,220,228,206,137,23,115,128,137,164,77,206,48,15,62,231,42,8,
-145,181,86,231,10,134,129,104,201,34,125,206,76,17,49,38,141,206,28,13,26,
-201,19,137,204,122,22,66,161,175,164,210,72,199,130,137,1,50,32,145,143,38,
-120,186,195,35,106,51,146,230,8,36,77,109,65,38,226,72,141,18,74,140,35,
-247,247,182,168,209,144,187,223,58,156,104,79,190,183,127,123,105,160,110,
-247,206,167,26,19,239,173,223,222,218,67,75,189,243,169,198,132,251,235,
-183,247,182,154,134,151,123,231,83,141,9,247,215,111,239,109,22,141,22,247,
-206,167,26,19,239,172,223,218,45,26,47,157,78,52,39,223,74,24,144,10,32,
-129,34,20,64,152,142,129,57,179,67,104,68,12,129,161,140,72,156,100,40,40,
-185,152,100,89,38,65,13,196,34,228,67,149,13,2,215,129,149,209,65,104,209,
-77,14,104,144,81,33,170,67,101,48,52,68,113,70,210,88,209,36,233,22,154,86,
-68,196,114,76,232,145,102,120,186,195,156,112,105,225,228,113,71,80,68,162,
-115,101,50,85,200,25,108,116,44,132,178,38,114,137,96,148,136,70,209,134,
-37,222,232,204,228,188,200,209,200,200,99,221,25,150,84,121,34,70,209,107,
-36,227,66,20,160,92,136,164,49,235,35,8,217,201,40,108,201,18,128,68,26,
-201,51,188,2,80,12,67,190,40,168,38,68,190,46,153,5,50,12,207,160,86,129,
-26,83,4,208,34,225,4,88,192,
+32,45,100,137,64,247,175,9,19,155,41,198,130,155,134,69,146,100,227,226,
+231,146,51,192,204,73,140,224,145,221,102,241,68,196,157,34,79,143,139,166,
+233,225,228,227,138,157,173,167,197,211,118,214,210,38,238,74,113,67,76,
+105,187,169,147,154,73,225,228,32,193,48,25,100,105,166,113,200,147,44,166,
+1,40,79,18,150,134,147,141,163,2,72,171,115,147,136,4,65,130,96,35,64,194,
+32,168,89,56,208,48,135,123,144,217,146,39,220,228,193,19,18,101,220,227,
+73,121,167,115,129,196,200,39,12,136,220,225,93,22,1,114,62,231,42,8,176,
+15,62,231,36,234,68,68,70,231,30,45,37,161,164,38,231,24,7,159,115,149,4,
+72,218,171,115,133,67,64,180,100,145,54,231,42,5,208,135,19,152,244,44,133,
+67,95,73,164,145,143,5,18,2,100,65,35,30,76,241,117,134,70,212,103,37,204,
+16,72,154,218,130,77,196,145,63,127,123,106,141,25,11,189,243,169,198,132,
+251,235,119,247,182,154,6,239,124,234,113,161,62,250,221,253,237,164,52,
+187,223,58,156,104,79,190,187,127,123,105,168,105,119,190,117,56,208,159,
+125,118,254,246,209,104,209,111,124,234,113,161,62,250,205,253,162,209,162,
+249,212,227,66,125,244,161,137,0,162,8,18,33,68,9,136,232,19,155,52,54,132,
+64,200,26,24,196,137,198,66,130,139,153,134,69,146,100,16,220,66,46,68,57,
+80,208,45,120,25,93,20,22,141,20,208,230,137,5,18,26,164,54,83,3,68,71,20,
+109,37,141,18,78,145,105,165,100,76,71,36,206,137,22,103,139,172,57,199,6,
+158,30,71,20,117,4,74,39,54,83,37,92,129,150,199,66,200,75,34,103,40,150,9,
+72,132,109,24,98,93,238,140,206,75,204,141,28,140,134,61,209,153,101,71,
+146,36,109,22,178,78,52,33,74,5,200,138,67,30,178,48,141,156,146,134,204,
+145,40,4,65,172,147,59,192,37,0,196,59,226,138,130,100,75,226,233,144,83,
+32,204,250,5,104,17,165,48,77,2,46,16,69,140,
};
#endif /* DUK_USE_ROM_STRINGS */
#if defined(DUK_USE_ROM_OBJECTS)
#error ROM support not enabled, rerun configure.py with --rom-support
#else /* DUK_USE_ROM_OBJECTS */
-/* native functions: 166 */
-DUK_INTERNAL const duk_c_function duk_bi_native_functions[166] = {
+/* native functions: 176 */
+DUK_INTERNAL const duk_c_function duk_bi_native_functions[176] = {
NULL,
duk_bi_array_constructor,
duk_bi_array_constructor_is_array,
@@ -10324,12 +10702,17 @@ DUK_INTERNAL const duk_c_function duk_bi_native_functions[166] = {
duk_bi_global_object_unescape,
duk_bi_json_object_parse,
duk_bi_json_object_stringify,
+ duk_bi_math_object_clz32,
duk_bi_math_object_hypot,
+ duk_bi_math_object_imul,
duk_bi_math_object_max,
duk_bi_math_object_min,
duk_bi_math_object_onearg_shared,
duk_bi_math_object_random,
+ duk_bi_math_object_sign,
duk_bi_math_object_twoarg_shared,
+ duk_bi_native_function_length,
+ duk_bi_native_function_name,
duk_bi_nodejs_buffer_byte_length,
duk_bi_nodejs_buffer_concat,
duk_bi_nodejs_buffer_constructor,
@@ -10360,16 +10743,21 @@ DUK_INTERNAL const duk_c_function duk_bi_native_functions[166] = {
duk_bi_object_constructor_prevent_extensions,
duk_bi_object_constructor_seal_freeze_shared,
duk_bi_object_getprototype_shared,
+ duk_bi_object_prototype_defineaccessor,
duk_bi_object_prototype_has_own_property,
duk_bi_object_prototype_is_prototype_of,
+ duk_bi_object_prototype_lookupaccessor,
duk_bi_object_prototype_property_is_enumerable,
duk_bi_object_prototype_to_locale_string,
duk_bi_object_prototype_to_string,
duk_bi_object_prototype_value_of,
duk_bi_object_setprototype_shared,
+ duk_bi_performance_now,
duk_bi_pointer_constructor,
duk_bi_pointer_prototype_tostring_shared,
duk_bi_proxy_constructor,
+ duk_bi_reflect_apply,
+ duk_bi_reflect_construct,
duk_bi_reflect_object_delete_property,
duk_bi_reflect_object_get,
duk_bi_reflect_object_has,
@@ -10421,541 +10809,556 @@ DUK_INTERNAL const duk_c_function duk_bi_native_functions[166] = {
duk_bi_uint8array_plainof,
};
#if defined(DUK_USE_DOUBLE_LE)
-DUK_INTERNAL const duk_uint8_t duk_builtins_data[3819] = {
-144,148,105,221,32,68,52,228,62,12,104,200,165,134,148,248,81,77,61,191,
-135,35,154,103,34,72,6,157,159,197,145,77,245,126,52,130,106,234,163,196,
-52,226,18,51,161,26,113,1,60,37,64,190,18,49,116,116,33,26,113,1,92,136,26,
-98,112,145,139,163,165,8,211,136,14,228,72,82,68,141,17,56,72,197,209,212,
-132,105,196,5,242,88,108,193,126,18,49,116,117,161,26,113,1,60,158,30,78,
-18,49,116,118,33,26,113,1,29,164,80,78,198,46,142,212,36,68,51,71,232,59,
-147,60,93,110,79,15,39,9,24,186,33,13,63,111,185,16,211,206,251,114,98,17,
-171,160,11,199,197,215,196,66,26,102,38,68,53,212,77,136,104,255,5,114,120,
-121,7,192,70,32,192,67,95,249,59,13,13,127,228,248,134,191,242,133,208,215,
-254,81,204,67,95,249,75,33,13,127,229,61,84,53,255,149,52,80,215,254,85,
-217,67,95,249,91,121,13,90,181,168,134,143,152,95,38,75,207,132,104,156,50,
-70,33,163,225,66,249,50,94,124,25,4,225,146,49,14,24,28,196,0,0,0,0,0,0,15,
-135,252,204,0,0,0,0,0,0,15,7,252,188,72,6,176,77,225,28,24,103,14,33,197,
-138,113,227,28,152,231,46,65,205,19,194,84,11,225,35,23,68,231,138,228,64,
-211,19,132,140,93,19,162,59,145,33,73,18,52,68,225,35,23,68,233,139,228,
-176,217,130,252,36,98,232,157,81,60,158,30,78,18,49,116,78,184,142,210,40,
-39,99,23,68,236,201,59,114,142,224,126,14,138,152,30,67,188,23,143,139,175,
-131,194,135,228,72,85,144,83,60,53,163,208,76,60,68,211,197,78,60,116,243,
-200,80,60,149,19,202,82,60,181,51,204,84,60,213,83,206,86,60,240,190,76,
-151,159,8,209,56,100,137,232,133,242,100,188,248,50,9,195,36,79,73,26,238,
-108,129,15,4,100,78,33,179,207,160,41,224,140,137,194,173,192,158,120,128,
-168,151,26,14,55,58,64,132,75,133,67,81,50,103,8,18,50,9,195,39,105,20,101,
-136,36,50,9,195,39,105,20,11,174,99,220,210,54,121,114,4,145,162,112,201,
-218,69,25,130,9,17,162,112,201,218,69,2,235,152,247,52,141,158,100,128,196,
-144,128,242,102,136,17,70,146,66,3,201,160,32,0,130,225,48,113,137,62,62,
-46,155,167,135,147,142,47,24,147,79,205,68,48,98,79,142,179,120,248,185,
-228,140,241,193,146,66,138,31,55,71,126,129,51,18,124,117,155,199,197,207,
-36,103,142,52,12,36,184,100,129,129,41,32,205,221,175,3,10,36,4,201,188,64,
-112,200,84,52,156,124,92,242,70,120,223,48,64,100,42,26,78,62,46,121,35,52,
-18,91,212,2,72,128,95,20,128,197,137,9,146,113,73,8,190,36,169,27,62,18,
-243,35,100,135,54,92,66,4,34,92,145,0,178,15,132,64,132,75,133,139,178,70,
-240,137,6,34,92,37,230,70,201,1,89,56,36,4,81,49,46,25,5,76,73,241,214,111,
-31,23,60,145,158,57,44,48,46,92,184,100,160,145,46,2,0,201,168,207,198,230,
-144,117,60,176,48,156,160,48,188,192,7,28,18,227,172,222,62,46,121,35,60,
-113,200,26,137,113,241,116,221,60,60,156,113,121,4,20,124,92,242,70,120,
-226,37,194,54,140,36,64,21,147,146,68,24,32,57,0,125,78,84,0,160,123,215,
-140,146,1,4,5,175,40,124,8,20,52,121,51,228,24,96,129,209,46,2,49,6,20,135,
-33,20,53,50,128,194,65,4,12,39,52,64,155,31,48,112,72,6,247,62,16,1,31,73,
-30,25,240,60,73,82,70,68,138,0,89,29,5,156,96,2,201,104,17,35,160,18,78,
-140,228,16,26,79,90,4,73,43,192,244,108,142,130,206,89,240,58,26,50,95,142,
-43,159,65,107,4,167,196,52,100,191,28,87,63,128,15,255,240,164,169,35,136,
-6,128,146,115,9,0,210,7,43,163,194,0,71,128,105,65,176,15,128,105,131,21,
-11,153,35,0,211,134,137,7,65,18,33,244,23,18,14,130,39,34,131,30,113,15,
-224,3,255,254,12,80,81,133,139,153,193,28,17,224,156,50,119,15,131,75,23,
-51,130,112,201,199,185,13,159,116,248,228,68,219,66,149,83,83,238,3,11,238,
-0,48,142,8,240,19,239,144,40,71,4,120,39,12,156,4,252,4,11,19,134,78,61,
-200,108,248,9,248,9,3,9,205,16,39,225,62,7,67,70,75,241,197,241,154,5,172,
-18,159,16,209,146,252,113,124,102,144,106,220,32,44,156,19,152,240,68,158,
-66,2,176,19,17,252,164,7,137,30,176,8,158,116,3,72,128,136,143,232,32,44,
-150,129,19,210,128,89,61,104,159,169,1,50,160,101,56,161,166,246,160,46,
-110,226,221,98,71,130,4,137,222,0,140,221,197,184,64,89,56,183,88,145,224,
-129,34,119,128,23,55,114,143,121,35,193,2,68,239,2,17,155,184,183,8,11,39,
-40,247,146,60,16,36,78,240,32,73,197,12,247,128,26,36,121,1,63,49,2,165,48,
-70,114,229,145,51,250,205,2,8,209,203,150,68,207,235,52,130,16,209,46,131,
-36,188,70,128,210,160,101,56,251,16,131,28,7,35,38,218,50,234,103,130,97,
-103,129,6,73,0,79,88,11,237,84,11,161,32,127,255,255,255,255,255,247,191,
-137,235,16,221,170,129,116,36,0,16,0,0,0,0,0,0,12,196,0,0,0,0,0,0,15,135,
-242,61,123,164,137,162,164,218,67,74,134,162,120,128,0,0,0,0,0,1,224,254,
-71,173,33,129,52,84,155,72,105,80,212,79,16,0,0,0,0,0,0,60,63,199,36,38,
-218,0,0,0,0,0,0,0,0,4,29,78,224,140,38,216,140,46,228,0,243,119,10,139,144,
-123,82,6,205,220,37,222,230,145,179,64,23,180,32,92,221,199,196,130,68,144,
-230,237,200,131,44,24,43,193,25,18,185,0,251,73,138,199,240,27,93,106,192,
-57,41,54,210,0,0,0,0,0,0,62,31,241,58,155,192,12,155,184,48,76,156,148,226,
-134,154,240,32,201,187,147,67,9,201,78,40,105,175,2,225,47,3,18,155,184,
-183,8,11,39,6,9,147,146,156,80,211,94,7,37,55,113,110,16,22,78,77,12,39,37,
-56,161,166,188,16,48,215,130,14,30,240,66,213,93,35,11,124,0,230,36,249,52,
-48,151,192,22,98,79,133,162,215,204,16,17,178,16,199,24,147,237,38,34,246,
-139,95,48,64,70,200,68,16,98,79,140,115,102,123,33,20,89,137,62,210,98,103,
-92,217,158,200,70,14,98,79,131,4,201,100,35,138,49,39,218,76,67,232,38,75,
-33,32,49,137,62,12,24,178,18,68,152,147,237,38,33,244,24,178,18,132,24,147,
-225,221,72,202,200,75,22,98,79,180,152,143,215,82,50,178,19,5,24,147,227,
-16,218,76,146,178,19,70,152,147,237,38,38,117,13,164,201,43,33,56,81,137,
-62,72,130,115,71,43,33,60,105,137,62,210,98,151,72,39,52,114,178,20,7,152,
-147,227,16,181,162,68,19,154,57,89,10,36,140,73,246,147,19,58,133,173,18,
-32,156,209,202,200,82,34,98,79,147,67,9,151,52,156,113,75,34,78,208,1,228,
-73,242,104,97,46,16,62,68,159,24,133,173,18,32,156,209,202,217,83,37,34,79,
-180,152,153,212,45,104,145,4,230,142,86,202,160,169,18,124,145,4,230,142,
-86,215,213,27,34,79,180,152,165,210,9,205,28,173,175,172,42,68,159,24,134,
-210,100,149,183,245,198,200,147,237,38,38,117,13,164,201,43,111,236,8,145,
-39,195,186,145,149,185,246,69,200,147,237,38,35,245,212,140,173,207,180,30,
-68,159,6,9,146,217,91,21,34,79,180,152,135,208,76,150,202,224,137,18,124,
-99,155,51,219,95,116,92,137,62,210,98,103,92,217,158,218,251,194,228,73,
-240,180,90,249,130,2,54,223,223,29,34,79,180,152,139,218,45,124,193,1,27,
-111,240,33,204,73,243,4,4,108,134,8,60,137,62,96,128,141,178,193,193,154,3,
-147,32,227,36,0,0,0,0,0,0,0,0,99,115,245,195,19,159,176,75,175,159,176,24,
-172,253,129,49,121,251,2,176,66,92,130,235,16,18,100,148,251,36,106,123,64,
-65,158,3,147,160,108,202,62,68,165,107,243,227,113,198,211,62,39,20,108,
-115,226,241,130,106,113,224,78,162,4,242,130,236,197,60,37,64,190,18,49,
-116,114,37,40,157,76,9,229,37,217,138,185,16,52,196,225,35,23,71,34,82,137,
-213,64,158,84,93,152,187,145,33,73,18,52,68,225,35,23,71,34,82,137,213,192,
-158,86,93,152,175,146,195,102,11,240,145,139,163,145,41,68,235,32,79,44,46,
-204,83,201,225,228,225,35,23,71,34,82,137,214,192,158,90,93,152,163,180,
-138,9,216,197,209,200,148,161,194,32,30,18,3,74,184,164,88,85,248,42,0,78,
-173,186,58,16,5,149,109,110,236,90,192,144,1,245,109,210,129,222,115,245,
-252,132,93,204,126,23,171,113,180,137,3,250,8,173,149,28,87,220,252,55,86,
-227,104,232,18,0,119,41,48,171,222,94,217,248,46,189,16,6,11,81,21,62,200,
-66,80,3,246,80,140,244,118,180,160,102,157,191,179,79,80,115,31,133,236,
-161,25,233,64,205,59,127,102,158,160,246,63,41,248,30,75,12,11,151,242,233,
-187,146,156,80,211,114,96,54,230,41,20,129,128,50,211,16,16,2,116,180,196,
-129,1,36,55,76,74,16,19,3,116,196,193,65,48,55,75,80,128,65,6,51,211,20,
-128,130,34,23,166,39,6,39,75,76,80,1,146,239,211,20,16,165,91,157,29,49,66,
-10,124,61,211,209,175,1,173,198,211,20,48,139,113,180,180,197,36,42,220,
-109,29,13,49,74,6,192,95,72,188,6,196,55,74,188,6,247,91,80,136,26,32,104,
-220,205,56,1,98,234,52,122,98,136,14,72,110,152,162,132,148,35,61,49,70,7,
-48,55,76,81,194,206,52,104,180,197,45,192,80,175,4,100,77,10,2,101,56,161,
-166,65,113,162,98,8,3,131,7,169,35,36,57,176,0,0,0,0,0,40,116,208,45,158,
-10,225,223,132,17,13,43,176,228,3,0,167,129,32,17,133,134,32,25,80,220,40,
-240,25,26,44,32,240,24,200,44,24,240,56,156,199,128,83,193,17,7,4,13,128,0,
-10,79,202,28,223,195,1,197,72,196,141,159,220,7,48,33,7,8,3,152,49,117,60,
-240,76,47,60,9,224,187,56,43,224,221,64,172,156,36,98,232,228,96,220,145,
-139,163,182,134,237,146,49,116,118,206,6,141,104,105,136,32,14,4,128,160,
-123,215,140,147,32,145,57,178,156,104,41,228,151,168,225,144,168,105,56,
-248,185,228,140,241,190,100,209,244,80,210,116,151,134,12,73,241,214,111,
-31,23,60,145,158,56,50,72,81,67,230,232,239,209,7,24,147,227,226,233,186,
-120,121,56,226,241,137,116,189,52,6,34,92,37,230,70,201,1,89,56,36,154,110,
-25,49,23,196,149,35,103,194,94,100,108,144,230,203,136,73,174,234,63,52,
-252,212,87,0,131,138,4,12,137,114,168,37,166,144,230,37,5,7,19,39,22,70,
-154,103,143,252,4,11,37,160,68,164,139,7,24,3,152,182,20,28,76,156,89,26,
-105,158,63,240,5,7,19,39,28,82,200,147,143,253,0,193,161,74,72,199,253,132,
-176,230,36,248,134,207,98,138,99,4,24,147,229,16,217,236,81,75,98,12,73,
-241,13,158,142,181,20,198,137,49,39,202,33,179,209,214,162,151,4,24,147,
-226,27,61,61,42,41,142,18,98,79,148,67,103,167,165,69,46,138,49,39,194,173,
-192,158,158,149,20,188,40,196,159,10,183,2,122,218,148,82,248,121,18,124,
-67,103,177,77,177,130,36,73,242,136,108,246,41,181,177,18,36,248,134,207,
-71,90,155,99,68,200,147,229,16,217,232,235,83,107,130,36,73,241,13,158,158,
-149,54,199,9,145,39,202,33,179,211,210,166,215,69,72,147,225,86,224,79,79,
-74,155,94,21,34,79,133,91,129,61,109,74,109,126,14,56,7,6,20,28,76,156,89,
-26,105,158,63,240,5,7,19,39,28,82,200,147,143,253,0,193,161,74,72,199,253,
-130,235,191,232,8,149,2,8,196,24,164,137,141,200,8,71,161,196,201,45,167,
-146,59,68,89,24,70,206,0,0,0,0,0,0,7,129,249,142,49,232,71,161,196,201,45,
-167,146,59,68,89,24,70,206,0,0,0,0,0,0,7,129,249,141,201,8,71,161,196,201,
-45,167,146,59,68,89,24,70,206,0,0,0,0,0,0,7,129,250,138,2,214,225,113,235,
-2,27,128,0,10,66,3,189,96,67,120,226,224,0,2,148,140,113,145,66,61,14,38,
-73,109,60,145,218,34,200,194,54,112,0,0,0,0,0,0,60,15,204,110,80,66,61,14,
-38,73,109,60,145,218,34,200,194,54,112,0,0,0,0,0,0,60,15,204,113,147,66,61,
-14,38,73,109,60,145,218,34,200,194,54,112,0,0,0,0,0,0,60,15,204,110,88,66,
-61,14,38,73,109,60,145,218,34,200,194,54,112,0,0,0,0,0,0,0,16,12,113,149,
-66,61,14,38,73,109,60,145,218,34,200,194,54,112,0,0,0,0,0,0,0,16,12,110,96,
-66,61,14,38,73,109,60,145,218,34,200,194,54,112,0,0,0,0,0,0,0,16,12,113,
-151,66,61,14,38,73,109,60,145,218,34,200,194,54,112,0,0,0,0,0,0,0,16,12,
-110,104,66,61,14,38,73,109,60,145,218,34,200,194,54,112,0,0,0,0,0,0,4,16,
-12,113,153,66,61,14,38,73,109,60,145,218,34,200,194,54,112,0,0,0,0,0,0,4,
-16,12,110,112,66,61,14,38,73,109,60,145,218,34,200,194,54,112,0,0,0,0,0,0,
-4,16,12,113,155,66,61,14,38,73,109,60,145,218,34,200,194,54,112,0,0,0,0,0,
-0,4,16,12,110,120,66,61,14,38,73,109,60,145,218,34,200,194,54,112,0,0,0,0,
-0,0,4,16,12,113,157,66,61,14,38,73,109,60,145,218,34,200,194,54,112,0,0,0,
-0,0,0,4,16,12,110,128,66,61,14,38,73,109,60,145,218,34,200,194,54,112,0,0,
-0,0,0,0,8,16,12,113,159,66,61,14,38,73,109,60,145,218,34,200,194,54,112,0,
-0,0,0,0,0,8,16,8,58,32,128,24,78,104,129,61,82,2,145,46,17,162,112,208,211,
-107,200,16,137,112,52,41,73,29,113,2,131,137,147,139,35,77,51,234,80,14,39,
-49,224,137,40,35,100,141,9,136,19,18,0,125,162,58,217,236,81,64,68,72,1,
-241,13,158,197,20,150,50,36,0,251,68,117,179,209,214,234,201,69,16,100,72,
-1,246,136,235,103,163,173,208,146,138,68,23,18,0,124,67,103,163,173,213,
-146,138,76,23,18,0,124,67,103,163,173,208,146,138,84,25,18,0,125,162,58,
-217,233,233,117,100,162,138,50,36,0,251,68,117,179,211,210,232,73,69,34,
-139,137,0,62,33,179,211,210,234,201,69,38,139,137,0,62,33,179,211,210,232,
-73,69,42,139,137,0,62,21,110,4,250,178,81,70,23,18,0,124,42,220,9,244,36,
-162,145,134,68,128,31,6,234,5,100,234,201,69,28,100,72,1,240,110,160,86,78,
-132,148,82,56,168,144,3,237,17,214,207,171,37,22,128,42,36,0,251,68,117,
-179,232,73,69,164,9,137,0,62,33,179,234,201,69,168,9,137,0,62,33,179,232,
-73,69,172,10,180,81,50,118,136,235,103,177,77,129,54,138,38,78,33,179,216,
-166,210,198,218,40,153,59,68,117,179,209,214,234,201,77,144,109,162,137,
-147,180,71,91,61,29,110,132,148,218,32,203,69,19,39,16,217,232,235,117,100,
-166,211,6,90,40,153,56,134,207,71,91,161,37,54,168,54,209,68,201,218,35,
-173,158,158,151,86,74,108,163,109,20,76,157,162,58,217,233,233,116,36,166,
-209,70,90,40,153,56,134,207,79,75,171,37,54,154,50,209,68,201,196,54,122,
-122,93,9,41,181,81,150,138,38,78,21,110,4,250,178,83,102,25,104,162,100,
-225,86,224,79,161,37,54,140,54,209,68,201,193,186,129,89,58,178,83,103,27,
-104,162,100,224,221,64,172,157,9,41,180,113,118,138,38,78,209,29,108,250,
-178,83,136,2,237,20,76,157,162,58,217,244,36,167,18,5,90,40,153,56,134,207,
-171,37,56,160,42,209,68,201,196,54,125,9,41,197,141,78,197,141,86,192,0,
-133,66,215,173,96,49,33,64,46,84,8,14,39,49,224,137,40,18,4,19,159,141,100,
-1,100,180,8,148,146,0,91,69,19,38,202,8,58,64,28,209,160,130,52,78,26,26,
-110,255,80,64,196,104,156,50,125,4,144,116,192,57,165,97,4,104,156,52,52,
-221,254,64,20,160,152,23,223,228,32,148,25,174,137,58,23,51,191,200,84,12,
-50,9,195,39,196,80,
+DUK_INTERNAL const duk_uint8_t duk_builtins_data[3972] = {
+144,148,105,223,160,68,52,228,62,12,104,200,165,132,52,167,194,138,105,242,
+252,57,28,211,57,18,64,52,238,62,44,138,111,171,241,164,19,87,125,30,33,
+167,16,145,159,8,211,136,9,225,42,5,240,145,139,163,163,8,211,136,10,228,
+64,211,19,132,140,93,29,56,70,156,64,119,34,66,146,36,104,137,194,70,46,
+142,172,35,78,32,47,146,195,102,11,240,145,139,163,175,8,211,136,9,228,240,
+242,112,145,139,163,179,8,211,136,8,237,34,130,118,49,116,118,225,26,48,0,
+1,80,29,201,158,46,183,39,135,147,132,140,93,16,132,76,66,33,8,66,16,132,
+33,8,66,34,33,154,112,0,1,73,247,35,79,91,237,198,174,192,47,31,23,95,17,
+13,51,19,35,93,68,216,209,128,0,10,192,174,79,15,32,248,8,196,24,8,107,192,
+0,5,98,118,27,94,0,0,43,19,227,94,0,0,43,20,46,215,128,0,10,197,28,198,188,
+0,0,86,41,100,53,224,0,2,177,79,85,175,0,0,21,138,154,45,120,0,0,172,85,
+217,107,192,0,5,98,182,243,86,193,106,52,127,66,249,50,94,124,35,68,225,
+146,49,13,31,170,23,201,146,243,224,200,39,12,145,136,67,134,11,49,0,0,0,0,
+0,0,3,225,255,51,0,0,0,0,0,0,3,193,255,47,18,1,172,19,120,71,10,25,196,136,
+113,162,156,136,199,42,57,204,144,115,132,240,149,2,248,72,197,209,58,2,
+185,16,52,196,225,35,23,68,233,14,228,72,82,68,141,17,56,72,197,209,58,130,
+249,44,54,96,191,9,24,186,39,88,79,39,135,147,132,140,93,19,176,35,180,138,
+9,216,197,209,59,82,79,31,40,242,1,248,58,42,96,121,14,232,94,62,46,190,15,
+38,31,145,33,86,65,76,242,150,143,69,48,242,179,79,45,56,243,51,207,53,64,
+243,116,79,57,72,243,180,207,61,80,243,245,79,65,88,244,34,249,50,94,124,
+35,68,225,146,39,163,23,201,146,243,224,200,39,12,145,61,40,183,146,37,116,
+88,6,136,158,244,241,174,230,202,80,135,130,50,39,16,217,231,208,20,240,70,
+68,225,86,224,79,60,64,84,75,141,7,27,157,32,66,37,194,161,168,153,51,132,
+9,25,4,225,147,180,138,50,196,18,25,4,225,147,180,138,5,215,49,238,105,27,
+60,185,2,72,209,56,100,237,34,140,193,4,136,209,56,100,237,34,129,117,204,
+123,154,70,207,50,64,98,72,64,121,51,68,8,163,73,33,1,228,208,16,0,65,112,
+152,56,196,159,31,23,77,211,195,201,199,23,150,73,169,234,34,24,49,39,199,
+89,188,124,92,242,70,120,224,201,33,69,15,155,163,196,64,153,137,62,58,205,
+227,226,231,146,51,199,26,6,18,92,130,64,192,148,144,102,240,23,129,133,18,
+2,100,224,160,56,100,42,26,78,62,46,121,35,60,112,216,32,50,21,13,39,31,23,
+60,145,154,9,46,18,1,36,64,47,148,64,98,196,132,201,57,68,132,95,18,84,141,
+159,9,121,145,178,67,155,46,73,2,17,46,72,128,89,7,199,32,66,37,194,197,
+217,35,120,228,131,17,46,18,243,35,100,128,172,156,98,2,40,152,151,32,130,
+166,36,248,235,55,143,139,158,72,207,28,150,24,23,46,92,130,80,72,151,21,0,
+100,213,103,229,245,8,186,190,144,24,78,136,24,94,152,3,142,9,113,214,111,
+31,23,60,145,158,57,164,13,68,184,248,186,110,158,30,78,56,188,226,10,62,
+46,121,35,60,113,18,225,27,70,18,32,10,201,208,32,134,214,208,200,84,52,
+156,49,39,50,71,107,107,152,129,13,173,161,144,168,105,57,34,78,100,142,
+214,215,49,16,134,214,210,220,229,81,252,49,39,50,71,107,107,158,65,13,173,
+165,185,202,163,249,34,78,100,142,214,215,60,146,12,16,28,128,62,175,42,6,
+143,36,136,16,64,90,242,135,192,129,67,71,147,62,65,5,215,231,214,6,215,62,
+180,8,49,1,3,162,92,4,98,12,41,14,67,40,106,229,1,132,130,8,24,78,104,129,
+54,62,96,224,144,13,238,124,32,2,62,146,60,51,224,120,146,164,140,137,20,0,
+178,58,11,56,192,5,146,208,34,71,64,36,157,25,200,32,52,158,180,8,146,87,
+129,232,217,29,5,156,179,224,116,52,100,191,28,87,62,130,214,9,79,136,104,
+201,126,56,174,127,0,31,255,225,73,82,71,16,13,1,36,230,18,1,164,14,87,71,
+132,0,143,0,210,131,96,31,0,211,6,42,23,50,70,1,167,13,18,14,130,36,67,232,
+46,36,29,4,78,69,6,60,226,31,192,7,255,252,24,192,163,11,23,51,130,56,35,
+193,56,100,243,31,6,150,46,103,4,225,147,143,114,27,63,57,241,200,169,194,
+133,42,166,175,240,6,23,240,0,97,28,17,224,39,233,32,80,142,8,240,78,25,56,
+9,250,136,22,39,12,156,123,144,217,240,19,245,18,6,19,154,32,79,214,124,14,
+134,140,151,227,139,237,52,11,88,37,62,33,163,37,248,226,251,77,32,213,184,
+64,89,56,39,49,224,137,61,196,5,96,38,35,251,200,15,18,61,96,17,62,40,6,
+145,1,17,31,228,64,89,45,2,39,205,0,178,122,209,63,162,2,101,64,202,113,67,
+77,247,64,92,221,197,186,196,143,4,9,19,208,1,25,187,139,112,128,178,113,
+110,177,35,193,2,68,244,0,46,110,229,30,242,71,130,4,137,232,4,35,55,113,
+110,16,22,78,81,239,36,120,32,72,158,128,64,147,138,25,249,0,52,72,242,2,
+127,2,5,74,96,140,229,203,34,103,250,154,4,17,163,151,44,137,159,234,105,4,
+33,162,93,6,73,123,13,1,165,64,202,113,251,33,6,64,14,71,78,20,101,213,207,
+4,194,207,2,12,162,0,158,176,23,218,168,23,66,64,255,255,255,255,255,255,
+239,127,19,214,33,187,85,2,232,72,0,32,0,0,0,0,0,0,25,136,0,0,0,0,0,0,31,
+15,228,122,247,73,19,69,73,180,134,149,13,68,241,0,0,0,0,0,0,3,193,252,143,
+90,67,2,104,169,54,144,210,161,168,158,32,0,0,0,0,0,0,120,127,142,73,78,20,
+0,0,0,0,0,0,0,0,8,58,189,233,24,77,217,24,93,240,1,230,238,21,23,32,247,68,
+13,155,184,75,189,205,35,102,128,47,114,64,185,187,143,137,4,137,33,205,
+222,17,6,96,48,87,130,50,37,114,1,246,147,21,143,224,54,186,213,128,114,90,
+112,164,0,0,0,0,0,0,124,63,226,117,119,128,25,55,112,96,153,57,41,197,13,
+53,224,65,147,119,38,134,19,146,156,80,211,94,5,194,94,6,37,55,113,110,16,
+22,78,12,19,39,37,56,161,166,188,14,74,110,226,220,32,44,156,154,24,78,74,
+113,67,77,120,32,97,175,4,28,61,224,133,172,186,70,22,248,1,204,73,242,104,
+97,47,128,44,196,159,11,69,175,152,32,35,100,33,142,49,39,218,76,69,237,22,
+190,96,128,141,144,136,32,196,159,24,230,204,246,66,40,179,18,125,164,196,
+206,185,179,61,144,140,28,196,159,6,9,146,200,71,20,98,79,180,152,135,208,
+76,150,66,64,99,18,124,24,49,100,36,137,49,39,218,76,67,232,49,100,37,8,49,
+39,195,186,145,149,144,150,44,196,159,105,49,31,174,164,101,100,38,10,49,
+39,198,33,180,153,37,100,38,141,49,39,218,76,76,234,27,73,146,86,66,112,
+163,18,124,145,4,230,142,86,66,120,211,18,125,164,197,46,144,78,104,229,
+100,40,15,49,39,198,33,107,68,136,39,52,114,178,20,73,24,147,237,38,38,117,
+11,90,36,65,57,163,149,144,164,68,196,159,38,134,19,46,105,56,226,150,68,
+157,160,3,200,147,228,208,194,92,32,124,137,62,49,11,90,36,65,57,163,149,
+178,166,74,68,159,105,49,51,168,90,209,34,9,205,28,173,149,65,82,36,249,34,
+9,205,28,173,175,170,54,68,159,105,49,75,164,19,154,57,91,95,88,84,137,62,
+49,13,164,201,43,111,235,141,145,39,218,76,76,234,27,73,146,86,223,216,17,
+34,79,135,117,35,43,115,236,139,145,39,218,76,71,235,169,25,91,159,104,60,
+137,62,12,19,37,178,182,42,68,159,105,49,15,160,153,45,149,193,18,36,248,
+199,54,103,182,190,232,185,18,125,164,196,206,185,179,61,181,247,133,200,
+147,225,104,181,243,4,4,109,191,190,58,68,159,105,49,23,180,90,249,130,2,
+54,223,224,67,152,147,230,8,8,217,12,16,121,18,124,193,1,27,101,131,131,56,
+7,38,193,198,72,0,0,0,0,0,0,0,0,198,231,240,134,39,63,136,151,95,63,136,49,
+89,252,66,98,243,248,133,96,132,185,5,224,32,36,201,41,248,200,213,249,0,
+131,64,7,39,192,218,148,124,137,74,216,231,198,227,141,182,124,78,40,217,
+231,197,227,4,213,227,192,159,72,10,5,21,218,138,120,74,129,124,36,98,232,
+228,74,81,62,160,20,10,107,181,21,114,32,105,137,194,70,46,142,68,165,19,
+235,1,64,170,187,81,119,34,66,146,36,104,137,194,70,46,142,68,165,19,236,1,
+64,174,187,81,95,37,134,204,23,225,35,23,71,34,82,137,246,128,160,89,93,
+168,167,147,195,201,194,70,46,142,68,165,19,238,1,64,182,187,81,71,105,20,
+19,177,139,163,145,41,68,16,7,6,15,82,70,72,115,96,0,0,0,0,0,93,105,160,91,
+60,149,195,200,194,8,134,149,216,114,1,128,83,192,144,8,194,195,16,12,168,
+110,20,120,12,141,22,16,120,12,100,22,12,120,28,78,99,192,41,224,136,115,
+36,14,100,197,213,245,193,48,189,112,40,2,237,96,175,131,117,2,178,112,145,
+139,163,145,131,114,70,46,142,218,27,182,72,197,209,219,56,26,53,161,166,
+28,1,204,178,10,14,38,78,44,141,52,207,31,0,0,21,64,129,100,180,8,148,145,
+92,203,176,160,226,100,226,200,211,76,241,240,0,1,84,2,131,137,147,142,41,
+100,73,199,192,0,5,88,6,13,10,82,70,62,0,0,42,66,88,115,18,124,67,103,177,
+69,49,130,12,73,242,136,108,246,40,165,177,6,36,248,134,207,71,90,138,99,
+68,152,147,229,16,217,232,235,81,75,130,12,73,241,13,158,158,149,20,199,9,
+49,39,202,33,179,211,210,162,151,69,24,147,225,86,224,79,79,74,138,94,20,
+98,79,133,91,129,61,109,74,41,124,60,137,62,33,179,216,166,216,193,18,36,
+249,68,54,123,20,218,216,137,18,124,67,103,163,173,77,177,162,100,73,242,
+136,108,244,117,169,181,193,18,36,248,134,207,79,74,155,99,132,200,147,229,
+16,217,233,233,83,107,162,164,73,240,171,112,39,167,165,77,175,10,145,39,
+194,173,192,158,182,165,54,191,153,51,72,71,161,196,201,45,167,146,59,68,
+89,24,70,206,0,0,0,0,0,0,7,129,249,153,51,104,71,161,196,201,45,167,146,59,
+68,89,24,70,206,0,0,0,0,0,0,7,129,249,153,51,136,71,161,196,201,45,167,146,
+59,68,89,24,70,206,0,0,0,0,0,0,7,129,249,153,51,168,71,161,196,201,45,167,
+146,59,68,89,24,70,206,0,0,0,0,0,0,0,2,1,153,51,200,71,161,196,201,45,167,
+146,59,68,89,24,70,206,0,0,0,0,0,0,0,2,1,153,51,232,71,161,196,201,45,167,
+146,59,68,89,24,70,206,0,0,0,0,0,0,0,130,1,153,52,8,71,161,196,201,45,167,
+146,59,68,89,24,70,206,0,0,0,0,0,0,0,130,1,153,52,40,71,161,196,201,45,167,
+146,59,68,89,24,70,206,0,0,0,0,0,0,0,130,1,153,52,72,71,161,196,201,45,167,
+146,59,68,89,24,70,206,0,0,0,0,0,0,1,2,1,135,52,102,32,76,72,1,246,136,235,
+103,177,69,1,17,32,7,196,54,123,20,82,88,200,144,3,237,17,214,207,71,91,
+171,37,20,65,145,32,7,218,35,173,158,142,183,66,74,41,16,92,72,1,241,13,
+158,142,183,86,74,41,48,92,72,1,241,13,158,142,183,66,74,41,80,100,72,1,
+246,136,235,103,167,165,213,146,138,40,200,144,3,237,17,214,207,79,75,161,
+37,20,138,46,36,0,248,134,207,79,75,171,37,20,154,46,36,0,248,134,207,79,
+75,161,37,20,170,46,36,0,248,85,184,19,234,201,69,24,92,72,1,240,171,112,
+39,208,146,138,70,25,18,0,124,27,168,21,147,171,37,20,113,145,32,7,193,186,
+129,89,58,18,81,72,226,162,64,15,180,71,91,62,172,148,90,0,168,144,3,237,
+17,214,207,161,37,22,144,38,36,0,248,134,207,171,37,22,160,38,36,0,248,134,
+207,161,37,22,176,42,209,68,201,218,35,173,158,197,54,4,218,40,153,56,134,
+207,98,155,75,27,104,162,100,237,17,214,207,71,91,171,37,54,65,182,138,38,
+78,209,29,108,244,117,186,18,83,104,131,45,20,76,156,67,103,163,173,213,
+146,155,76,25,104,162,100,226,27,61,29,110,132,148,218,160,219,69,19,39,
+104,142,182,122,122,93,89,41,178,141,180,81,50,118,136,235,103,167,165,208,
+146,155,69,25,104,162,100,226,27,61,61,46,172,148,218,104,203,69,19,39,16,
+217,233,233,116,36,166,213,70,90,40,153,56,85,184,19,234,201,77,152,101,
+162,137,147,133,91,129,62,132,148,218,48,219,69,19,39,6,234,5,100,234,201,
+77,156,109,162,137,147,131,117,2,178,116,36,166,209,197,218,40,153,59,68,
+117,179,234,201,78,32,11,180,81,50,118,136,235,103,208,146,156,72,21,104,
+162,100,226,27,62,172,148,226,128,171,69,19,39,16,217,244,36,167,22,53,123,
+102,53,155,80,2,21,11,94,201,128,196,133,0,185,80,32,56,156,199,130,36,160,
+72,16,78,126,54,48,5,146,208,34,82,72,1,109,20,76,155,120,28,34,1,225,32,
+52,171,138,69,133,95,130,160,4,234,219,163,161,0,89,86,214,238,197,172,9,0,
+31,86,221,40,29,231,63,95,200,69,220,199,225,122,183,27,72,144,63,160,138,
+217,81,197,125,207,195,117,110,54,142,129,32,7,114,147,10,189,229,237,159,
+130,235,209,0,96,181,17,83,236,132,37,0,63,101,8,207,71,107,74,6,105,219,
+251,52,245,7,49,248,94,202,17,158,148,12,211,183,246,105,234,15,99,242,159,
+129,228,176,192,185,127,46,155,185,41,197,13,55,38,3,127,255,20,138,160,
+192,25,106,8,8,1,58,90,130,64,128,146,27,168,37,8,9,129,186,130,96,160,152,
+27,165,171,64,32,131,25,234,10,64,65,17,11,212,19,133,18,243,167,165,163,
+32,24,157,45,65,64,6,75,191,80,80,66,149,110,116,117,5,8,41,240,247,79,72,
+188,8,134,81,122,84,1,173,198,212,20,48,139,113,180,181,5,36,42,220,109,29,
+13,65,74,6,192,95,76,188,6,196,55,78,188,6,247,91,86,136,26,32,104,220,205,
+72,1,98,234,52,122,130,136,18,72,51,117,68,3,146,27,168,40,161,37,8,207,80,
+81,129,204,13,212,20,112,179,141,26,45,65,75,112,20,43,193,25,19,66,128,
+153,78,40,105,144,92,104,152,131,124,27,253,128,0,10,116,3,68,146,163,9,
+128,0,10,102,3,138,145,137,27,60,0,0,82,129,7,2,4,16,7,2,70,143,178,203,
+164,237,35,14,25,10,134,147,143,139,158,72,207,28,54,77,47,109,13,55,113,
+120,96,196,159,29,102,241,241,115,201,25,227,131,36,133,20,62,110,143,17,
+16,113,137,62,62,46,155,167,135,147,142,47,44,151,79,221,64,98,37,194,94,
+100,108,144,21,147,140,73,168,228,19,17,124,73,82,54,124,37,230,70,201,14,
+108,185,36,155,14,243,243,83,212,69,131,132,4,12,137,114,168,37,166,145,7,
+10,4,28,200,14,12,40,56,153,56,178,52,211,60,124,0,0,85,0,160,226,100,227,
+138,89,18,113,240,0,1,86,1,131,66,148,145,143,128,0,10,144,93,134,0,0,43,
+80,17,42,4,17,136,49,73,19,49,134,16,143,67,137,146,91,79,36,118,136,178,
+48,141,156,0,0,0,0,0,0,15,3,243,49,135,16,143,67,137,146,91,79,36,118,136,
+178,48,141,156,0,0,0,0,0,0,15,3,245,20,5,173,194,227,214,4,55,0,0,21,196,7,
+122,192,134,241,197,192,0,5,121,25,140,64,132,122,28,76,146,218,121,35,180,
+69,145,132,108,224,0,0,0,0,0,0,120,31,153,140,72,132,122,28,76,146,218,121,
+35,180,69,145,132,108,224,0,0,0,0,0,0,0,32,25,140,80,132,122,28,76,146,218,
+121,35,180,69,145,132,108,224,0,0,0,0,0,0,0,32,25,140,88,132,122,28,76,146,
+218,121,35,180,69,145,132,108,224,0,0,0,0,0,0,8,32,25,140,96,132,122,28,76,
+146,218,121,35,180,69,145,132,108,224,0,0,0,0,0,0,8,32,25,140,104,132,122,
+28,76,146,218,121,35,180,69,145,132,108,224,0,0,0,0,0,0,8,32,25,140,112,
+132,122,28,76,146,218,121,35,180,69,145,132,108,224,0,0,0,0,0,0,16,32,16,
+113,225,0,48,156,209,2,122,244,5,34,92,35,68,225,161,166,218,16,33,18,224,
+104,82,146,59,50,5,7,19,39,22,70,154,103,215,32,28,78,99,193,18,80,70,131,
+165,1,205,34,8,35,68,225,161,166,239,255,4,12,70,137,195,39,248,73,7,78,3,
+154,102,16,70,137,195,67,77,223,248,1,74,9,129,125,255,130,9,65,154,232,
+147,161,115,59,255,5,64,195,32,156,50,126,197,14,2,3,107,173,213,0,
};
#elif defined(DUK_USE_DOUBLE_BE)
-DUK_INTERNAL const duk_uint8_t duk_builtins_data[3819] = {
-144,148,105,221,32,68,52,228,62,12,104,200,165,134,148,248,81,77,61,191,
-135,35,154,103,34,72,6,157,159,197,145,77,245,126,52,130,106,234,163,196,
-52,226,18,51,161,26,113,1,60,37,64,190,18,49,116,116,33,26,113,1,92,136,26,
-98,112,145,139,163,165,8,211,136,14,228,72,82,68,141,17,56,72,197,209,212,
-132,105,196,5,242,88,108,193,126,18,49,116,117,161,26,113,1,60,158,30,78,
-18,49,116,118,33,26,113,1,29,164,80,78,198,46,142,212,36,68,51,71,232,59,
-147,60,93,110,79,15,39,9,24,186,33,13,63,111,185,16,211,206,251,114,98,17,
-171,160,11,199,197,215,196,66,26,102,38,68,53,212,77,136,104,255,5,114,120,
-121,7,192,70,32,192,67,95,249,59,13,13,127,228,248,134,191,242,133,208,215,
-254,81,204,67,95,249,75,33,13,127,229,61,84,53,255,149,52,80,215,254,85,
-217,67,95,249,91,121,13,90,181,168,134,143,152,95,38,75,207,132,104,156,50,
-70,33,163,225,66,249,50,94,124,25,4,225,146,49,14,24,28,196,7,255,128,0,0,
-0,0,0,12,204,7,255,0,0,0,0,0,0,12,188,72,6,176,77,225,28,24,103,14,33,197,
-138,113,227,28,152,231,46,65,205,19,194,84,11,225,35,23,68,231,138,228,64,
-211,19,132,140,93,19,162,59,145,33,73,18,52,68,225,35,23,68,233,139,228,
-176,217,130,252,36,98,232,157,81,60,158,30,78,18,49,116,78,184,142,210,40,
-39,99,23,68,236,201,59,114,142,224,126,14,138,152,30,67,188,23,143,139,175,
-131,194,135,228,72,85,144,83,60,53,163,208,76,60,68,211,197,78,60,116,243,
-200,80,60,149,19,202,82,60,181,51,204,84,60,213,83,206,86,60,240,190,76,
-151,159,8,209,56,100,137,232,133,242,100,188,248,50,9,195,36,79,73,26,238,
-108,129,15,4,100,78,33,179,207,160,41,224,140,137,194,173,192,158,120,128,
-168,151,26,14,55,58,64,132,75,133,67,81,50,103,8,18,50,9,195,39,105,20,101,
-136,36,50,9,195,39,105,20,11,174,99,220,210,54,121,114,4,145,162,112,201,
-218,69,25,130,9,17,162,112,201,218,69,2,235,152,247,52,141,158,100,128,196,
-144,128,242,102,136,17,70,146,66,3,201,160,32,0,130,225,48,113,137,62,62,
-46,155,167,135,147,142,47,24,147,79,205,68,48,98,79,142,179,120,248,185,
-228,140,241,193,146,66,138,31,55,71,126,129,51,18,124,117,155,199,197,207,
-36,103,142,52,12,36,184,100,129,129,41,32,205,221,175,3,10,36,4,201,188,64,
-112,200,84,52,156,124,92,242,70,120,223,48,64,100,42,26,78,62,46,121,35,52,
-18,91,212,2,72,128,95,20,128,197,137,9,146,113,73,8,190,36,169,27,62,18,
-243,35,100,135,54,92,66,4,34,92,145,0,178,15,132,64,132,75,133,139,178,70,
-240,137,6,34,92,37,230,70,201,1,89,56,36,4,81,49,46,25,5,76,73,241,214,111,
-31,23,60,145,158,57,44,48,46,92,184,100,160,145,46,2,0,201,168,207,198,230,
-144,117,60,176,48,156,160,48,188,192,7,28,18,227,172,222,62,46,121,35,60,
-113,200,26,137,113,241,116,221,60,60,156,113,121,4,20,124,92,242,70,120,
-226,37,194,54,140,36,64,21,147,146,68,24,32,57,0,125,78,84,0,160,123,215,
-140,146,1,4,5,175,40,124,8,20,52,121,51,228,24,96,129,209,46,2,49,6,20,135,
-33,20,53,50,128,194,65,4,12,39,52,64,155,31,48,112,72,6,247,62,16,1,31,73,
-30,25,240,60,73,82,70,68,138,0,89,29,5,156,96,2,201,104,17,35,160,18,78,
-140,228,16,26,79,90,4,73,43,192,244,108,142,130,206,89,240,58,26,50,95,142,
-43,159,65,107,4,167,196,52,100,191,28,87,63,128,15,255,240,164,169,35,136,
-6,128,146,115,9,0,210,7,43,163,194,0,71,128,105,65,176,15,128,105,131,21,
-11,153,35,0,211,134,137,7,65,18,33,244,23,18,14,130,39,34,131,30,113,15,
-224,3,255,254,12,80,81,133,139,153,193,28,17,224,156,50,119,15,131,75,23,
-51,130,112,201,199,185,13,159,116,248,228,68,219,66,149,83,83,238,3,11,238,
-0,48,142,8,240,19,239,144,40,71,4,120,39,12,156,4,252,4,11,19,134,78,61,
-200,108,248,9,248,9,3,9,205,16,39,225,62,7,67,70,75,241,197,241,154,5,172,
-18,159,16,209,146,252,113,124,102,144,106,220,32,44,156,19,152,240,68,158,
-66,2,176,19,17,252,164,7,137,30,176,8,158,116,3,72,128,136,143,232,32,44,
-150,129,19,210,128,89,61,104,159,169,1,50,160,101,56,161,166,246,160,46,
-110,226,221,98,71,130,4,137,222,0,140,221,197,184,64,89,56,183,88,145,224,
-129,34,119,128,23,55,114,143,121,35,193,2,68,239,2,17,155,184,183,8,11,39,
-40,247,146,60,16,36,78,240,32,73,197,12,247,128,26,36,121,1,63,49,2,165,48,
-70,114,229,145,51,250,205,2,8,209,203,150,68,207,235,52,130,16,209,46,131,
-36,188,70,128,210,160,101,56,251,16,131,28,7,35,38,218,50,234,103,130,97,
-103,129,6,73,0,79,88,11,237,84,11,161,32,63,247,255,255,255,255,255,255,
-137,235,16,221,170,129,116,36,0,0,0,0,0,0,0,0,28,196,7,255,128,0,0,0,0,0,2,
-61,123,164,137,162,164,218,67,74,134,162,120,128,255,224,0,0,0,0,0,0,71,
-173,33,129,52,84,155,72,105,80,212,79,16,63,252,0,0,0,0,0,0,7,36,38,218,0,
-0,0,0,0,0,0,0,4,29,78,224,140,38,216,140,46,228,0,243,119,10,139,144,123,
-82,6,205,220,37,222,230,145,179,64,23,180,32,92,221,199,196,130,68,144,230,
-237,200,131,44,24,43,193,25,18,185,0,251,73,138,199,240,27,93,106,192,57,
-41,54,210,31,254,0,0,0,0,0,0,49,58,155,192,12,155,184,48,76,156,148,226,
-134,154,240,32,201,187,147,67,9,201,78,40,105,175,2,225,47,3,18,155,184,
-183,8,11,39,6,9,147,146,156,80,211,94,7,37,55,113,110,16,22,78,77,12,39,37,
-56,161,166,188,16,48,215,130,14,30,240,66,213,93,35,11,124,0,230,36,249,52,
-48,151,192,22,98,79,133,162,215,204,16,17,178,16,199,24,147,237,38,34,246,
-139,95,48,64,70,200,68,16,98,79,140,115,102,123,33,20,89,137,62,210,98,103,
-92,217,158,200,70,14,98,79,131,4,201,100,35,138,49,39,218,76,67,232,38,75,
-33,32,49,137,62,12,24,178,18,68,152,147,237,38,33,244,24,178,18,132,24,147,
-225,221,72,202,200,75,22,98,79,180,152,143,215,82,50,178,19,5,24,147,227,
-16,218,76,146,178,19,70,152,147,237,38,38,117,13,164,201,43,33,56,81,137,
-62,72,130,115,71,43,33,60,105,137,62,210,98,151,72,39,52,114,178,20,7,152,
-147,227,16,181,162,68,19,154,57,89,10,36,140,73,246,147,19,58,133,173,18,
-32,156,209,202,200,82,34,98,79,147,67,9,151,52,156,113,75,34,78,208,1,228,
-73,242,104,97,46,16,62,68,159,24,133,173,18,32,156,209,202,217,83,37,34,79,
-180,152,153,212,45,104,145,4,230,142,86,202,160,169,18,124,145,4,230,142,
-86,215,213,27,34,79,180,152,165,210,9,205,28,173,175,172,42,68,159,24,134,
-210,100,149,183,245,198,200,147,237,38,38,117,13,164,201,43,111,236,8,145,
-39,195,186,145,149,185,246,69,200,147,237,38,35,245,212,140,173,207,180,30,
-68,159,6,9,146,217,91,21,34,79,180,152,135,208,76,150,202,224,137,18,124,
-99,155,51,219,95,116,92,137,62,210,98,103,92,217,158,218,251,194,228,73,
-240,180,90,249,130,2,54,223,223,29,34,79,180,152,139,218,45,124,193,1,27,
-111,240,33,204,73,243,4,4,108,134,8,60,137,62,96,128,141,178,193,193,154,3,
-147,32,227,36,0,0,0,0,0,0,0,0,99,115,245,195,19,159,176,75,175,159,176,24,
-172,253,129,49,121,251,2,176,66,92,130,235,16,18,100,148,251,36,106,123,64,
-65,158,3,147,160,108,202,62,68,165,107,243,227,113,198,211,62,39,20,108,
-115,226,241,130,106,113,224,78,162,4,242,130,236,197,60,37,64,190,18,49,
-116,114,37,40,157,76,9,229,37,217,138,185,16,52,196,225,35,23,71,34,82,137,
-213,64,158,84,93,152,187,145,33,73,18,52,68,225,35,23,71,34,82,137,213,192,
-158,86,93,152,175,146,195,102,11,240,145,139,163,145,41,68,235,32,79,44,46,
-204,83,201,225,228,225,35,23,71,34,82,137,214,192,158,90,93,152,163,180,
-138,9,216,197,209,200,148,161,194,32,30,18,2,0,45,248,84,88,162,187,72,78,
-173,186,58,16,16,0,154,236,110,237,85,69,129,245,109,210,128,127,204,92,
-133,253,244,115,222,23,171,113,180,137,0,255,220,85,29,148,174,11,248,55,
-86,227,104,232,18,1,254,222,91,216,169,55,40,112,46,189,16,16,2,72,126,213,
-17,11,70,3,246,80,140,244,118,180,160,31,243,80,79,51,63,157,230,133,236,
-161,25,233,64,63,246,160,158,102,127,59,205,41,248,30,75,12,11,151,242,233,
-187,146,156,80,211,114,96,54,230,41,20,129,128,50,211,16,16,2,116,180,196,
-129,1,36,55,76,74,16,19,3,116,196,193,65,48,55,75,80,128,65,6,51,211,20,
-128,130,34,23,166,39,6,39,75,76,80,1,146,239,211,20,16,165,91,157,29,49,66,
-10,124,61,211,209,175,1,173,198,211,20,48,139,113,180,180,197,36,42,220,
-109,29,13,49,74,6,192,95,72,188,6,196,55,74,188,6,247,91,80,136,26,32,104,
-220,205,56,1,98,234,52,122,98,136,14,72,110,152,162,132,148,35,61,49,70,7,
-48,55,76,81,194,206,52,104,180,197,45,192,80,175,4,100,77,10,2,101,56,161,
-166,65,113,162,98,8,3,131,7,169,35,36,57,176,16,52,232,64,0,0,0,0,45,158,
-10,225,223,132,17,13,43,176,228,3,0,167,129,32,17,133,134,32,25,80,220,40,
-240,25,26,44,32,240,24,200,44,24,240,56,156,199,128,83,193,17,7,4,13,128,0,
-10,79,202,28,223,195,1,197,72,196,141,159,220,7,48,33,7,8,3,152,49,117,60,
-240,76,47,60,9,224,187,56,43,224,221,64,172,156,36,98,232,228,96,220,145,
-139,163,182,134,237,146,49,116,118,206,6,141,104,105,136,32,14,4,128,160,
-123,215,140,147,32,145,57,178,156,104,41,228,151,168,225,144,168,105,56,
-248,185,228,140,241,190,100,209,244,80,210,116,151,134,12,73,241,214,111,
-31,23,60,145,158,56,50,72,81,67,230,232,239,209,7,24,147,227,226,233,186,
-120,121,56,226,241,137,116,189,52,6,34,92,37,230,70,201,1,89,56,36,154,110,
-25,49,23,196,149,35,103,194,94,100,108,144,230,203,136,73,174,234,63,52,
-252,212,87,0,131,138,4,12,137,114,168,37,166,144,230,37,5,7,19,39,22,70,
-154,103,143,252,4,11,37,160,68,164,139,7,24,3,152,182,20,28,76,156,89,26,
-105,158,63,240,5,7,19,39,28,82,200,147,143,253,0,193,161,74,72,199,253,132,
-176,230,36,248,134,207,98,138,99,4,24,147,229,16,217,236,81,75,98,12,73,
-241,13,158,142,181,20,198,137,49,39,202,33,179,209,214,162,151,4,24,147,
-226,27,61,61,42,41,142,18,98,79,148,67,103,167,165,69,46,138,49,39,194,173,
-192,158,158,149,20,188,40,196,159,10,183,2,122,218,148,82,248,121,18,124,
-67,103,177,77,177,130,36,73,242,136,108,246,41,181,177,18,36,248,134,207,
-71,90,155,99,68,200,147,229,16,217,232,235,83,107,130,36,73,241,13,158,158,
-149,54,199,9,145,39,202,33,179,211,210,166,215,69,72,147,225,86,224,79,79,
-74,155,94,21,34,79,133,91,129,61,109,74,109,126,14,56,7,6,20,28,76,156,89,
-26,105,158,63,240,5,7,19,39,28,82,200,147,143,253,0,193,161,74,72,199,253,
-130,235,191,232,8,149,2,8,196,24,164,137,141,200,8,71,161,196,201,45,167,
-146,59,68,89,24,70,206,1,255,128,0,0,0,0,0,1,142,49,232,71,161,196,201,45,
-167,146,59,68,89,24,70,206,1,255,128,0,0,0,0,0,1,141,201,8,71,161,196,201,
-45,167,146,59,68,89,24,70,206,1,255,128,0,0,0,0,0,2,138,2,214,225,113,235,
-2,27,128,0,10,66,3,189,96,67,120,226,224,0,2,148,140,113,145,66,61,14,38,
-73,109,60,145,218,34,200,194,54,112,15,252,0,0,0,0,0,0,12,110,80,66,61,14,
-38,73,109,60,145,218,34,200,194,54,112,15,252,0,0,0,0,0,0,12,113,147,66,61,
-14,38,73,109,60,145,218,34,200,194,54,112,15,252,0,0,0,0,0,0,12,110,88,66,
-61,14,38,73,109,60,145,218,34,200,194,54,112,16,0,0,0,0,0,0,0,12,113,149,
-66,61,14,38,73,109,60,145,218,34,200,194,54,112,16,0,0,0,0,0,0,0,12,110,96,
-66,61,14,38,73,109,60,145,218,34,200,194,54,112,16,0,0,0,0,0,0,0,12,113,
-151,66,61,14,38,73,109,60,145,218,34,200,194,54,112,16,0,0,0,0,0,0,0,12,
-110,104,66,61,14,38,73,109,60,145,218,34,200,194,54,112,16,4,0,0,0,0,0,0,
-12,113,153,66,61,14,38,73,109,60,145,218,34,200,194,54,112,16,4,0,0,0,0,0,
-0,12,110,112,66,61,14,38,73,109,60,145,218,34,200,194,54,112,16,4,0,0,0,0,
-0,0,12,113,155,66,61,14,38,73,109,60,145,218,34,200,194,54,112,16,4,0,0,0,
-0,0,0,12,110,120,66,61,14,38,73,109,60,145,218,34,200,194,54,112,16,4,0,0,
-0,0,0,0,12,113,157,66,61,14,38,73,109,60,145,218,34,200,194,54,112,16,4,0,
-0,0,0,0,0,12,110,128,66,61,14,38,73,109,60,145,218,34,200,194,54,112,16,8,
-0,0,0,0,0,0,12,113,159,66,61,14,38,73,109,60,145,218,34,200,194,54,112,16,
-8,0,0,0,0,0,0,8,58,32,128,24,78,104,129,61,82,2,145,46,17,162,112,208,211,
-107,200,16,137,112,52,41,73,29,113,2,131,137,147,139,35,77,51,234,80,14,39,
-49,224,137,40,35,100,141,9,136,19,18,0,125,162,58,217,236,81,64,68,72,1,
-241,13,158,197,20,150,50,36,0,251,68,117,179,209,214,234,201,69,16,100,72,
-1,246,136,235,103,163,173,208,146,138,68,23,18,0,124,67,103,163,173,213,
-146,138,76,23,18,0,124,67,103,163,173,208,146,138,84,25,18,0,125,162,58,
-217,233,233,117,100,162,138,50,36,0,251,68,117,179,211,210,232,73,69,34,
-139,137,0,62,33,179,211,210,234,201,69,38,139,137,0,62,33,179,211,210,232,
-73,69,42,139,137,0,62,21,110,4,250,178,81,70,23,18,0,124,42,220,9,244,36,
-162,145,134,68,128,31,6,234,5,100,234,201,69,28,100,72,1,240,110,160,86,78,
-132,148,82,56,168,144,3,237,17,214,207,171,37,22,128,42,36,0,251,68,117,
-179,232,73,69,164,9,137,0,62,33,179,234,201,69,168,9,137,0,62,33,179,232,
-73,69,172,10,180,81,50,118,136,235,103,177,77,129,54,138,38,78,33,179,216,
-166,210,198,218,40,153,59,68,117,179,209,214,234,201,77,144,109,162,137,
-147,180,71,91,61,29,110,132,148,218,32,203,69,19,39,16,217,232,235,117,100,
-166,211,6,90,40,153,56,134,207,71,91,161,37,54,168,54,209,68,201,218,35,
-173,158,158,151,86,74,108,163,109,20,76,157,162,58,217,233,233,116,36,166,
-209,70,90,40,153,56,134,207,79,75,171,37,54,154,50,209,68,201,196,54,122,
-122,93,9,41,181,81,150,138,38,78,21,110,4,250,178,83,102,25,104,162,100,
-225,86,224,79,161,37,54,140,54,209,68,201,193,186,129,89,58,178,83,103,27,
-104,162,100,224,221,64,172,157,9,41,180,113,118,138,38,78,209,29,108,250,
-178,83,136,2,237,20,76,157,162,58,217,244,36,167,18,5,90,40,153,56,134,207,
-171,37,56,160,42,209,68,201,196,54,125,9,41,197,141,78,197,141,86,192,0,
-133,66,215,173,96,49,33,64,46,84,8,14,39,49,224,137,40,18,4,19,159,141,100,
-1,100,180,8,148,146,0,91,69,19,38,202,8,58,64,28,209,160,130,52,78,26,26,
-110,255,80,64,196,104,156,50,125,4,144,116,192,57,165,97,4,104,156,52,52,
-221,254,64,20,160,152,23,223,228,32,148,25,174,137,58,23,51,191,200,84,12,
-50,9,195,39,196,80,
+DUK_INTERNAL const duk_uint8_t duk_builtins_data[3972] = {
+144,148,105,223,160,68,52,228,62,12,104,200,165,132,52,167,194,138,105,242,
+252,57,28,211,57,18,64,52,238,62,44,138,111,171,241,164,19,87,125,30,33,
+167,16,145,159,8,211,136,9,225,42,5,240,145,139,163,163,8,211,136,10,228,
+64,211,19,132,140,93,29,56,70,156,64,119,34,66,146,36,104,137,194,70,46,
+142,172,35,78,32,47,146,195,102,11,240,145,139,163,175,8,211,136,9,228,240,
+242,112,145,139,163,179,8,211,136,8,237,34,130,118,49,116,118,225,26,48,0,
+1,80,29,201,158,46,183,39,135,147,132,140,93,16,132,76,66,33,8,66,16,132,
+33,8,66,34,33,154,112,0,1,73,247,35,79,91,237,198,174,192,47,31,23,95,17,
+13,51,19,35,93,68,216,209,128,0,10,192,174,79,15,32,248,8,196,24,8,107,192,
+0,5,98,118,27,94,0,0,43,19,227,94,0,0,43,20,46,215,128,0,10,197,28,198,188,
+0,0,86,41,100,53,224,0,2,177,79,85,175,0,0,21,138,154,45,120,0,0,172,85,
+217,107,192,0,5,98,182,243,86,193,106,52,127,66,249,50,94,124,35,68,225,
+146,49,13,31,170,23,201,146,243,224,200,39,12,145,136,67,134,11,49,1,255,
+224,0,0,0,0,0,3,51,1,255,192,0,0,0,0,0,3,47,18,1,172,19,120,71,10,25,196,
+136,113,162,156,136,199,42,57,204,144,115,132,240,149,2,248,72,197,209,58,
+2,185,16,52,196,225,35,23,68,233,14,228,72,82,68,141,17,56,72,197,209,58,
+130,249,44,54,96,191,9,24,186,39,88,79,39,135,147,132,140,93,19,176,35,180,
+138,9,216,197,209,59,82,79,31,40,242,1,248,58,42,96,121,14,232,94,62,46,
+190,15,38,31,145,33,86,65,76,242,150,143,69,48,242,179,79,45,56,243,51,207,
+53,64,243,116,79,57,72,243,180,207,61,80,243,245,79,65,88,244,34,249,50,94,
+124,35,68,225,146,39,163,23,201,146,243,224,200,39,12,145,61,40,183,146,37,
+116,88,6,136,158,244,241,174,230,202,80,135,130,50,39,16,217,231,208,20,
+240,70,68,225,86,224,79,60,64,84,75,141,7,27,157,32,66,37,194,161,168,153,
+51,132,9,25,4,225,147,180,138,50,196,18,25,4,225,147,180,138,5,215,49,238,
+105,27,60,185,2,72,209,56,100,237,34,140,193,4,136,209,56,100,237,34,129,
+117,204,123,154,70,207,50,64,98,72,64,121,51,68,8,163,73,33,1,228,208,16,0,
+65,112,152,56,196,159,31,23,77,211,195,201,199,23,150,73,169,234,34,24,49,
+39,199,89,188,124,92,242,70,120,224,201,33,69,15,155,163,196,64,153,137,62,
+58,205,227,226,231,146,51,199,26,6,18,92,130,64,192,148,144,102,240,23,129,
+133,18,2,100,224,160,56,100,42,26,78,62,46,121,35,60,112,216,32,50,21,13,
+39,31,23,60,145,154,9,46,18,1,36,64,47,148,64,98,196,132,201,57,68,132,95,
+18,84,141,159,9,121,145,178,67,155,46,73,2,17,46,72,128,89,7,199,32,66,37,
+194,197,217,35,120,228,131,17,46,18,243,35,100,128,172,156,98,2,40,152,151,
+32,130,166,36,248,235,55,143,139,158,72,207,28,150,24,23,46,92,130,80,72,
+151,21,0,100,213,103,229,245,8,186,190,144,24,78,136,24,94,152,3,142,9,113,
+214,111,31,23,60,145,158,57,164,13,68,184,248,186,110,158,30,78,56,188,226,
+10,62,46,121,35,60,113,18,225,27,70,18,32,10,201,208,32,134,214,208,200,84,
+52,156,49,39,50,71,107,107,152,129,13,173,161,144,168,105,57,34,78,100,142,
+214,215,49,16,134,214,210,220,229,81,252,49,39,50,71,107,107,158,65,13,173,
+165,185,202,163,249,34,78,100,142,214,215,60,146,12,16,28,128,62,175,42,6,
+143,36,136,16,64,90,242,135,192,129,67,71,147,62,65,5,215,231,214,6,215,62,
+180,8,49,1,3,162,92,4,98,12,41,14,67,40,106,229,1,132,130,8,24,78,104,129,
+54,62,96,224,144,13,238,124,32,2,62,146,60,51,224,120,146,164,140,137,20,0,
+178,58,11,56,192,5,146,208,34,71,64,36,157,25,200,32,52,158,180,8,146,87,
+129,232,217,29,5,156,179,224,116,52,100,191,28,87,62,130,214,9,79,136,104,
+201,126,56,174,127,0,31,255,225,73,82,71,16,13,1,36,230,18,1,164,14,87,71,
+132,0,143,0,210,131,96,31,0,211,6,42,23,50,70,1,167,13,18,14,130,36,67,232,
+46,36,29,4,78,69,6,60,226,31,192,7,255,252,24,192,163,11,23,51,130,56,35,
+193,56,100,243,31,6,150,46,103,4,225,147,143,114,27,63,57,241,200,169,194,
+133,42,166,175,240,6,23,240,0,97,28,17,224,39,233,32,80,142,8,240,78,25,56,
+9,250,136,22,39,12,156,123,144,217,240,19,245,18,6,19,154,32,79,214,124,14,
+134,140,151,227,139,237,52,11,88,37,62,33,163,37,248,226,251,77,32,213,184,
+64,89,56,39,49,224,137,61,196,5,96,38,35,251,200,15,18,61,96,17,62,40,6,
+145,1,17,31,228,64,89,45,2,39,205,0,178,122,209,63,162,2,101,64,202,113,67,
+77,247,64,92,221,197,186,196,143,4,9,19,208,1,25,187,139,112,128,178,113,
+110,177,35,193,2,68,244,0,46,110,229,30,242,71,130,4,137,232,4,35,55,113,
+110,16,22,78,81,239,36,120,32,72,158,128,64,147,138,25,249,0,52,72,242,2,
+127,2,5,74,96,140,229,203,34,103,250,154,4,17,163,151,44,137,159,234,105,4,
+33,162,93,6,73,123,13,1,165,64,202,113,251,33,6,64,14,71,78,20,101,213,207,
+4,194,207,2,12,162,0,158,176,23,218,168,23,66,64,127,239,255,255,255,255,
+255,255,19,214,33,187,85,2,232,72,0,0,0,0,0,0,0,0,57,136,15,255,0,0,0,0,0,
+0,4,122,247,73,19,69,73,180,134,149,13,68,241,1,255,192,0,0,0,0,0,0,143,90,
+67,2,104,169,54,144,210,161,168,158,32,127,248,0,0,0,0,0,0,14,73,78,20,0,0,
+0,0,0,0,0,0,8,58,189,233,24,77,217,24,93,240,1,230,238,21,23,32,247,68,13,
+155,184,75,189,205,35,102,128,47,114,64,185,187,143,137,4,137,33,205,222,
+17,6,96,48,87,130,50,37,114,1,246,147,21,143,224,54,186,213,128,114,90,112,
+164,63,252,0,0,0,0,0,0,98,117,119,128,25,55,112,96,153,57,41,197,13,53,224,
+65,147,119,38,134,19,146,156,80,211,94,5,194,94,6,37,55,113,110,16,22,78,
+12,19,39,37,56,161,166,188,14,74,110,226,220,32,44,156,154,24,78,74,113,67,
+77,120,32,97,175,4,28,61,224,133,172,186,70,22,248,1,204,73,242,104,97,47,
+128,44,196,159,11,69,175,152,32,35,100,33,142,49,39,218,76,69,237,22,190,
+96,128,141,144,136,32,196,159,24,230,204,246,66,40,179,18,125,164,196,206,
+185,179,61,144,140,28,196,159,6,9,146,200,71,20,98,79,180,152,135,208,76,
+150,66,64,99,18,124,24,49,100,36,137,49,39,218,76,67,232,49,100,37,8,49,39,
+195,186,145,149,144,150,44,196,159,105,49,31,174,164,101,100,38,10,49,39,
+198,33,180,153,37,100,38,141,49,39,218,76,76,234,27,73,146,86,66,112,163,
+18,124,145,4,230,142,86,66,120,211,18,125,164,197,46,144,78,104,229,100,40,
+15,49,39,198,33,107,68,136,39,52,114,178,20,73,24,147,237,38,38,117,11,90,
+36,65,57,163,149,144,164,68,196,159,38,134,19,46,105,56,226,150,68,157,160,
+3,200,147,228,208,194,92,32,124,137,62,49,11,90,36,65,57,163,149,178,166,
+74,68,159,105,49,51,168,90,209,34,9,205,28,173,149,65,82,36,249,34,9,205,
+28,173,175,170,54,68,159,105,49,75,164,19,154,57,91,95,88,84,137,62,49,13,
+164,201,43,111,235,141,145,39,218,76,76,234,27,73,146,86,223,216,17,34,79,
+135,117,35,43,115,236,139,145,39,218,76,71,235,169,25,91,159,104,60,137,62,
+12,19,37,178,182,42,68,159,105,49,15,160,153,45,149,193,18,36,248,199,54,
+103,182,190,232,185,18,125,164,196,206,185,179,61,181,247,133,200,147,225,
+104,181,243,4,4,109,191,190,58,68,159,105,49,23,180,90,249,130,2,54,223,
+224,67,152,147,230,8,8,217,12,16,121,18,124,193,1,27,101,131,131,56,7,38,
+193,198,72,0,0,0,0,0,0,0,0,198,231,240,134,39,63,136,151,95,63,136,49,89,
+252,66,98,243,248,133,96,132,185,5,224,32,36,201,41,248,200,213,249,0,131,
+64,7,39,192,218,148,124,137,74,216,231,198,227,141,182,124,78,40,217,231,
+197,227,4,213,227,192,159,72,10,5,21,218,138,120,74,129,124,36,98,232,228,
+74,81,62,160,20,10,107,181,21,114,32,105,137,194,70,46,142,68,165,19,235,1,
+64,170,187,81,119,34,66,146,36,104,137,194,70,46,142,68,165,19,236,1,64,
+174,187,81,95,37,134,204,23,225,35,23,71,34,82,137,246,128,160,89,93,168,
+167,147,195,201,194,70,46,142,68,165,19,238,1,64,182,187,81,71,105,20,19,
+177,139,163,145,41,68,16,7,6,15,82,70,72,115,96,32,105,221,0,0,0,0,0,91,60,
+149,195,200,194,8,134,149,216,114,1,128,83,192,144,8,194,195,16,12,168,110,
+20,120,12,141,22,16,120,12,100,22,12,120,28,78,99,192,41,224,136,115,36,14,
+100,197,213,245,193,48,189,112,40,2,237,96,175,131,117,2,178,112,145,139,
+163,145,131,114,70,46,142,218,27,182,72,197,209,219,56,26,53,161,166,28,1,
+204,178,10,14,38,78,44,141,52,207,31,0,0,21,64,129,100,180,8,148,145,92,
+203,176,160,226,100,226,200,211,76,241,240,0,1,84,2,131,137,147,142,41,100,
+73,199,192,0,5,88,6,13,10,82,70,62,0,0,42,66,88,115,18,124,67,103,177,69,
+49,130,12,73,242,136,108,246,40,165,177,6,36,248,134,207,71,90,138,99,68,
+152,147,229,16,217,232,235,81,75,130,12,73,241,13,158,158,149,20,199,9,49,
+39,202,33,179,211,210,162,151,69,24,147,225,86,224,79,79,74,138,94,20,98,
+79,133,91,129,61,109,74,41,124,60,137,62,33,179,216,166,216,193,18,36,249,
+68,54,123,20,218,216,137,18,124,67,103,163,173,77,177,162,100,73,242,136,
+108,244,117,169,181,193,18,36,248,134,207,79,74,155,99,132,200,147,229,16,
+217,233,233,83,107,162,164,73,240,171,112,39,167,165,77,175,10,145,39,194,
+173,192,158,182,165,54,191,153,51,72,71,161,196,201,45,167,146,59,68,89,24,
+70,206,1,255,128,0,0,0,0,0,1,153,51,104,71,161,196,201,45,167,146,59,68,89,
+24,70,206,1,255,128,0,0,0,0,0,1,153,51,136,71,161,196,201,45,167,146,59,68,
+89,24,70,206,1,255,128,0,0,0,0,0,1,153,51,168,71,161,196,201,45,167,146,59,
+68,89,24,70,206,2,0,0,0,0,0,0,0,1,153,51,200,71,161,196,201,45,167,146,59,
+68,89,24,70,206,2,0,0,0,0,0,0,0,1,153,51,232,71,161,196,201,45,167,146,59,
+68,89,24,70,206,2,0,128,0,0,0,0,0,1,153,52,8,71,161,196,201,45,167,146,59,
+68,89,24,70,206,2,0,128,0,0,0,0,0,1,153,52,40,71,161,196,201,45,167,146,59,
+68,89,24,70,206,2,0,128,0,0,0,0,0,1,153,52,72,71,161,196,201,45,167,146,59,
+68,89,24,70,206,2,1,0,0,0,0,0,0,1,135,52,102,32,76,72,1,246,136,235,103,
+177,69,1,17,32,7,196,54,123,20,82,88,200,144,3,237,17,214,207,71,91,171,37,
+20,65,145,32,7,218,35,173,158,142,183,66,74,41,16,92,72,1,241,13,158,142,
+183,86,74,41,48,92,72,1,241,13,158,142,183,66,74,41,80,100,72,1,246,136,
+235,103,167,165,213,146,138,40,200,144,3,237,17,214,207,79,75,161,37,20,
+138,46,36,0,248,134,207,79,75,171,37,20,154,46,36,0,248,134,207,79,75,161,
+37,20,170,46,36,0,248,85,184,19,234,201,69,24,92,72,1,240,171,112,39,208,
+146,138,70,25,18,0,124,27,168,21,147,171,37,20,113,145,32,7,193,186,129,89,
+58,18,81,72,226,162,64,15,180,71,91,62,172,148,90,0,168,144,3,237,17,214,
+207,161,37,22,144,38,36,0,248,134,207,171,37,22,160,38,36,0,248,134,207,
+161,37,22,176,42,209,68,201,218,35,173,158,197,54,4,218,40,153,56,134,207,
+98,155,75,27,104,162,100,237,17,214,207,71,91,171,37,54,65,182,138,38,78,
+209,29,108,244,117,186,18,83,104,131,45,20,76,156,67,103,163,173,213,146,
+155,76,25,104,162,100,226,27,61,29,110,132,148,218,160,219,69,19,39,104,
+142,182,122,122,93,89,41,178,141,180,81,50,118,136,235,103,167,165,208,146,
+155,69,25,104,162,100,226,27,61,61,46,172,148,218,104,203,69,19,39,16,217,
+233,233,116,36,166,213,70,90,40,153,56,85,184,19,234,201,77,152,101,162,
+137,147,133,91,129,62,132,148,218,48,219,69,19,39,6,234,5,100,234,201,77,
+156,109,162,137,147,131,117,2,178,116,36,166,209,197,218,40,153,59,68,117,
+179,234,201,78,32,11,180,81,50,118,136,235,103,208,146,156,72,21,104,162,
+100,226,27,62,172,148,226,128,171,69,19,39,16,217,244,36,167,22,53,123,102,
+53,155,80,2,21,11,94,201,128,196,133,0,185,80,32,56,156,199,130,36,160,72,
+16,78,126,54,48,5,146,208,34,82,72,1,109,20,76,155,120,28,34,1,225,32,32,2,
+223,133,69,138,43,180,132,234,219,163,161,1,0,9,174,198,238,213,84,88,31,
+86,221,40,7,252,197,200,95,223,71,61,225,122,183,27,72,144,15,253,197,81,
+217,74,224,191,131,117,110,54,142,129,32,31,237,229,189,138,147,114,135,2,
+235,209,1,0,36,135,237,81,16,180,96,63,101,8,207,71,107,74,1,255,53,4,243,
+51,249,222,104,94,202,17,158,148,3,255,106,9,230,103,243,188,210,159,129,
+228,176,192,185,127,46,155,185,41,197,13,55,38,3,127,255,20,138,160,192,25,
+106,8,8,1,58,90,130,64,128,146,27,168,37,8,9,129,186,130,96,160,152,27,165,
+171,64,32,131,25,234,10,64,65,17,11,212,19,133,18,243,167,165,163,32,24,
+157,45,65,64,6,75,191,80,80,66,149,110,116,117,5,8,41,240,247,79,72,188,8,
+134,81,122,84,1,173,198,212,20,48,139,113,180,181,5,36,42,220,109,29,13,65,
+74,6,192,95,76,188,6,196,55,78,188,6,247,91,86,136,26,32,104,220,205,72,1,
+98,234,52,122,130,136,18,72,51,117,68,3,146,27,168,40,161,37,8,207,80,81,
+129,204,13,212,20,112,179,141,26,45,65,75,112,20,43,193,25,19,66,128,153,
+78,40,105,144,92,104,152,131,124,27,253,128,0,10,116,3,68,146,163,9,128,0,
+10,102,3,138,145,137,27,60,0,0,82,129,7,2,4,16,7,2,70,143,178,203,164,237,
+35,14,25,10,134,147,143,139,158,72,207,28,54,77,47,109,13,55,113,120,96,
+196,159,29,102,241,241,115,201,25,227,131,36,133,20,62,110,143,17,16,113,
+137,62,62,46,155,167,135,147,142,47,44,151,79,221,64,98,37,194,94,100,108,
+144,21,147,140,73,168,228,19,17,124,73,82,54,124,37,230,70,201,14,108,185,
+36,155,14,243,243,83,212,69,131,132,4,12,137,114,168,37,166,145,7,10,4,28,
+200,14,12,40,56,153,56,178,52,211,60,124,0,0,85,0,160,226,100,227,138,89,
+18,113,240,0,1,86,1,131,66,148,145,143,128,0,10,144,93,134,0,0,43,80,17,42,
+4,17,136,49,73,19,49,134,16,143,67,137,146,91,79,36,118,136,178,48,141,156,
+3,255,0,0,0,0,0,0,3,49,135,16,143,67,137,146,91,79,36,118,136,178,48,141,
+156,3,255,0,0,0,0,0,0,5,20,5,173,194,227,214,4,55,0,0,21,196,7,122,192,134,
+241,197,192,0,5,121,25,140,64,132,122,28,76,146,218,121,35,180,69,145,132,
+108,224,31,248,0,0,0,0,0,0,25,140,72,132,122,28,76,146,218,121,35,180,69,
+145,132,108,224,32,0,0,0,0,0,0,0,25,140,80,132,122,28,76,146,218,121,35,
+180,69,145,132,108,224,32,0,0,0,0,0,0,0,25,140,88,132,122,28,76,146,218,
+121,35,180,69,145,132,108,224,32,8,0,0,0,0,0,0,25,140,96,132,122,28,76,146,
+218,121,35,180,69,145,132,108,224,32,8,0,0,0,0,0,0,25,140,104,132,122,28,
+76,146,218,121,35,180,69,145,132,108,224,32,8,0,0,0,0,0,0,25,140,112,132,
+122,28,76,146,218,121,35,180,69,145,132,108,224,32,16,0,0,0,0,0,0,16,113,
+225,0,48,156,209,2,122,244,5,34,92,35,68,225,161,166,218,16,33,18,224,104,
+82,146,59,50,5,7,19,39,22,70,154,103,215,32,28,78,99,193,18,80,70,131,165,
+1,205,34,8,35,68,225,161,166,239,255,4,12,70,137,195,39,248,73,7,78,3,154,
+102,16,70,137,195,67,77,223,248,1,74,9,129,125,255,130,9,65,154,232,147,
+161,115,59,255,5,64,195,32,156,50,126,197,14,2,3,107,173,213,0,
};
#elif defined(DUK_USE_DOUBLE_ME)
-DUK_INTERNAL const duk_uint8_t duk_builtins_data[3819] = {
-144,148,105,221,32,68,52,228,62,12,104,200,165,134,148,248,81,77,61,191,
-135,35,154,103,34,72,6,157,159,197,145,77,245,126,52,130,106,234,163,196,
-52,226,18,51,161,26,113,1,60,37,64,190,18,49,116,116,33,26,113,1,92,136,26,
-98,112,145,139,163,165,8,211,136,14,228,72,82,68,141,17,56,72,197,209,212,
-132,105,196,5,242,88,108,193,126,18,49,116,117,161,26,113,1,60,158,30,78,
-18,49,116,118,33,26,113,1,29,164,80,78,198,46,142,212,36,68,51,71,232,59,
-147,60,93,110,79,15,39,9,24,186,33,13,63,111,185,16,211,206,251,114,98,17,
-171,160,11,199,197,215,196,66,26,102,38,68,53,212,77,136,104,255,5,114,120,
-121,7,192,70,32,192,67,95,249,59,13,13,127,228,248,134,191,242,133,208,215,
-254,81,204,67,95,249,75,33,13,127,229,61,84,53,255,149,52,80,215,254,85,
-217,67,95,249,91,121,13,90,181,168,134,143,152,95,38,75,207,132,104,156,50,
-70,33,163,225,66,249,50,94,124,25,4,225,146,49,14,24,28,196,0,0,15,135,240,
-0,0,0,12,204,0,0,15,7,240,0,0,0,12,188,72,6,176,77,225,28,24,103,14,33,197,
-138,113,227,28,152,231,46,65,205,19,194,84,11,225,35,23,68,231,138,228,64,
-211,19,132,140,93,19,162,59,145,33,73,18,52,68,225,35,23,68,233,139,228,
-176,217,130,252,36,98,232,157,81,60,158,30,78,18,49,116,78,184,142,210,40,
-39,99,23,68,236,201,59,114,142,224,126,14,138,152,30,67,188,23,143,139,175,
-131,194,135,228,72,85,144,83,60,53,163,208,76,60,68,211,197,78,60,116,243,
-200,80,60,149,19,202,82,60,181,51,204,84,60,213,83,206,86,60,240,190,76,
-151,159,8,209,56,100,137,232,133,242,100,188,248,50,9,195,36,79,73,26,238,
-108,129,15,4,100,78,33,179,207,160,41,224,140,137,194,173,192,158,120,128,
-168,151,26,14,55,58,64,132,75,133,67,81,50,103,8,18,50,9,195,39,105,20,101,
-136,36,50,9,195,39,105,20,11,174,99,220,210,54,121,114,4,145,162,112,201,
-218,69,25,130,9,17,162,112,201,218,69,2,235,152,247,52,141,158,100,128,196,
-144,128,242,102,136,17,70,146,66,3,201,160,32,0,130,225,48,113,137,62,62,
-46,155,167,135,147,142,47,24,147,79,205,68,48,98,79,142,179,120,248,185,
-228,140,241,193,146,66,138,31,55,71,126,129,51,18,124,117,155,199,197,207,
-36,103,142,52,12,36,184,100,129,129,41,32,205,221,175,3,10,36,4,201,188,64,
-112,200,84,52,156,124,92,242,70,120,223,48,64,100,42,26,78,62,46,121,35,52,
-18,91,212,2,72,128,95,20,128,197,137,9,146,113,73,8,190,36,169,27,62,18,
-243,35,100,135,54,92,66,4,34,92,145,0,178,15,132,64,132,75,133,139,178,70,
-240,137,6,34,92,37,230,70,201,1,89,56,36,4,81,49,46,25,5,76,73,241,214,111,
-31,23,60,145,158,57,44,48,46,92,184,100,160,145,46,2,0,201,168,207,198,230,
-144,117,60,176,48,156,160,48,188,192,7,28,18,227,172,222,62,46,121,35,60,
-113,200,26,137,113,241,116,221,60,60,156,113,121,4,20,124,92,242,70,120,
-226,37,194,54,140,36,64,21,147,146,68,24,32,57,0,125,78,84,0,160,123,215,
-140,146,1,4,5,175,40,124,8,20,52,121,51,228,24,96,129,209,46,2,49,6,20,135,
-33,20,53,50,128,194,65,4,12,39,52,64,155,31,48,112,72,6,247,62,16,1,31,73,
-30,25,240,60,73,82,70,68,138,0,89,29,5,156,96,2,201,104,17,35,160,18,78,
-140,228,16,26,79,90,4,73,43,192,244,108,142,130,206,89,240,58,26,50,95,142,
-43,159,65,107,4,167,196,52,100,191,28,87,63,128,15,255,240,164,169,35,136,
-6,128,146,115,9,0,210,7,43,163,194,0,71,128,105,65,176,15,128,105,131,21,
-11,153,35,0,211,134,137,7,65,18,33,244,23,18,14,130,39,34,131,30,113,15,
-224,3,255,254,12,80,81,133,139,153,193,28,17,224,156,50,119,15,131,75,23,
-51,130,112,201,199,185,13,159,116,248,228,68,219,66,149,83,83,238,3,11,238,
-0,48,142,8,240,19,239,144,40,71,4,120,39,12,156,4,252,4,11,19,134,78,61,
-200,108,248,9,248,9,3,9,205,16,39,225,62,7,67,70,75,241,197,241,154,5,172,
-18,159,16,209,146,252,113,124,102,144,106,220,32,44,156,19,152,240,68,158,
-66,2,176,19,17,252,164,7,137,30,176,8,158,116,3,72,128,136,143,232,32,44,
-150,129,19,210,128,89,61,104,159,169,1,50,160,101,56,161,166,246,160,46,
-110,226,221,98,71,130,4,137,222,0,140,221,197,184,64,89,56,183,88,145,224,
-129,34,119,128,23,55,114,143,121,35,193,2,68,239,2,17,155,184,183,8,11,39,
-40,247,146,60,16,36,78,240,32,73,197,12,247,128,26,36,121,1,63,49,2,165,48,
-70,114,229,145,51,250,205,2,8,209,203,150,68,207,235,52,130,16,209,46,131,
-36,188,70,128,210,160,101,56,251,16,131,28,7,35,38,218,50,234,103,130,97,
-103,129,6,73,0,79,88,11,237,84,11,161,32,127,255,247,191,255,255,255,255,
-137,235,16,221,170,129,116,36,0,0,0,0,0,16,0,0,12,196,0,0,15,135,240,0,0,0,
-2,61,123,164,137,162,164,218,67,74,134,162,120,128,0,1,224,254,0,0,0,0,71,
-173,33,129,52,84,155,72,105,80,212,79,16,0,0,60,63,192,0,0,0,7,36,38,218,0,
-0,0,0,0,0,0,0,4,29,78,224,140,38,216,140,46,228,0,243,119,10,139,144,123,
-82,6,205,220,37,222,230,145,179,64,23,180,32,92,221,199,196,130,68,144,230,
-237,200,131,44,24,43,193,25,18,185,0,251,73,138,199,240,27,93,106,192,57,
-41,54,210,0,0,62,31,192,0,0,0,49,58,155,192,12,155,184,48,76,156,148,226,
-134,154,240,32,201,187,147,67,9,201,78,40,105,175,2,225,47,3,18,155,184,
-183,8,11,39,6,9,147,146,156,80,211,94,7,37,55,113,110,16,22,78,77,12,39,37,
-56,161,166,188,16,48,215,130,14,30,240,66,213,93,35,11,124,0,230,36,249,52,
-48,151,192,22,98,79,133,162,215,204,16,17,178,16,199,24,147,237,38,34,246,
-139,95,48,64,70,200,68,16,98,79,140,115,102,123,33,20,89,137,62,210,98,103,
-92,217,158,200,70,14,98,79,131,4,201,100,35,138,49,39,218,76,67,232,38,75,
-33,32,49,137,62,12,24,178,18,68,152,147,237,38,33,244,24,178,18,132,24,147,
-225,221,72,202,200,75,22,98,79,180,152,143,215,82,50,178,19,5,24,147,227,
-16,218,76,146,178,19,70,152,147,237,38,38,117,13,164,201,43,33,56,81,137,
-62,72,130,115,71,43,33,60,105,137,62,210,98,151,72,39,52,114,178,20,7,152,
-147,227,16,181,162,68,19,154,57,89,10,36,140,73,246,147,19,58,133,173,18,
-32,156,209,202,200,82,34,98,79,147,67,9,151,52,156,113,75,34,78,208,1,228,
-73,242,104,97,46,16,62,68,159,24,133,173,18,32,156,209,202,217,83,37,34,79,
-180,152,153,212,45,104,145,4,230,142,86,202,160,169,18,124,145,4,230,142,
-86,215,213,27,34,79,180,152,165,210,9,205,28,173,175,172,42,68,159,24,134,
-210,100,149,183,245,198,200,147,237,38,38,117,13,164,201,43,111,236,8,145,
-39,195,186,145,149,185,246,69,200,147,237,38,35,245,212,140,173,207,180,30,
-68,159,6,9,146,217,91,21,34,79,180,152,135,208,76,150,202,224,137,18,124,
-99,155,51,219,95,116,92,137,62,210,98,103,92,217,158,218,251,194,228,73,
-240,180,90,249,130,2,54,223,223,29,34,79,180,152,139,218,45,124,193,1,27,
-111,240,33,204,73,243,4,4,108,134,8,60,137,62,96,128,141,178,193,193,154,3,
-147,32,227,36,0,0,0,0,0,0,0,0,99,115,245,195,19,159,176,75,175,159,176,24,
-172,253,129,49,121,251,2,176,66,92,130,235,16,18,100,148,251,36,106,123,64,
-65,158,3,147,160,108,202,62,68,165,107,243,227,113,198,211,62,39,20,108,
-115,226,241,130,106,113,224,78,162,4,242,130,236,197,60,37,64,190,18,49,
-116,114,37,40,157,76,9,229,37,217,138,185,16,52,196,225,35,23,71,34,82,137,
-213,64,158,84,93,152,187,145,33,73,18,52,68,225,35,23,71,34,82,137,213,192,
-158,86,93,152,175,146,195,102,11,240,145,139,163,145,41,68,235,32,79,44,46,
-204,83,201,225,228,225,35,23,71,34,82,137,214,192,158,90,93,152,163,180,
-138,9,216,197,209,200,148,161,194,32,30,18,0,85,248,42,3,74,184,164,88,78,
-173,186,58,16,44,90,192,144,5,149,109,110,193,245,109,210,128,132,93,204,
-127,222,115,245,252,23,171,113,180,137,1,28,87,220,255,250,8,173,148,55,86,
-227,104,232,18,3,222,94,217,248,119,41,48,168,46,189,16,62,200,66,80,6,11,
-81,21,3,246,80,140,244,118,180,160,79,80,115,31,230,157,191,179,5,236,161,
-25,233,64,158,160,246,63,205,59,127,102,41,248,30,75,12,11,151,242,233,187,
-146,156,80,211,114,96,54,230,41,20,129,128,50,211,16,16,2,116,180,196,129,
-1,36,55,76,74,16,19,3,116,196,193,65,48,55,75,80,128,65,6,51,211,20,128,
-130,34,23,166,39,6,39,75,76,80,1,146,239,211,20,16,165,91,157,29,49,66,10,
-124,61,211,209,175,1,173,198,211,20,48,139,113,180,180,197,36,42,220,109,
-29,13,49,74,6,192,95,72,188,6,196,55,74,188,6,247,91,80,136,26,32,104,220,
-205,56,1,98,234,52,122,98,136,14,72,110,152,162,132,148,35,61,49,70,7,48,
-55,76,81,194,206,52,104,180,197,45,192,80,175,4,100,77,10,2,101,56,161,166,
-65,113,162,98,8,3,131,7,169,35,36,57,176,0,40,116,208,0,0,0,0,45,158,10,
-225,223,132,17,13,43,176,228,3,0,167,129,32,17,133,134,32,25,80,220,40,240,
-25,26,44,32,240,24,200,44,24,240,56,156,199,128,83,193,17,7,4,13,128,0,10,
-79,202,28,223,195,1,197,72,196,141,159,220,7,48,33,7,8,3,152,49,117,60,240,
-76,47,60,9,224,187,56,43,224,221,64,172,156,36,98,232,228,96,220,145,139,
-163,182,134,237,146,49,116,118,206,6,141,104,105,136,32,14,4,128,160,123,
-215,140,147,32,145,57,178,156,104,41,228,151,168,225,144,168,105,56,248,
-185,228,140,241,190,100,209,244,80,210,116,151,134,12,73,241,214,111,31,23,
-60,145,158,56,50,72,81,67,230,232,239,209,7,24,147,227,226,233,186,120,121,
-56,226,241,137,116,189,52,6,34,92,37,230,70,201,1,89,56,36,154,110,25,49,
-23,196,149,35,103,194,94,100,108,144,230,203,136,73,174,234,63,52,252,212,
-87,0,131,138,4,12,137,114,168,37,166,144,230,37,5,7,19,39,22,70,154,103,
-143,252,4,11,37,160,68,164,139,7,24,3,152,182,20,28,76,156,89,26,105,158,
-63,240,5,7,19,39,28,82,200,147,143,253,0,193,161,74,72,199,253,132,176,230,
-36,248,134,207,98,138,99,4,24,147,229,16,217,236,81,75,98,12,73,241,13,158,
-142,181,20,198,137,49,39,202,33,179,209,214,162,151,4,24,147,226,27,61,61,
-42,41,142,18,98,79,148,67,103,167,165,69,46,138,49,39,194,173,192,158,158,
-149,20,188,40,196,159,10,183,2,122,218,148,82,248,121,18,124,67,103,177,77,
-177,130,36,73,242,136,108,246,41,181,177,18,36,248,134,207,71,90,155,99,68,
-200,147,229,16,217,232,235,83,107,130,36,73,241,13,158,158,149,54,199,9,
-145,39,202,33,179,211,210,166,215,69,72,147,225,86,224,79,79,74,155,94,21,
-34,79,133,91,129,61,109,74,109,126,14,56,7,6,20,28,76,156,89,26,105,158,63,
-240,5,7,19,39,28,82,200,147,143,253,0,193,161,74,72,199,253,130,235,191,
-232,8,149,2,8,196,24,164,137,141,200,8,71,161,196,201,45,167,146,59,68,89,
-24,70,206,0,0,7,129,248,0,0,0,1,142,49,232,71,161,196,201,45,167,146,59,68,
-89,24,70,206,0,0,7,129,248,0,0,0,1,141,201,8,71,161,196,201,45,167,146,59,
-68,89,24,70,206,0,0,7,129,248,0,0,0,2,138,2,214,225,113,235,2,27,128,0,10,
-66,3,189,96,67,120,226,224,0,2,148,140,113,145,66,61,14,38,73,109,60,145,
-218,34,200,194,54,112,0,0,60,15,192,0,0,0,12,110,80,66,61,14,38,73,109,60,
-145,218,34,200,194,54,112,0,0,60,15,192,0,0,0,12,113,147,66,61,14,38,73,
-109,60,145,218,34,200,194,54,112,0,0,60,15,192,0,0,0,12,110,88,66,61,14,38,
-73,109,60,145,218,34,200,194,54,112,0,0,0,16,0,0,0,0,12,113,149,66,61,14,
-38,73,109,60,145,218,34,200,194,54,112,0,0,0,16,0,0,0,0,12,110,96,66,61,14,
-38,73,109,60,145,218,34,200,194,54,112,0,0,0,16,0,0,0,0,12,113,151,66,61,
-14,38,73,109,60,145,218,34,200,194,54,112,0,0,0,16,0,0,0,0,12,110,104,66,
-61,14,38,73,109,60,145,218,34,200,194,54,112,0,0,4,16,0,0,0,0,12,113,153,
-66,61,14,38,73,109,60,145,218,34,200,194,54,112,0,0,4,16,0,0,0,0,12,110,
-112,66,61,14,38,73,109,60,145,218,34,200,194,54,112,0,0,4,16,0,0,0,0,12,
-113,155,66,61,14,38,73,109,60,145,218,34,200,194,54,112,0,0,4,16,0,0,0,0,
-12,110,120,66,61,14,38,73,109,60,145,218,34,200,194,54,112,0,0,4,16,0,0,0,
-0,12,113,157,66,61,14,38,73,109,60,145,218,34,200,194,54,112,0,0,4,16,0,0,
-0,0,12,110,128,66,61,14,38,73,109,60,145,218,34,200,194,54,112,0,0,8,16,0,
-0,0,0,12,113,159,66,61,14,38,73,109,60,145,218,34,200,194,54,112,0,0,8,16,
-0,0,0,0,8,58,32,128,24,78,104,129,61,82,2,145,46,17,162,112,208,211,107,
-200,16,137,112,52,41,73,29,113,2,131,137,147,139,35,77,51,234,80,14,39,49,
-224,137,40,35,100,141,9,136,19,18,0,125,162,58,217,236,81,64,68,72,1,241,
-13,158,197,20,150,50,36,0,251,68,117,179,209,214,234,201,69,16,100,72,1,
-246,136,235,103,163,173,208,146,138,68,23,18,0,124,67,103,163,173,213,146,
-138,76,23,18,0,124,67,103,163,173,208,146,138,84,25,18,0,125,162,58,217,
-233,233,117,100,162,138,50,36,0,251,68,117,179,211,210,232,73,69,34,139,
-137,0,62,33,179,211,210,234,201,69,38,139,137,0,62,33,179,211,210,232,73,
-69,42,139,137,0,62,21,110,4,250,178,81,70,23,18,0,124,42,220,9,244,36,162,
-145,134,68,128,31,6,234,5,100,234,201,69,28,100,72,1,240,110,160,86,78,132,
-148,82,56,168,144,3,237,17,214,207,171,37,22,128,42,36,0,251,68,117,179,
-232,73,69,164,9,137,0,62,33,179,234,201,69,168,9,137,0,62,33,179,232,73,69,
-172,10,180,81,50,118,136,235,103,177,77,129,54,138,38,78,33,179,216,166,
-210,198,218,40,153,59,68,117,179,209,214,234,201,77,144,109,162,137,147,
-180,71,91,61,29,110,132,148,218,32,203,69,19,39,16,217,232,235,117,100,166,
-211,6,90,40,153,56,134,207,71,91,161,37,54,168,54,209,68,201,218,35,173,
-158,158,151,86,74,108,163,109,20,76,157,162,58,217,233,233,116,36,166,209,
-70,90,40,153,56,134,207,79,75,171,37,54,154,50,209,68,201,196,54,122,122,
-93,9,41,181,81,150,138,38,78,21,110,4,250,178,83,102,25,104,162,100,225,86,
-224,79,161,37,54,140,54,209,68,201,193,186,129,89,58,178,83,103,27,104,162,
-100,224,221,64,172,157,9,41,180,113,118,138,38,78,209,29,108,250,178,83,
-136,2,237,20,76,157,162,58,217,244,36,167,18,5,90,40,153,56,134,207,171,37,
-56,160,42,209,68,201,196,54,125,9,41,197,141,78,197,141,86,192,0,133,66,
-215,173,96,49,33,64,46,84,8,14,39,49,224,137,40,18,4,19,159,141,100,1,100,
-180,8,148,146,0,91,69,19,38,202,8,58,64,28,209,160,130,52,78,26,26,110,255,
-80,64,196,104,156,50,125,4,144,116,192,57,165,97,4,104,156,52,52,221,254,
-64,20,160,152,23,223,228,32,148,25,174,137,58,23,51,191,200,84,12,50,9,195,
-39,196,80,
+DUK_INTERNAL const duk_uint8_t duk_builtins_data[3972] = {
+144,148,105,223,160,68,52,228,62,12,104,200,165,132,52,167,194,138,105,242,
+252,57,28,211,57,18,64,52,238,62,44,138,111,171,241,164,19,87,125,30,33,
+167,16,145,159,8,211,136,9,225,42,5,240,145,139,163,163,8,211,136,10,228,
+64,211,19,132,140,93,29,56,70,156,64,119,34,66,146,36,104,137,194,70,46,
+142,172,35,78,32,47,146,195,102,11,240,145,139,163,175,8,211,136,9,228,240,
+242,112,145,139,163,179,8,211,136,8,237,34,130,118,49,116,118,225,26,48,0,
+1,80,29,201,158,46,183,39,135,147,132,140,93,16,132,76,66,33,8,66,16,132,
+33,8,66,34,33,154,112,0,1,73,247,35,79,91,237,198,174,192,47,31,23,95,17,
+13,51,19,35,93,68,216,209,128,0,10,192,174,79,15,32,248,8,196,24,8,107,192,
+0,5,98,118,27,94,0,0,43,19,227,94,0,0,43,20,46,215,128,0,10,197,28,198,188,
+0,0,86,41,100,53,224,0,2,177,79,85,175,0,0,21,138,154,45,120,0,0,172,85,
+217,107,192,0,5,98,182,243,86,193,106,52,127,66,249,50,94,124,35,68,225,
+146,49,13,31,170,23,201,146,243,224,200,39,12,145,136,67,134,11,49,0,0,3,
+225,252,0,0,0,3,51,0,0,3,193,252,0,0,0,3,47,18,1,172,19,120,71,10,25,196,
+136,113,162,156,136,199,42,57,204,144,115,132,240,149,2,248,72,197,209,58,
+2,185,16,52,196,225,35,23,68,233,14,228,72,82,68,141,17,56,72,197,209,58,
+130,249,44,54,96,191,9,24,186,39,88,79,39,135,147,132,140,93,19,176,35,180,
+138,9,216,197,209,59,82,79,31,40,242,1,248,58,42,96,121,14,232,94,62,46,
+190,15,38,31,145,33,86,65,76,242,150,143,69,48,242,179,79,45,56,243,51,207,
+53,64,243,116,79,57,72,243,180,207,61,80,243,245,79,65,88,244,34,249,50,94,
+124,35,68,225,146,39,163,23,201,146,243,224,200,39,12,145,61,40,183,146,37,
+116,88,6,136,158,244,241,174,230,202,80,135,130,50,39,16,217,231,208,20,
+240,70,68,225,86,224,79,60,64,84,75,141,7,27,157,32,66,37,194,161,168,153,
+51,132,9,25,4,225,147,180,138,50,196,18,25,4,225,147,180,138,5,215,49,238,
+105,27,60,185,2,72,209,56,100,237,34,140,193,4,136,209,56,100,237,34,129,
+117,204,123,154,70,207,50,64,98,72,64,121,51,68,8,163,73,33,1,228,208,16,0,
+65,112,152,56,196,159,31,23,77,211,195,201,199,23,150,73,169,234,34,24,49,
+39,199,89,188,124,92,242,70,120,224,201,33,69,15,155,163,196,64,153,137,62,
+58,205,227,226,231,146,51,199,26,6,18,92,130,64,192,148,144,102,240,23,129,
+133,18,2,100,224,160,56,100,42,26,78,62,46,121,35,60,112,216,32,50,21,13,
+39,31,23,60,145,154,9,46,18,1,36,64,47,148,64,98,196,132,201,57,68,132,95,
+18,84,141,159,9,121,145,178,67,155,46,73,2,17,46,72,128,89,7,199,32,66,37,
+194,197,217,35,120,228,131,17,46,18,243,35,100,128,172,156,98,2,40,152,151,
+32,130,166,36,248,235,55,143,139,158,72,207,28,150,24,23,46,92,130,80,72,
+151,21,0,100,213,103,229,245,8,186,190,144,24,78,136,24,94,152,3,142,9,113,
+214,111,31,23,60,145,158,57,164,13,68,184,248,186,110,158,30,78,56,188,226,
+10,62,46,121,35,60,113,18,225,27,70,18,32,10,201,208,32,134,214,208,200,84,
+52,156,49,39,50,71,107,107,152,129,13,173,161,144,168,105,57,34,78,100,142,
+214,215,49,16,134,214,210,220,229,81,252,49,39,50,71,107,107,158,65,13,173,
+165,185,202,163,249,34,78,100,142,214,215,60,146,12,16,28,128,62,175,42,6,
+143,36,136,16,64,90,242,135,192,129,67,71,147,62,65,5,215,231,214,6,215,62,
+180,8,49,1,3,162,92,4,98,12,41,14,67,40,106,229,1,132,130,8,24,78,104,129,
+54,62,96,224,144,13,238,124,32,2,62,146,60,51,224,120,146,164,140,137,20,0,
+178,58,11,56,192,5,146,208,34,71,64,36,157,25,200,32,52,158,180,8,146,87,
+129,232,217,29,5,156,179,224,116,52,100,191,28,87,62,130,214,9,79,136,104,
+201,126,56,174,127,0,31,255,225,73,82,71,16,13,1,36,230,18,1,164,14,87,71,
+132,0,143,0,210,131,96,31,0,211,6,42,23,50,70,1,167,13,18,14,130,36,67,232,
+46,36,29,4,78,69,6,60,226,31,192,7,255,252,24,192,163,11,23,51,130,56,35,
+193,56,100,243,31,6,150,46,103,4,225,147,143,114,27,63,57,241,200,169,194,
+133,42,166,175,240,6,23,240,0,97,28,17,224,39,233,32,80,142,8,240,78,25,56,
+9,250,136,22,39,12,156,123,144,217,240,19,245,18,6,19,154,32,79,214,124,14,
+134,140,151,227,139,237,52,11,88,37,62,33,163,37,248,226,251,77,32,213,184,
+64,89,56,39,49,224,137,61,196,5,96,38,35,251,200,15,18,61,96,17,62,40,6,
+145,1,17,31,228,64,89,45,2,39,205,0,178,122,209,63,162,2,101,64,202,113,67,
+77,247,64,92,221,197,186,196,143,4,9,19,208,1,25,187,139,112,128,178,113,
+110,177,35,193,2,68,244,0,46,110,229,30,242,71,130,4,137,232,4,35,55,113,
+110,16,22,78,81,239,36,120,32,72,158,128,64,147,138,25,249,0,52,72,242,2,
+127,2,5,74,96,140,229,203,34,103,250,154,4,17,163,151,44,137,159,234,105,4,
+33,162,93,6,73,123,13,1,165,64,202,113,251,33,6,64,14,71,78,20,101,213,207,
+4,194,207,2,12,162,0,158,176,23,218,168,23,66,64,255,255,239,127,255,255,
+255,255,19,214,33,187,85,2,232,72,0,0,0,0,0,32,0,0,25,136,0,0,31,15,224,0,
+0,0,4,122,247,73,19,69,73,180,134,149,13,68,241,0,0,3,193,252,0,0,0,0,143,
+90,67,2,104,169,54,144,210,161,168,158,32,0,0,120,127,128,0,0,0,14,73,78,
+20,0,0,0,0,0,0,0,0,8,58,189,233,24,77,217,24,93,240,1,230,238,21,23,32,247,
+68,13,155,184,75,189,205,35,102,128,47,114,64,185,187,143,137,4,137,33,205,
+222,17,6,96,48,87,130,50,37,114,1,246,147,21,143,224,54,186,213,128,114,90,
+112,164,0,0,124,63,128,0,0,0,98,117,119,128,25,55,112,96,153,57,41,197,13,
+53,224,65,147,119,38,134,19,146,156,80,211,94,5,194,94,6,37,55,113,110,16,
+22,78,12,19,39,37,56,161,166,188,14,74,110,226,220,32,44,156,154,24,78,74,
+113,67,77,120,32,97,175,4,28,61,224,133,172,186,70,22,248,1,204,73,242,104,
+97,47,128,44,196,159,11,69,175,152,32,35,100,33,142,49,39,218,76,69,237,22,
+190,96,128,141,144,136,32,196,159,24,230,204,246,66,40,179,18,125,164,196,
+206,185,179,61,144,140,28,196,159,6,9,146,200,71,20,98,79,180,152,135,208,
+76,150,66,64,99,18,124,24,49,100,36,137,49,39,218,76,67,232,49,100,37,8,49,
+39,195,186,145,149,144,150,44,196,159,105,49,31,174,164,101,100,38,10,49,
+39,198,33,180,153,37,100,38,141,49,39,218,76,76,234,27,73,146,86,66,112,
+163,18,124,145,4,230,142,86,66,120,211,18,125,164,197,46,144,78,104,229,
+100,40,15,49,39,198,33,107,68,136,39,52,114,178,20,73,24,147,237,38,38,117,
+11,90,36,65,57,163,149,144,164,68,196,159,38,134,19,46,105,56,226,150,68,
+157,160,3,200,147,228,208,194,92,32,124,137,62,49,11,90,36,65,57,163,149,
+178,166,74,68,159,105,49,51,168,90,209,34,9,205,28,173,149,65,82,36,249,34,
+9,205,28,173,175,170,54,68,159,105,49,75,164,19,154,57,91,95,88,84,137,62,
+49,13,164,201,43,111,235,141,145,39,218,76,76,234,27,73,146,86,223,216,17,
+34,79,135,117,35,43,115,236,139,145,39,218,76,71,235,169,25,91,159,104,60,
+137,62,12,19,37,178,182,42,68,159,105,49,15,160,153,45,149,193,18,36,248,
+199,54,103,182,190,232,185,18,125,164,196,206,185,179,61,181,247,133,200,
+147,225,104,181,243,4,4,109,191,190,58,68,159,105,49,23,180,90,249,130,2,
+54,223,224,67,152,147,230,8,8,217,12,16,121,18,124,193,1,27,101,131,131,56,
+7,38,193,198,72,0,0,0,0,0,0,0,0,198,231,240,134,39,63,136,151,95,63,136,49,
+89,252,66,98,243,248,133,96,132,185,5,224,32,36,201,41,248,200,213,249,0,
+131,64,7,39,192,218,148,124,137,74,216,231,198,227,141,182,124,78,40,217,
+231,197,227,4,213,227,192,159,72,10,5,21,218,138,120,74,129,124,36,98,232,
+228,74,81,62,160,20,10,107,181,21,114,32,105,137,194,70,46,142,68,165,19,
+235,1,64,170,187,81,119,34,66,146,36,104,137,194,70,46,142,68,165,19,236,1,
+64,174,187,81,95,37,134,204,23,225,35,23,71,34,82,137,246,128,160,89,93,
+168,167,147,195,201,194,70,46,142,68,165,19,238,1,64,182,187,81,71,105,20,
+19,177,139,163,145,41,68,16,7,6,15,82,70,72,115,96,0,93,105,160,0,0,0,0,91,
+60,149,195,200,194,8,134,149,216,114,1,128,83,192,144,8,194,195,16,12,168,
+110,20,120,12,141,22,16,120,12,100,22,12,120,28,78,99,192,41,224,136,115,
+36,14,100,197,213,245,193,48,189,112,40,2,237,96,175,131,117,2,178,112,145,
+139,163,145,131,114,70,46,142,218,27,182,72,197,209,219,56,26,53,161,166,
+28,1,204,178,10,14,38,78,44,141,52,207,31,0,0,21,64,129,100,180,8,148,145,
+92,203,176,160,226,100,226,200,211,76,241,240,0,1,84,2,131,137,147,142,41,
+100,73,199,192,0,5,88,6,13,10,82,70,62,0,0,42,66,88,115,18,124,67,103,177,
+69,49,130,12,73,242,136,108,246,40,165,177,6,36,248,134,207,71,90,138,99,
+68,152,147,229,16,217,232,235,81,75,130,12,73,241,13,158,158,149,20,199,9,
+49,39,202,33,179,211,210,162,151,69,24,147,225,86,224,79,79,74,138,94,20,
+98,79,133,91,129,61,109,74,41,124,60,137,62,33,179,216,166,216,193,18,36,
+249,68,54,123,20,218,216,137,18,124,67,103,163,173,77,177,162,100,73,242,
+136,108,244,117,169,181,193,18,36,248,134,207,79,74,155,99,132,200,147,229,
+16,217,233,233,83,107,162,164,73,240,171,112,39,167,165,77,175,10,145,39,
+194,173,192,158,182,165,54,191,153,51,72,71,161,196,201,45,167,146,59,68,
+89,24,70,206,0,0,7,129,248,0,0,0,1,153,51,104,71,161,196,201,45,167,146,59,
+68,89,24,70,206,0,0,7,129,248,0,0,0,1,153,51,136,71,161,196,201,45,167,146,
+59,68,89,24,70,206,0,0,7,129,248,0,0,0,1,153,51,168,71,161,196,201,45,167,
+146,59,68,89,24,70,206,0,0,0,2,0,0,0,0,1,153,51,200,71,161,196,201,45,167,
+146,59,68,89,24,70,206,0,0,0,2,0,0,0,0,1,153,51,232,71,161,196,201,45,167,
+146,59,68,89,24,70,206,0,0,0,130,0,0,0,0,1,153,52,8,71,161,196,201,45,167,
+146,59,68,89,24,70,206,0,0,0,130,0,0,0,0,1,153,52,40,71,161,196,201,45,167,
+146,59,68,89,24,70,206,0,0,0,130,0,0,0,0,1,153,52,72,71,161,196,201,45,167,
+146,59,68,89,24,70,206,0,0,1,2,0,0,0,0,1,135,52,102,32,76,72,1,246,136,235,
+103,177,69,1,17,32,7,196,54,123,20,82,88,200,144,3,237,17,214,207,71,91,
+171,37,20,65,145,32,7,218,35,173,158,142,183,66,74,41,16,92,72,1,241,13,
+158,142,183,86,74,41,48,92,72,1,241,13,158,142,183,66,74,41,80,100,72,1,
+246,136,235,103,167,165,213,146,138,40,200,144,3,237,17,214,207,79,75,161,
+37,20,138,46,36,0,248,134,207,79,75,171,37,20,154,46,36,0,248,134,207,79,
+75,161,37,20,170,46,36,0,248,85,184,19,234,201,69,24,92,72,1,240,171,112,
+39,208,146,138,70,25,18,0,124,27,168,21,147,171,37,20,113,145,32,7,193,186,
+129,89,58,18,81,72,226,162,64,15,180,71,91,62,172,148,90,0,168,144,3,237,
+17,214,207,161,37,22,144,38,36,0,248,134,207,171,37,22,160,38,36,0,248,134,
+207,161,37,22,176,42,209,68,201,218,35,173,158,197,54,4,218,40,153,56,134,
+207,98,155,75,27,104,162,100,237,17,214,207,71,91,171,37,54,65,182,138,38,
+78,209,29,108,244,117,186,18,83,104,131,45,20,76,156,67,103,163,173,213,
+146,155,76,25,104,162,100,226,27,61,29,110,132,148,218,160,219,69,19,39,
+104,142,182,122,122,93,89,41,178,141,180,81,50,118,136,235,103,167,165,208,
+146,155,69,25,104,162,100,226,27,61,61,46,172,148,218,104,203,69,19,39,16,
+217,233,233,116,36,166,213,70,90,40,153,56,85,184,19,234,201,77,152,101,
+162,137,147,133,91,129,62,132,148,218,48,219,69,19,39,6,234,5,100,234,201,
+77,156,109,162,137,147,131,117,2,178,116,36,166,209,197,218,40,153,59,68,
+117,179,234,201,78,32,11,180,81,50,118,136,235,103,208,146,156,72,21,104,
+162,100,226,27,62,172,148,226,128,171,69,19,39,16,217,244,36,167,22,53,123,
+102,53,155,80,2,21,11,94,201,128,196,133,0,185,80,32,56,156,199,130,36,160,
+72,16,78,126,54,48,5,146,208,34,82,72,1,109,20,76,155,120,28,34,1,225,32,5,
+95,130,160,52,171,138,69,132,234,219,163,161,2,197,172,9,0,89,86,214,236,
+31,86,221,40,8,69,220,199,253,231,63,95,193,122,183,27,72,144,17,197,125,
+207,255,160,138,217,67,117,110,54,142,129,32,61,229,237,159,135,114,147,10,
+130,235,209,3,236,132,37,0,96,181,17,80,63,101,8,207,71,107,74,4,245,7,49,
+254,105,219,251,48,94,202,17,158,148,9,234,15,99,252,211,183,246,98,159,
+129,228,176,192,185,127,46,155,185,41,197,13,55,38,3,127,255,20,138,160,
+192,25,106,8,8,1,58,90,130,64,128,146,27,168,37,8,9,129,186,130,96,160,152,
+27,165,171,64,32,131,25,234,10,64,65,17,11,212,19,133,18,243,167,165,163,
+32,24,157,45,65,64,6,75,191,80,80,66,149,110,116,117,5,8,41,240,247,79,72,
+188,8,134,81,122,84,1,173,198,212,20,48,139,113,180,181,5,36,42,220,109,29,
+13,65,74,6,192,95,76,188,6,196,55,78,188,6,247,91,86,136,26,32,104,220,205,
+72,1,98,234,52,122,130,136,18,72,51,117,68,3,146,27,168,40,161,37,8,207,80,
+81,129,204,13,212,20,112,179,141,26,45,65,75,112,20,43,193,25,19,66,128,
+153,78,40,105,144,92,104,152,131,124,27,253,128,0,10,116,3,68,146,163,9,
+128,0,10,102,3,138,145,137,27,60,0,0,82,129,7,2,4,16,7,2,70,143,178,203,
+164,237,35,14,25,10,134,147,143,139,158,72,207,28,54,77,47,109,13,55,113,
+120,96,196,159,29,102,241,241,115,201,25,227,131,36,133,20,62,110,143,17,
+16,113,137,62,62,46,155,167,135,147,142,47,44,151,79,221,64,98,37,194,94,
+100,108,144,21,147,140,73,168,228,19,17,124,73,82,54,124,37,230,70,201,14,
+108,185,36,155,14,243,243,83,212,69,131,132,4,12,137,114,168,37,166,145,7,
+10,4,28,200,14,12,40,56,153,56,178,52,211,60,124,0,0,85,0,160,226,100,227,
+138,89,18,113,240,0,1,86,1,131,66,148,145,143,128,0,10,144,93,134,0,0,43,
+80,17,42,4,17,136,49,73,19,49,134,16,143,67,137,146,91,79,36,118,136,178,
+48,141,156,0,0,15,3,240,0,0,0,3,49,135,16,143,67,137,146,91,79,36,118,136,
+178,48,141,156,0,0,15,3,240,0,0,0,5,20,5,173,194,227,214,4,55,0,0,21,196,7,
+122,192,134,241,197,192,0,5,121,25,140,64,132,122,28,76,146,218,121,35,180,
+69,145,132,108,224,0,0,120,31,128,0,0,0,25,140,72,132,122,28,76,146,218,
+121,35,180,69,145,132,108,224,0,0,0,32,0,0,0,0,25,140,80,132,122,28,76,146,
+218,121,35,180,69,145,132,108,224,0,0,0,32,0,0,0,0,25,140,88,132,122,28,76,
+146,218,121,35,180,69,145,132,108,224,0,0,8,32,0,0,0,0,25,140,96,132,122,
+28,76,146,218,121,35,180,69,145,132,108,224,0,0,8,32,0,0,0,0,25,140,104,
+132,122,28,76,146,218,121,35,180,69,145,132,108,224,0,0,8,32,0,0,0,0,25,
+140,112,132,122,28,76,146,218,121,35,180,69,145,132,108,224,0,0,16,32,0,0,
+0,0,16,113,225,0,48,156,209,2,122,244,5,34,92,35,68,225,161,166,218,16,33,
+18,224,104,82,146,59,50,5,7,19,39,22,70,154,103,215,32,28,78,99,193,18,80,
+70,131,165,1,205,34,8,35,68,225,161,166,239,255,4,12,70,137,195,39,248,73,
+7,78,3,154,102,16,70,137,195,67,77,223,248,1,74,9,129,125,255,130,9,65,154,
+232,147,161,115,59,255,5,64,195,32,156,50,126,197,14,2,3,107,173,213,0,
};
#else
#error invalid endianness defines
@@ -11004,12 +11407,12 @@ DUK_INTERNAL DUK_COLD void duk_err_handle_error(duk_hthread *thr, duk_errcode_t
#if defined(DUK_USE_PARANOID_ERRORS)
DUK_INTERNAL DUK_COLD void duk_err_require_type_index(duk_hthread *thr, const char *filename, duk_int_t linenumber, duk_idx_t idx, const char *expect_name) {
DUK_ERROR_RAW_FMT3(thr, filename, linenumber, DUK_ERR_TYPE_ERROR, "%s required, found %s (stack index %ld)",
- expect_name, duk_get_type_name((duk_context *) thr, idx), (long) idx);
+ expect_name, duk_get_type_name(thr, idx), (long) idx);
}
#else
DUK_INTERNAL DUK_COLD void duk_err_require_type_index(duk_hthread *thr, const char *filename, duk_int_t linenumber, duk_idx_t idx, const char *expect_name) {
DUK_ERROR_RAW_FMT3(thr, filename, linenumber, DUK_ERR_TYPE_ERROR, "%s required, found %s (stack index %ld)",
- expect_name, duk_push_string_readable((duk_context *) thr, idx), (long) idx);
+ expect_name, duk_push_string_readable(thr, idx), (long) idx);
}
#endif
DUK_INTERNAL DUK_COLD void duk_err_error_internal(duk_hthread *thr, const char *filename, duk_int_t linenumber) {
@@ -11044,8 +11447,8 @@ DUK_INTERNAL DUK_COLD void duk_err_type_invalid_trap_result(duk_hthread *thr, co
* when non-verbose errors are used.
*/
-DUK_NORETURN(DUK_LOCAL_DECL void duk__err_shared(duk_hthread *thr, duk_uint_t code));
-DUK_LOCAL void duk__err_shared(duk_hthread *thr, duk_uint_t code) {
+DUK_NORETURN(DUK_LOCAL_DECL void duk__err_shared(duk_hthread *thr, duk_errcode_t code));
+DUK_LOCAL void duk__err_shared(duk_hthread *thr, duk_errcode_t code) {
DUK_ERROR_RAW(thr, NULL, 0, code, NULL);
}
DUK_INTERNAL DUK_COLD void duk_err_error(duk_hthread *thr) {
@@ -11087,6 +11490,17 @@ DUK_INTERNAL DUK_COLD void duk_default_fatal_handler(void *udata, const char *ms
/* Default behavior is to abort() on error. There's no printout
* which makes this awkward, so it's always recommended to use an
* explicit fatal error handler.
+ *
+ * ====================================================================
+ * NOTE: If you are seeing this, you are most likely dealing with an
+ * uncaught error. You should provide a fatal error handler in Duktape
+ * heap creation, and should consider using a protected call as your
+ * first call into an empty Duktape context to properly handle errors.
+ * See:
+ * - http://duktape.org/guide.html#error-handling
+ * - http://wiki.duktape.org/HowtoFatalErrors.html
+ * - http://duktape.org/api.html#taglist-protected
+ * ====================================================================
*/
DUK_D(DUK_DPRINT("built-in default fatal error handler called: %s", msg ? msg : "NULL"));
DUK_ABORT();
@@ -11928,8 +12342,8 @@ duk_codepoint_t duk__slow_case_conversion(duk_hthread *thr,
duk_codepoint_t start_i;
duk_codepoint_t start_o;
- DUK_UNREF(thr);
DUK_ASSERT(bd_ctx != NULL);
+ DUK_UNREF(thr);
DUK_DDD(DUK_DDDPRINT("slow case conversion for codepoint: %ld", (long) cp));
@@ -12111,15 +12525,14 @@ duk_codepoint_t duk__case_transform_helper(duk_hthread *thr,
* Replace valstack top with case converted version.
*/
-DUK_INTERNAL void duk_unicode_case_convert_string(duk_hthread *thr, duk_small_int_t uppercase) {
- duk_context *ctx = (duk_context *) thr;
+DUK_INTERNAL void duk_unicode_case_convert_string(duk_hthread *thr, duk_bool_t uppercase) {
duk_hstring *h_input;
duk_bufwriter_ctx bw_alloc;
duk_bufwriter_ctx *bw;
const duk_uint8_t *p, *p_start, *p_end;
duk_codepoint_t prev, curr, next;
- h_input = duk_require_hstring(ctx, -1); /* Accept symbols. */
+ h_input = duk_require_hstring(thr, -1); /* Accept symbols. */
DUK_ASSERT(h_input != NULL);
bw = &bw_alloc;
@@ -12166,9 +12579,9 @@ DUK_INTERNAL void duk_unicode_case_convert_string(duk_hthread *thr, duk_small_in
}
DUK_BW_COMPACT(thr, bw);
- (void) duk_buffer_to_string(ctx, -1); /* Safe, output is encoded. */
+ (void) duk_buffer_to_string(thr, -1); /* Safe, output is encoded. */
/* invalidates h_buf pointer */
- duk_remove_m2(ctx);
+ duk_remove_m2(thr);
}
#if defined(DUK_USE_REGEXP_SUPPORT)
@@ -12597,9 +13010,9 @@ DUK_INTERNAL duk_bool_t duk_double_is_nan_or_inf(duk_double_t x) {
*/
#if defined(DUK_USE_64BIT_OPS)
#if defined(DUK_USE_DOUBLE_ME)
- return (du.ull[DUK_DBL_IDX_ULL0] & 0x000000007ff00000ULL) == 0x000000007ff00000ULL;
+ return (du.ull[DUK_DBL_IDX_ULL0] & DUK_U64_CONSTANT(0x000000007ff00000)) == DUK_U64_CONSTANT(0x000000007ff00000);
#else
- return (du.ull[DUK_DBL_IDX_ULL0] & 0x7ff0000000000000ULL) == 0x7ff0000000000000ULL;
+ return (du.ull[DUK_DBL_IDX_ULL0] & DUK_U64_CONSTANT(0x7ff0000000000000)) == DUK_U64_CONSTANT(0x7ff0000000000000);
#endif
#else
return (du.ui[DUK_DBL_IDX_UI0] & 0x7ff00000UL) == 0x7ff00000UL;
@@ -12616,21 +13029,21 @@ DUK_INTERNAL duk_bool_t duk_double_is_nan_zero_inf(duk_double_t x) {
du.d = x;
#if defined(DUK_USE_64BIT_OPS)
#if defined(DUK_USE_DOUBLE_ME)
- t = du.ull[DUK_DBL_IDX_ULL0] & 0x000000007ff00000ULL;
- if (t == 0x0000000000000000ULL) {
- t = du.ull[DUK_DBL_IDX_ULL0] & 0x0000000080000000ULL;
+ t = du.ull[DUK_DBL_IDX_ULL0] & DUK_U64_CONSTANT(0x000000007ff00000);
+ if (t == DUK_U64_CONSTANT(0x0000000000000000)) {
+ t = du.ull[DUK_DBL_IDX_ULL0] & DUK_U64_CONSTANT(0x0000000080000000);
return t == 0;
}
- if (t == 0x000000007ff00000UL) {
+ if (t == DUK_U64_CONSTANT(0x000000007ff00000)) {
return 1;
}
#else
- t = du.ull[DUK_DBL_IDX_ULL0] & 0x7ff0000000000000ULL;
- if (t == 0x0000000000000000ULL) {
- t = du.ull[DUK_DBL_IDX_ULL0] & 0x8000000000000000ULL;
+ t = du.ull[DUK_DBL_IDX_ULL0] & DUK_U64_CONSTANT(0x7ff0000000000000);
+ if (t == DUK_U64_CONSTANT(0x0000000000000000)) {
+ t = du.ull[DUK_DBL_IDX_ULL0] & DUK_U64_CONSTANT(0x8000000000000000);
return t == 0;
}
- if (t == 0x7ff0000000000000ULL) {
+ if (t == DUK_U64_CONSTANT(0x7ff0000000000000)) {
return 1;
}
#endif
@@ -12654,7 +13067,7 @@ DUK_INTERNAL duk_small_uint_t duk_double_signbit(duk_double_t x) {
DUK_INTERNAL duk_double_t duk_double_trunc_towards_zero(duk_double_t x) {
/* XXX: optimize */
- duk_small_int_t s = duk_double_signbit(x);
+ duk_small_uint_t s = duk_double_signbit(x);
x = DUK_FLOOR(DUK_FABS(x)); /* truncate towards zero */
if (s) {
x = -x;
@@ -12857,13 +13270,12 @@ DUK_INTERNAL void duk_default_free_function(void *udata, void *ptr) {
/* #include duk_internal.h -> already included */
-DUK_EXTERNAL void *duk_resize_buffer(duk_context *ctx, duk_idx_t idx, duk_size_t new_size) {
- duk_hthread *thr = (duk_hthread *) ctx;
+DUK_EXTERNAL void *duk_resize_buffer(duk_hthread *thr, duk_idx_t idx, duk_size_t new_size) {
duk_hbuffer_dynamic *h;
- DUK_ASSERT_CTX_VALID(ctx);
+ DUK_ASSERT_API_ENTRY(thr);
- h = (duk_hbuffer_dynamic *) duk_require_hbuffer(ctx, idx);
+ h = (duk_hbuffer_dynamic *) duk_require_hbuffer(thr, idx);
DUK_ASSERT(h != NULL);
if (!(DUK_HBUFFER_HAS_DYNAMIC(h) && !DUK_HBUFFER_HAS_EXTERNAL(h))) {
@@ -12876,15 +13288,14 @@ DUK_EXTERNAL void *duk_resize_buffer(duk_context *ctx, duk_idx_t idx, duk_size_t
return DUK_HBUFFER_DYNAMIC_GET_DATA_PTR(thr->heap, h);
}
-DUK_EXTERNAL void *duk_steal_buffer(duk_context *ctx, duk_idx_t idx, duk_size_t *out_size) {
- duk_hthread *thr = (duk_hthread *) ctx;
+DUK_EXTERNAL void *duk_steal_buffer(duk_hthread *thr, duk_idx_t idx, duk_size_t *out_size) {
duk_hbuffer_dynamic *h;
void *ptr;
duk_size_t sz;
- DUK_ASSERT(ctx != NULL);
+ DUK_ASSERT_API_ENTRY(thr);
- h = (duk_hbuffer_dynamic *) duk_require_hbuffer(ctx, idx);
+ h = (duk_hbuffer_dynamic *) duk_require_hbuffer(thr, idx);
DUK_ASSERT(h != NULL);
if (!(DUK_HBUFFER_HAS_DYNAMIC(h) && !DUK_HBUFFER_HAS_EXTERNAL(h))) {
@@ -12907,13 +13318,12 @@ DUK_EXTERNAL void *duk_steal_buffer(duk_context *ctx, duk_idx_t idx, duk_size_t
return ptr;
}
-DUK_EXTERNAL void duk_config_buffer(duk_context *ctx, duk_idx_t idx, void *ptr, duk_size_t len) {
- duk_hthread *thr = (duk_hthread *) ctx;
+DUK_EXTERNAL void duk_config_buffer(duk_hthread *thr, duk_idx_t idx, void *ptr, duk_size_t len) {
duk_hbuffer_external *h;
- DUK_ASSERT(ctx != NULL);
+ DUK_ASSERT_API_ENTRY(thr);
- h = (duk_hbuffer_external *) duk_require_hbuffer(ctx, idx);
+ h = (duk_hbuffer_external *) duk_require_hbuffer(thr, idx);
DUK_ASSERT(h != NULL);
if (!DUK_HBUFFER_HAS_EXTERNAL(h)) {
@@ -12940,31 +13350,31 @@ DUK_EXTERNAL void duk_config_buffer(duk_context *ctx, duk_idx_t idx, void *ptr,
#if defined(DUK_USE_BYTECODE_DUMP_SUPPORT)
-#define DUK__SER_MARKER 0xff
-#define DUK__SER_VERSION 0x00
+#define DUK__SER_MARKER 0xbf
#define DUK__SER_STRING 0x00
#define DUK__SER_NUMBER 0x01
#define DUK__BYTECODE_INITIAL_ALLOC 256
+#define DUK__NO_FORMALS 0xffffffffUL
/*
* Dump/load helpers, xxx_raw() helpers do no buffer checks
*/
-DUK_LOCAL duk_uint8_t *duk__load_string_raw(duk_context *ctx, duk_uint8_t *p) {
+DUK_LOCAL duk_uint8_t *duk__load_string_raw(duk_hthread *thr, duk_uint8_t *p) {
duk_uint32_t len;
len = DUK_RAW_READ_U32_BE(p);
- duk_push_lstring(ctx, (const char *) p, len);
+ duk_push_lstring(thr, (const char *) p, len);
p += len;
return p;
}
-DUK_LOCAL duk_uint8_t *duk__load_buffer_raw(duk_context *ctx, duk_uint8_t *p) {
+DUK_LOCAL duk_uint8_t *duk__load_buffer_raw(duk_hthread *thr, duk_uint8_t *p) {
duk_uint32_t len;
duk_uint8_t *buf;
len = DUK_RAW_READ_U32_BE(p);
- buf = (duk_uint8_t *) duk_push_fixed_buffer_nozero(ctx, (duk_size_t) len);
+ buf = (duk_uint8_t *) duk_push_fixed_buffer_nozero(thr, (duk_size_t) len);
DUK_ASSERT(buf != NULL);
DUK_MEMCPY((void *) buf, (const void *) p, (size_t) len);
p += len;
@@ -13020,7 +13430,7 @@ DUK_LOCAL duk_uint8_t *duk__dump_string_prop(duk_hthread *thr, duk_uint8_t *p, d
DUK_ASSERT(h_str != NULL);
}
DUK_ASSERT(DUK_HSTRING_MAX_BYTELEN <= 0x7fffffffUL); /* ensures no overflow */
- p = DUK_BW_ENSURE_RAW(thr, bw_ctx, 4 + DUK_HSTRING_GET_BYTELEN(h_str), p);
+ p = DUK_BW_ENSURE_RAW(thr, bw_ctx, 4U + DUK_HSTRING_GET_BYTELEN(h_str), p);
p = duk__dump_hstring_raw(p, h_str);
return p;
}
@@ -13034,10 +13444,10 @@ DUK_LOCAL duk_uint8_t *duk__dump_buffer_prop(duk_hthread *thr, duk_uint8_t *p, d
h_buf = DUK_TVAL_GET_BUFFER(tv);
DUK_ASSERT(h_buf != NULL);
DUK_ASSERT(DUK_HBUFFER_MAX_BYTELEN <= 0x7fffffffUL); /* ensures no overflow */
- p = DUK_BW_ENSURE_RAW(thr, bw_ctx, 4 + DUK_HBUFFER_GET_SIZE(h_buf), p);
+ p = DUK_BW_ENSURE_RAW(thr, bw_ctx, 4U + DUK_HBUFFER_GET_SIZE(h_buf), p);
p = duk__dump_hbuffer_raw(thr, p, h_buf);
} else {
- p = DUK_BW_ENSURE_RAW(thr, bw_ctx, 4, p);
+ p = DUK_BW_ENSURE_RAW(thr, bw_ctx, 4U, p);
DUK_RAW_WRITE_U32_BE(p, 0);
}
return p;
@@ -13053,7 +13463,7 @@ DUK_LOCAL duk_uint8_t *duk__dump_uint32_prop(duk_hthread *thr, duk_uint8_t *p, d
} else {
val = def_value;
}
- p = DUK_BW_ENSURE_RAW(thr, bw_ctx, 4, p);
+ p = DUK_BW_ENSURE_RAW(thr, bw_ctx, 4U, p);
DUK_RAW_WRITE_U32_BE(p, val);
return p;
}
@@ -13094,12 +13504,12 @@ DUK_LOCAL duk_uint8_t *duk__dump_varmap(duk_hthread *thr, duk_uint8_t *p, duk_bu
#endif
DUK_ASSERT(DUK_HSTRING_MAX_BYTELEN <= 0x7fffffffUL); /* ensures no overflow */
- p = DUK_BW_ENSURE_RAW(thr, bw_ctx, 4 + DUK_HSTRING_GET_BYTELEN(key) + 4, p);
+ p = DUK_BW_ENSURE_RAW(thr, bw_ctx, 4U + DUK_HSTRING_GET_BYTELEN(key) + 4U, p);
p = duk__dump_hstring_raw(p, key);
DUK_RAW_WRITE_U32_BE(p, val);
}
}
- p = DUK_BW_ENSURE_RAW(thr, bw_ctx, 4, p);
+ p = DUK_BW_ENSURE_RAW(thr, bw_ctx, 4U, p);
DUK_RAW_WRITE_U32_BE(p, 0); /* end of _Varmap */
return p;
}
@@ -13109,45 +13519,48 @@ DUK_LOCAL duk_uint8_t *duk__dump_formals(duk_hthread *thr, duk_uint8_t *p, duk_b
tv = duk_hobject_find_existing_entry_tval_ptr(thr->heap, (duk_hobject *) func, DUK_HTHREAD_STRING_INT_FORMALS(thr));
if (tv != NULL && DUK_TVAL_IS_OBJECT(tv)) {
- duk_hobject *h;
- duk_uint_fast32_t i;
+ duk_harray *h;
+ duk_uint32_t i;
- h = DUK_TVAL_GET_OBJECT(tv);
+ /* Here we rely on _Formals being a dense array containing
+ * strings. This should be the case unless _Formals has been
+ * tweaked by the application (which we don't support right
+ * now).
+ */
+ h = (duk_harray *) DUK_TVAL_GET_OBJECT(tv);
DUK_ASSERT(h != NULL);
+ DUK_ASSERT(DUK_HOBJECT_IS_ARRAY((duk_hobject *) h));
+ DUK_ASSERT(h->length <= DUK_HOBJECT_GET_ASIZE((duk_hobject *) h));
- /* We know _Formals is dense and all entries will be in the
- * array part. GC and finalizers shouldn't affect _Formals
- * so side effects should be fine.
- */
- for (i = 0; i < (duk_uint_fast32_t) DUK_HOBJECT_GET_ASIZE(h); i++) {
+ p = DUK_BW_ENSURE_RAW(thr, bw_ctx, 4U, p);
+ DUK_ASSERT(h->length != DUK__NO_FORMALS); /* limits */
+ DUK_RAW_WRITE_U32_BE(p, h->length);
+
+ for (i = 0; i < h->length; i++) {
duk_tval *tv_val;
duk_hstring *varname;
- tv_val = DUK_HOBJECT_A_GET_VALUE_PTR(thr->heap, h, i);
+ tv_val = DUK_HOBJECT_A_GET_VALUE_PTR(thr->heap, (duk_hobject *) h, i);
DUK_ASSERT(tv_val != NULL);
- if (DUK_TVAL_IS_STRING(tv_val)) {
- /* Array is dense and contains only strings, but ASIZE may
- * be larger than used part and there are UNUSED entries.
- */
- varname = DUK_TVAL_GET_STRING(tv_val);
- DUK_ASSERT(varname != NULL);
- DUK_ASSERT(DUK_HSTRING_GET_BYTELEN(varname) >= 1); /* won't be confused with terminator */
+ DUK_ASSERT(DUK_TVAL_IS_STRING(tv_val));
- DUK_ASSERT(DUK_HSTRING_MAX_BYTELEN <= 0x7fffffffUL); /* ensures no overflow */
- p = DUK_BW_ENSURE_RAW(thr, bw_ctx, 4 + DUK_HSTRING_GET_BYTELEN(varname), p);
- p = duk__dump_hstring_raw(p, varname);
- }
+ varname = DUK_TVAL_GET_STRING(tv_val);
+ DUK_ASSERT(varname != NULL);
+ DUK_ASSERT(DUK_HSTRING_GET_BYTELEN(varname) >= 1);
+
+ DUK_ASSERT(DUK_HSTRING_MAX_BYTELEN <= 0x7fffffffUL); /* ensures no overflow */
+ p = DUK_BW_ENSURE_RAW(thr, bw_ctx, 4U + DUK_HSTRING_GET_BYTELEN(varname), p);
+ p = duk__dump_hstring_raw(p, varname);
}
} else {
- DUK_DD(DUK_DDPRINT("dumping function without _Formals, emit empty list"));
+ DUK_DD(DUK_DDPRINT("dumping function without _Formals, emit marker to indicate missing _Formals"));
+ p = DUK_BW_ENSURE_RAW(thr, bw_ctx, 4U, p);
+ DUK_RAW_WRITE_U32_BE(p, DUK__NO_FORMALS); /* marker: no formals */
}
- p = DUK_BW_ENSURE_RAW(thr, bw_ctx, 4, p);
- DUK_RAW_WRITE_U32_BE(p, 0); /* end of _Formals */
return p;
}
-static duk_uint8_t *duk__dump_func(duk_context *ctx, duk_hcompfunc *func, duk_bufwriter_ctx *bw_ctx, duk_uint8_t *p) {
- duk_hthread *thr;
+static duk_uint8_t *duk__dump_func(duk_hthread *thr, duk_hcompfunc *func, duk_bufwriter_ctx *bw_ctx, duk_uint8_t *p) {
duk_tval *tv, *tv_end;
duk_instr_t *ins, *ins_end;
duk_hobject **fn, **fn_end;
@@ -13157,10 +13570,6 @@ static duk_uint8_t *duk__dump_func(duk_context *ctx, duk_hcompfunc *func, duk_bu
duk_uint16_t tmp16;
duk_double_t d;
- thr = (duk_hthread *) ctx;
- DUK_UNREF(ctx);
- DUK_UNREF(thr);
-
DUK_DD(DUK_DDPRINT("dumping function %p to %p: "
"consts=[%p,%p[ (%ld bytes, %ld items), "
"funcs=[%p,%p[ (%ld bytes, %ld items), "
@@ -13182,7 +13591,7 @@ static duk_uint8_t *duk__dump_func(duk_context *ctx, duk_hcompfunc *func, duk_bu
DUK_ASSERT(DUK_USE_ESBC_MAX_BYTES <= 0x7fffffffUL); /* ensures no overflow */
count_instr = (duk_uint32_t) DUK_HCOMPFUNC_GET_CODE_COUNT(thr->heap, func);
- p = DUK_BW_ENSURE_RAW(thr, bw_ctx, 3 * 4 + 2 * 2 + 3 * 4 + count_instr * 4, p);
+ p = DUK_BW_ENSURE_RAW(thr, bw_ctx, 3U * 4U + 2U * 2U + 3U * 4U + count_instr * 4U, p);
/* Fixed header info. */
tmp32 = count_instr;
@@ -13237,12 +13646,12 @@ static duk_uint8_t *duk__dump_func(duk_context *ctx, duk_hcompfunc *func, duk_bu
h_str = DUK_TVAL_GET_STRING(tv);
DUK_ASSERT(h_str != NULL);
DUK_ASSERT(DUK_HSTRING_MAX_BYTELEN <= 0x7fffffffUL); /* ensures no overflow */
- p = DUK_BW_ENSURE_RAW(thr, bw_ctx, 1 + 4 + DUK_HSTRING_GET_BYTELEN(h_str), p),
+ p = DUK_BW_ENSURE_RAW(thr, bw_ctx, 1U + 4U + DUK_HSTRING_GET_BYTELEN(h_str), p),
*p++ = DUK__SER_STRING;
p = duk__dump_hstring_raw(p, h_str);
} else {
DUK_ASSERT(DUK_TVAL_IS_NUMBER(tv));
- p = DUK_BW_ENSURE_RAW(thr, bw_ctx, 1 + 8, p);
+ p = DUK_BW_ENSURE_RAW(thr, bw_ctx, 1U + 8U, p);
*p++ = DUK__SER_NUMBER;
d = DUK_TVAL_GET_NUMBER(tv);
DUK_RAW_WRITE_DOUBLE_BE(p, d);
@@ -13261,7 +13670,7 @@ static duk_uint8_t *duk__dump_func(duk_context *ctx, duk_hcompfunc *func, duk_bu
* to serialize deep functions.
*/
DUK_ASSERT(DUK_HOBJECT_IS_COMPFUNC(*fn));
- p = duk__dump_func(ctx, (duk_hcompfunc *) *fn, bw_ctx, p);
+ p = duk__dump_func(thr, (duk_hcompfunc *) *fn, bw_ctx, p);
fn++;
}
@@ -13306,8 +13715,7 @@ static duk_uint8_t *duk__dump_func(duk_context *ctx, duk_hcompfunc *func, duk_bu
DUK_ASSERT((duk_size_t) (p_end - p) >= (duk_size_t) (n)); \
} while (0)
-static duk_uint8_t *duk__load_func(duk_context *ctx, duk_uint8_t *p, duk_uint8_t *p_end) {
- duk_hthread *thr;
+static duk_uint8_t *duk__load_func(duk_hthread *thr, duk_uint8_t *p, duk_uint8_t *p_end) {
duk_hcompfunc *h_fun;
duk_hbuffer *h_data;
duk_size_t data_size;
@@ -13320,6 +13728,7 @@ static duk_uint8_t *duk__load_func(duk_context *ctx, duk_uint8_t *p, duk_uint8_t
duk_idx_t idx_base;
duk_tval *tv1;
duk_uarridx_t arr_idx;
+ duk_uarridx_t arr_limit;
duk_hobject *func_env;
duk_bool_t need_pop;
@@ -13328,8 +13737,7 @@ static duk_uint8_t *duk__load_func(duk_context *ctx, duk_uint8_t *p, duk_uint8_t
* looks the same as created by duk_js_closure().
*/
- DUK_ASSERT(ctx != NULL);
- thr = (duk_hthread *) ctx;
+ DUK_ASSERT(thr != NULL);
DUK_DD(DUK_DDPRINT("loading function, p=%p, p_end=%p", (void *) p, (void *) p_end));
@@ -13350,13 +13758,13 @@ static duk_uint8_t *duk__load_func(duk_context *ctx, duk_uint8_t *p, duk_uint8_t
* inner functions being loaded. Require enough space to handle
* large functions correctly.
*/
- duk_require_stack(ctx, 2 + count_const + count_funcs);
- idx_base = duk_get_top(ctx);
+ duk_require_stack(thr, (duk_idx_t) (2 + count_const + count_funcs));
+ idx_base = duk_get_top(thr);
/* Push function object, init flags etc. This must match
* duk_js_push_closure() quite carefully.
*/
- h_fun = duk_push_hcompfunc(ctx);
+ h_fun = duk_push_hcompfunc(thr);
DUK_ASSERT(h_fun != NULL);
DUK_ASSERT(DUK_HOBJECT_IS_COMPFUNC((duk_hobject *) h_fun));
DUK_ASSERT(DUK_HCOMPFUNC_GET_DATA(thr->heap, h_fun) == NULL);
@@ -13377,8 +13785,11 @@ static duk_uint8_t *duk__load_func(duk_context *ctx, duk_uint8_t *p, duk_uint8_t
tmp32 = DUK_RAW_READ_U32_BE(p);
DUK_HEAPHDR_SET_FLAGS((duk_heaphdr *) h_fun, tmp32); /* masks flags to only change duk_hobject flags */
- /* standard prototype */
+ /* standard prototype (no need to set here, already set) */
+ DUK_ASSERT(DUK_HOBJECT_GET_PROTOTYPE(thr->heap, (duk_hobject *) h_fun) == thr->builtins[DUK_BIDX_FUNCTION_PROTOTYPE]);
+#if 0
DUK_HOBJECT_SET_PROTOTYPE_UPDREF(thr, &h_fun->obj, thr->builtins[DUK_BIDX_FUNCTION_PROTOTYPE]);
+#endif
/* assert just a few critical flags */
DUK_ASSERT(DUK_HEAPHDR_GET_TYPE((duk_heaphdr *) h_fun) == DUK_HTYPE_OBJECT);
@@ -13391,7 +13802,7 @@ static duk_uint8_t *duk__load_func(duk_context *ctx, duk_uint8_t *p, duk_uint8_t
DUK_ASSERT(!DUK_HOBJECT_HAS_EXOTIC_ARGUMENTS(&h_fun->obj));
/* Create function 'data' buffer but don't attach it yet. */
- fun_data = (duk_uint8_t *) duk_push_fixed_buffer_nozero(ctx, data_size);
+ fun_data = (duk_uint8_t *) duk_push_fixed_buffer_nozero(thr, data_size);
DUK_ASSERT(fun_data != NULL);
/* Load bytecode instructions. */
@@ -13417,7 +13828,7 @@ static duk_uint8_t *duk__load_func(duk_context *ctx, duk_uint8_t *p, duk_uint8_t
const_type = DUK_RAW_READ_U8(p);
switch (const_type) {
case DUK__SER_STRING: {
- p = duk__load_string_raw(ctx, p);
+ p = duk__load_string_raw(thr, p);
break;
}
case DUK__SER_NUMBER: {
@@ -13429,7 +13840,7 @@ static duk_uint8_t *duk__load_func(duk_context *ctx, duk_uint8_t *p, duk_uint8_t
DUK__ASSERT_LEFT(8);
val = DUK_RAW_READ_DOUBLE_BE(p);
DUK_TVAL_SET_NUMBER_CHKFAST_SLOW(&tv_tmp, val);
- duk_push_tval(ctx, &tv_tmp);
+ duk_push_tval(thr, &tv_tmp);
break;
}
default: {
@@ -13440,7 +13851,7 @@ static duk_uint8_t *duk__load_func(duk_context *ctx, duk_uint8_t *p, duk_uint8_t
/* Load inner functions to value stack, but don't yet copy to buffer. */
for (n = count_funcs; n > 0; n--) {
- p = duk__load_func(ctx, p, p_end);
+ p = duk__load_func(thr, p, p_end);
if (p == NULL) {
goto format_error;
}
@@ -13455,12 +13866,12 @@ static duk_uint8_t *duk__load_func(duk_context *ctx, duk_uint8_t *p, duk_uint8_t
* them afterwards.
*/
- h_data = (duk_hbuffer *) duk_known_hbuffer(ctx, idx_base + 1);
+ h_data = (duk_hbuffer *) duk_known_hbuffer(thr, idx_base + 1);
DUK_ASSERT(!DUK_HBUFFER_HAS_DYNAMIC(h_data));
DUK_HCOMPFUNC_SET_DATA(thr->heap, h_fun, h_data);
DUK_HBUFFER_INCREF(thr, h_data);
- tv1 = duk_get_tval(ctx, idx_base + 2); /* may be NULL if no constants or inner funcs */
+ tv1 = duk_get_tval(thr, 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;
@@ -13493,16 +13904,16 @@ static duk_uint8_t *duk__load_func(duk_context *ctx, duk_uint8_t *p, duk_uint8_t
/* The function object is now reachable and refcounts are fine,
* so we can pop off all the temporaries.
*/
- DUK_DDD(DUK_DDDPRINT("function is reachable, reset top; func: %!iT", duk_get_tval(ctx, idx_base)));
- duk_set_top(ctx, idx_base + 1);
+ DUK_DDD(DUK_DDDPRINT("function is reachable, reset top; func: %!iT", duk_get_tval(thr, idx_base)));
+ duk_set_top(thr, idx_base + 1);
/* Setup function properties. */
tmp32 = DUK_RAW_READ_U32_BE(p);
- duk_push_u32(ctx, tmp32);
- duk_xdef_prop_stridx_short(ctx, -2, DUK_STRIDX_LENGTH, DUK_PROPDESC_FLAGS_C);
+ duk_push_u32(thr, tmp32);
+ duk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_LENGTH, DUK_PROPDESC_FLAGS_C);
#if defined(DUK_USE_FUNC_NAME_PROPERTY)
- p = duk__load_string_raw(ctx, p); /* -> [ func funcname ] */
+ p = duk__load_string_raw(thr, p); /* -> [ func funcname ] */
func_env = thr->builtins[DUK_BIDX_GLOBAL_ENV];
DUK_ASSERT(func_env != NULL);
need_pop = 0;
@@ -13519,7 +13930,7 @@ static duk_uint8_t *duk__load_func(duk_context *ctx, duk_uint8_t *p, duk_uint8_t
DUK_ASSERT(new_env != NULL);
DUK_ASSERT(new_env->thread == NULL); /* Closed. */
DUK_ASSERT(new_env->varmap == NULL);
- DUK_ASSERT(new_env->regbase == 0);
+ DUK_ASSERT(new_env->regbase_byteoff == 0);
DUK_ASSERT_HDECENV_VALID(new_env);
DUK_ASSERT(DUK_HOBJECT_GET_PROTOTYPE(thr->heap, (duk_hobject *) new_env) == NULL);
DUK_HOBJECT_SET_PROTOTYPE(thr->heap, (duk_hobject *) new_env, func_env);
@@ -13527,11 +13938,11 @@ static duk_uint8_t *duk__load_func(duk_context *ctx, duk_uint8_t *p, duk_uint8_t
func_env = (duk_hobject *) new_env;
- duk_push_hobject(ctx, (duk_hobject *) new_env);
+ duk_push_hobject(thr, (duk_hobject *) new_env);
- duk_dup_m2(ctx); /* -> [ func funcname env funcname ] */
- duk_dup(ctx, idx_base); /* -> [ func funcname env funcname func ] */
- duk_xdef_prop(ctx, -3, DUK_PROPDESC_FLAGS_NONE); /* -> [ func funcname env ] */
+ duk_dup_m2(thr); /* -> [ func funcname env funcname ] */
+ duk_dup(thr, idx_base); /* -> [ func funcname env funcname func ] */
+ duk_xdef_prop(thr, -3, DUK_PROPDESC_FLAGS_NONE); /* -> [ func funcname env ] */
need_pop = 1; /* Need to pop env, but -after- updating h_fun and increfs. */
}
@@ -13541,93 +13952,85 @@ static duk_uint8_t *duk__load_func(duk_context *ctx, duk_uint8_t *p, duk_uint8_t
DUK_HOBJECT_INCREF(thr, func_env);
DUK_HOBJECT_INCREF(thr, func_env);
if (need_pop) {
- duk_pop(ctx);
+ duk_pop(thr);
}
- duk_xdef_prop_stridx_short(ctx, -2, DUK_STRIDX_NAME, DUK_PROPDESC_FLAGS_C);
+ duk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_NAME, DUK_PROPDESC_FLAGS_C);
#endif /* DUK_USE_FUNC_NAME_PROPERTY */
#if defined(DUK_USE_FUNC_FILENAME_PROPERTY)
- p = duk__load_string_raw(ctx, p);
- duk_xdef_prop_stridx_short(ctx, -2, DUK_STRIDX_FILE_NAME, DUK_PROPDESC_FLAGS_C);
+ p = duk__load_string_raw(thr, p);
+ duk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_FILE_NAME, DUK_PROPDESC_FLAGS_C);
#endif /* DUK_USE_FUNC_FILENAME_PROPERTY */
if (DUK_HOBJECT_HAS_CONSTRUCTABLE((duk_hobject *) h_fun)) {
/* Restore empty external .prototype only for constructable
* functions.
*/
- duk_push_object(ctx);
- duk_dup_m2(ctx);
- duk_xdef_prop_stridx_short(ctx, -2, DUK_STRIDX_CONSTRUCTOR, DUK_PROPDESC_FLAGS_WC); /* func.prototype.constructor = func */
- duk_compact_m1(ctx);
- duk_xdef_prop_stridx_short(ctx, -2, DUK_STRIDX_PROTOTYPE, DUK_PROPDESC_FLAGS_W);
+ duk_push_object(thr);
+ duk_dup_m2(thr);
+ duk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_CONSTRUCTOR, DUK_PROPDESC_FLAGS_WC); /* func.prototype.constructor = func */
+ duk_compact_m1(thr);
+ duk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_PROTOTYPE, DUK_PROPDESC_FLAGS_W);
}
#if defined(DUK_USE_PC2LINE)
- p = duk__load_buffer_raw(ctx, p);
- duk_xdef_prop_stridx_short(ctx, -2, DUK_STRIDX_INT_PC2LINE, DUK_PROPDESC_FLAGS_WC);
+ p = duk__load_buffer_raw(thr, p);
+ duk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_INT_PC2LINE, DUK_PROPDESC_FLAGS_WC);
#endif /* DUK_USE_PC2LINE */
- duk_push_object(ctx); /* _Varmap */
+ duk_push_object(thr); /* _Varmap */
for (;;) {
/* XXX: awkward */
- p = duk__load_string_raw(ctx, p);
- if (duk_get_length(ctx, -1) == 0) {
- duk_pop(ctx);
+ p = duk__load_string_raw(thr, p);
+ if (duk_get_length(thr, -1) == 0) {
+ duk_pop(thr);
break;
}
tmp32 = DUK_RAW_READ_U32_BE(p);
- duk_push_u32(ctx, tmp32);
- duk_put_prop(ctx, -3);
+ duk_push_u32(thr, tmp32);
+ duk_put_prop(thr, -3);
}
- duk_compact_m1(ctx);
- duk_xdef_prop_stridx_short(ctx, -2, DUK_STRIDX_INT_VARMAP, DUK_PROPDESC_FLAGS_NONE);
+ duk_compact_m1(thr);
+ duk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_INT_VARMAP, DUK_PROPDESC_FLAGS_NONE);
- /* If _Formals wasn't present in the original function, the list
- * here will be empty. Same happens if _Formals was present but
- * had zero length. We can omit _Formals from the result if its
- * length is zero and matches nargs.
+ /* _Formals may have been missing in the original function, which is
+ * handled using a marker length.
*/
- duk_push_array(ctx); /* _Formals */
- for (arr_idx = 0; ; arr_idx++) {
- /* XXX: awkward */
- p = duk__load_string_raw(ctx, p);
- if (duk_get_length(ctx, -1) == 0) {
- duk_pop(ctx);
- break;
+ arr_limit = DUK_RAW_READ_U32_BE(p);
+ if (arr_limit != DUK__NO_FORMALS) {
+ duk_push_array(thr); /* _Formals */
+ for (arr_idx = 0; arr_idx < arr_limit; arr_idx++) {
+ p = duk__load_string_raw(thr, p);
+ duk_put_prop_index(thr, -2, arr_idx);
}
- duk_put_prop_index(ctx, -2, arr_idx);
- }
- if (arr_idx == 0 && h_fun->nargs == 0) {
- duk_pop(ctx);
+ duk_compact_m1(thr);
+ duk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_INT_FORMALS, DUK_PROPDESC_FLAGS_NONE);
} else {
- duk_compact_m1(ctx);
- duk_xdef_prop_stridx_short(ctx, -2, DUK_STRIDX_INT_FORMALS, DUK_PROPDESC_FLAGS_NONE);
+ DUK_DD(DUK_DDPRINT("no _Formals in dumped function"));
}
/* Return with final function pushed on stack top. */
- DUK_DD(DUK_DDPRINT("final loaded function: %!iT", duk_get_tval(ctx, -1)));
- DUK_ASSERT_TOP(ctx, idx_base + 1);
+ DUK_DD(DUK_DDPRINT("final loaded function: %!iT", duk_get_tval(thr, -1)));
+ DUK_ASSERT_TOP(thr, idx_base + 1);
return p;
format_error:
return NULL;
}
-DUK_EXTERNAL void duk_dump_function(duk_context *ctx) {
- duk_hthread *thr;
+DUK_EXTERNAL void duk_dump_function(duk_hthread *thr) {
duk_hcompfunc *func;
duk_bufwriter_ctx bw_ctx_alloc;
duk_bufwriter_ctx *bw_ctx = &bw_ctx_alloc;
duk_uint8_t *p;
- DUK_ASSERT(ctx != NULL);
- thr = (duk_hthread *) ctx;
+ DUK_ASSERT_API_ENTRY(thr);
/* Bound functions don't have all properties so we'd either need to
* lookup the non-bound target function or reject bound functions.
- * For now, bound functions are rejected.
+ * For now, bound functions are rejected with TypeError.
*/
- func = duk_require_hcompfunc(ctx, -1);
+ func = duk_require_hcompfunc(thr, -1);
DUK_ASSERT(func != NULL);
DUK_ASSERT(!DUK_HOBJECT_HAS_BOUNDFUNC(&func->obj));
@@ -13637,26 +14040,22 @@ DUK_EXTERNAL void duk_dump_function(duk_context *ctx) {
DUK_BW_INIT_PUSHBUF(thr, bw_ctx, DUK__BYTECODE_INITIAL_ALLOC);
p = DUK_BW_GET_PTR(thr, bw_ctx);
*p++ = DUK__SER_MARKER;
- *p++ = DUK__SER_VERSION;
- p = duk__dump_func(ctx, func, bw_ctx, p);
+ p = duk__dump_func(thr, func, bw_ctx, p);
DUK_BW_SET_PTR(thr, bw_ctx, p);
DUK_BW_COMPACT(thr, bw_ctx);
- DUK_DD(DUK_DDPRINT("serialized result: %!T", duk_get_tval(ctx, -1)));
+ DUK_DD(DUK_DDPRINT("serialized result: %!T", duk_get_tval(thr, -1)));
- duk_remove_m2(ctx); /* [ ... func buf ] -> [ ... buf ] */
+ duk_remove_m2(thr); /* [ ... func buf ] -> [ ... buf ] */
}
-DUK_EXTERNAL void duk_load_function(duk_context *ctx) {
- duk_hthread *thr;
+DUK_EXTERNAL void duk_load_function(duk_hthread *thr) {
duk_uint8_t *p_buf, *p, *p_end;
duk_size_t sz;
- DUK_ASSERT(ctx != NULL);
- thr = (duk_hthread *) ctx;
- DUK_UNREF(ctx);
+ DUK_ASSERT_API_ENTRY(thr);
- p_buf = (duk_uint8_t *) duk_require_buffer(ctx, -1, &sz);
+ p_buf = (duk_uint8_t *) duk_require_buffer(thr, -1, &sz);
DUK_ASSERT(p_buf != NULL);
/* The caller is responsible for being sure that bytecode being loaded
@@ -13665,36 +14064,38 @@ DUK_EXTERNAL void duk_load_function(duk_context *ctx) {
* (instruction validation would be quite complex to implement).
*
* This signature check is the only sanity check for detecting
- * accidental invalid inputs. The initial 0xFF byte ensures no
- * ordinary string will be accepted by accident.
+ * accidental invalid inputs. The initial byte ensures no ordinary
+ * string or Symbol will be accepted by accident.
*/
p = p_buf;
p_end = p_buf + sz;
- if (sz < 2 || p[0] != DUK__SER_MARKER || p[1] != DUK__SER_VERSION) {
+ if (sz < 1 || p[0] != DUK__SER_MARKER) {
goto format_error;
}
- p += 2;
+ p++;
- p = duk__load_func(ctx, p, p_end);
+ p = duk__load_func(thr, p, p_end);
if (p == NULL) {
goto format_error;
}
- duk_remove_m2(ctx); /* [ ... buf func ] -> [ ... func ] */
+ duk_remove_m2(thr); /* [ ... buf func ] -> [ ... func ] */
return;
format_error:
- DUK_ERROR_TYPE(thr, DUK_STR_DECODE_FAILED);
+ DUK_ERROR_TYPE(thr, DUK_STR_INVALID_BYTECODE);
}
#else /* DUK_USE_BYTECODE_DUMP_SUPPORT */
-DUK_EXTERNAL void duk_dump_function(duk_context *ctx) {
- DUK_ERROR_UNSUPPORTED((duk_hthread *) ctx);
+DUK_EXTERNAL void duk_dump_function(duk_hthread *thr) {
+ DUK_ASSERT_API_ENTRY(thr);
+ DUK_ERROR_UNSUPPORTED(thr);
}
-DUK_EXTERNAL void duk_load_function(duk_context *ctx) {
- DUK_ERROR_UNSUPPORTED((duk_hthread *) ctx);
+DUK_EXTERNAL void duk_load_function(duk_hthread *thr) {
+ DUK_ASSERT_API_ENTRY(thr);
+ DUK_ERROR_UNSUPPORTED(thr);
}
#endif /* DUK_USE_BYTECODE_DUMP_SUPPORT */
@@ -13702,228 +14103,324 @@ DUK_EXTERNAL void duk_load_function(duk_context *ctx) {
/* automatic undefs */
#undef DUK__ASSERT_LEFT
#undef DUK__BYTECODE_INITIAL_ALLOC
+#undef DUK__NO_FORMALS
#undef DUK__SER_MARKER
#undef DUK__SER_NUMBER
#undef DUK__SER_STRING
-#undef DUK__SER_VERSION
/*
* Calls.
*
- * Protected variants should avoid ever throwing an error.
+ * Protected variants should avoid ever throwing an error. Must be careful
+ * to catch errors related to value stack manipulation and property lookup,
+ * not just the call itself.
+ *
+ * The only exception is when arguments are insane, e.g. nargs/nrets are out
+ * of bounds; in such cases an error is thrown for two reasons. First, we
+ * can't always respect the value stack input/output guarantees in such cases
+ * so the caller would end up with the value stack in an unexpected state.
+ * Second, an attempt to create an error might itself fail (although this
+ * could be avoided by pushing a preallocated object/string or a primitive
+ * value).
*/
/* #include duk_internal.h -> already included */
+/*
+ * Helpers
+ */
+
+struct duk__pcall_prop_args {
+ duk_idx_t obj_idx;
+ duk_idx_t nargs;
+ duk_small_uint_t call_flags;
+};
+typedef struct duk__pcall_prop_args duk__pcall_prop_args;
+
+struct duk__pcall_method_args {
+ duk_idx_t nargs;
+ duk_small_uint_t call_flags;
+};
+typedef struct duk__pcall_method_args duk__pcall_method_args;
+
+struct duk__pcall_args {
+ duk_idx_t nargs;
+ duk_small_uint_t call_flags;
+};
+typedef struct duk__pcall_args duk__pcall_args;
+
+/* Compute and validate idx_func for a certain 'nargs' and 'other'
+ * parameter count (1 or 2, depending on whether 'this' binding is
+ * present).
+ */
+DUK_LOCAL duk_idx_t duk__call_get_idx_func(duk_hthread *thr, duk_idx_t nargs, duk_idx_t other) {
+ duk_idx_t idx_func;
+
+ /* XXX: byte arithmetic? */
+
+ DUK_ASSERT(other >= 0);
+
+ idx_func = duk_get_top(thr) - nargs - other;
+ if (DUK_UNLIKELY((idx_func | nargs) < 0)) { /* idx_func < 0 || nargs < 0; OR sign bits */
+ DUK_ERROR_TYPE_INVALID_ARGS(thr);
+ /* unreachable */
+ }
+ DUK_ASSERT(duk_is_valid_index(thr, idx_func));
+ return idx_func;
+}
+
+/* Compute idx_func, assume index will be valid. This is a valid assumption
+ * for protected calls: nargs < 0 is checked explicitly and duk_safe_call()
+ * validates the argument count.
+ */
+DUK_LOCAL duk_idx_t duk__call_get_idx_func_unvalidated(duk_hthread *thr, duk_idx_t nargs, duk_idx_t other) {
+ duk_idx_t idx_func;
+
+ /* XXX: byte arithmetic? */
+
+ DUK_ASSERT(nargs >= 0);
+ DUK_ASSERT(other >= 0);
+
+ idx_func = duk_get_top(thr) - nargs - other;
+ DUK_ASSERT(idx_func >= 0);
+ DUK_ASSERT(duk_is_valid_index(thr, idx_func));
+ return idx_func;
+}
+
/* Prepare value stack for a method call through an object property.
* May currently throw an error e.g. when getting the property.
*/
-DUK_LOCAL void duk__call_prop_prep_stack(duk_context *ctx, duk_idx_t normalized_obj_idx, duk_idx_t nargs) {
- DUK_ASSERT_CTX_VALID(ctx);
+DUK_LOCAL void duk__call_prop_prep_stack(duk_hthread *thr, duk_idx_t normalized_obj_idx, duk_idx_t nargs) {
+ DUK_ASSERT_CTX_VALID(thr);
+ DUK_ASSERT(nargs >= 0);
DUK_DDD(DUK_DDDPRINT("duk__call_prop_prep_stack, normalized_obj_idx=%ld, nargs=%ld, stacktop=%ld",
- (long) normalized_obj_idx, (long) nargs, (long) duk_get_top(ctx)));
+ (long) normalized_obj_idx, (long) nargs, (long) duk_get_top(thr)));
/* [... key arg1 ... argN] */
/* duplicate key */
- duk_dup(ctx, -nargs - 1); /* Note: -nargs alone would fail for nargs == 0, this is OK */
- duk_get_prop(ctx, normalized_obj_idx);
+ duk_dup(thr, -nargs - 1); /* Note: -nargs alone would fail for nargs == 0, this is OK */
+ (void) duk_get_prop(thr, normalized_obj_idx);
+
+ DUK_DDD(DUK_DDDPRINT("func: %!T", (duk_tval *) duk_get_tval(thr, -1)));
+
+#if defined(DUK_USE_VERBOSE_ERRORS)
+ if (DUK_UNLIKELY(!duk_is_callable(thr, -1))) {
+ duk_tval *tv_targ;
+ duk_tval *tv_base;
+ duk_tval *tv_key;
- DUK_DDD(DUK_DDDPRINT("func: %!T", (duk_tval *) duk_get_tval(ctx, -1)));
+ tv_targ = DUK_GET_TVAL_NEGIDX(thr, -1);
+ tv_base = DUK_GET_TVAL_POSIDX(thr, normalized_obj_idx);
+ tv_key = DUK_GET_TVAL_NEGIDX(thr, -nargs - 2);
+ DUK_ASSERT(tv_targ >= thr->valstack_bottom && tv_targ < thr->valstack_top);
+ DUK_ASSERT(tv_base >= thr->valstack_bottom && tv_base < thr->valstack_top);
+ DUK_ASSERT(tv_key >= thr->valstack_bottom && tv_key < thr->valstack_top);
+
+ duk_call_setup_propcall_error(thr, tv_targ, tv_base, tv_key);
+ }
+#endif
/* [... key arg1 ... argN func] */
- duk_replace(ctx, -nargs - 2);
+ duk_replace(thr, -nargs - 2);
/* [... func arg1 ... argN] */
- duk_dup(ctx, normalized_obj_idx);
- duk_insert(ctx, -nargs - 1);
+ duk_dup(thr, normalized_obj_idx);
+ duk_insert(thr, -nargs - 1);
/* [... func this arg1 ... argN] */
}
-DUK_EXTERNAL void duk_call(duk_context *ctx, duk_idx_t nargs) {
- duk_hthread *thr = (duk_hthread *) ctx;
+DUK_EXTERNAL void duk_call(duk_hthread *thr, duk_idx_t nargs) {
duk_small_uint_t call_flags;
duk_idx_t idx_func;
- DUK_ASSERT_CTX_VALID(ctx);
- DUK_ASSERT(thr != NULL);
+ DUK_ASSERT_API_ENTRY(thr);
- idx_func = duk_get_top(ctx) - nargs - 1;
- if (idx_func < 0 || nargs < 0) {
- /* note that we can't reliably pop anything here */
- DUK_ERROR_TYPE_INVALID_ARGS(thr);
- }
+ idx_func = duk__call_get_idx_func(thr, nargs, 1);
+ DUK_ASSERT(duk_is_valid_index(thr, idx_func));
- /* XXX: awkward; we assume there is space for this, overwrite
- * directly instead?
- */
- duk_push_undefined(ctx);
- duk_insert(ctx, idx_func + 1);
+ duk_insert_undefined(thr, idx_func + 1);
call_flags = 0; /* not protected, respect reclimit, not constructor */
-
- duk_handle_call_unprotected(thr, /* thread */
- nargs, /* num_stack_args */
- call_flags); /* call_flags */
+ duk_handle_call_unprotected(thr, idx_func, call_flags);
}
-DUK_EXTERNAL void duk_call_method(duk_context *ctx, duk_idx_t nargs) {
- duk_hthread *thr = (duk_hthread *) ctx;
+DUK_EXTERNAL void duk_call_method(duk_hthread *thr, duk_idx_t nargs) {
duk_small_uint_t call_flags;
duk_idx_t idx_func;
- DUK_ASSERT_CTX_VALID(ctx);
- DUK_ASSERT(thr != NULL);
+ DUK_ASSERT_API_ENTRY(thr);
- idx_func = duk_get_top(ctx) - nargs - 2; /* must work for nargs <= 0 */
- if (idx_func < 0 || nargs < 0) {
- /* note that we can't reliably pop anything here */
- DUK_ERROR_TYPE_INVALID_ARGS(thr);
- }
+ idx_func = duk__call_get_idx_func(thr, nargs, 2);
+ DUK_ASSERT(duk_is_valid_index(thr, idx_func));
call_flags = 0; /* not protected, respect reclimit, not constructor */
-
- duk_handle_call_unprotected(thr, /* thread */
- nargs, /* num_stack_args */
- call_flags); /* call_flags */
+ duk_handle_call_unprotected(thr, idx_func, call_flags);
}
-DUK_EXTERNAL void duk_call_prop(duk_context *ctx, duk_idx_t obj_idx, duk_idx_t nargs) {
+DUK_EXTERNAL void duk_call_prop(duk_hthread *thr, duk_idx_t obj_idx, duk_idx_t nargs) {
/*
* XXX: if duk_handle_call() took values through indices, this could be
* made much more sensible. However, duk_handle_call() needs to fudge
- * the 'this' and 'func' values to handle bound function chains, which
- * is now done "in-place", so this is not a trivial change.
+ * the 'this' and 'func' values to handle bound functions, which is now
+ * done "in-place", so this is not a trivial change.
*/
- DUK_ASSERT_CTX_VALID(ctx);
+ DUK_ASSERT_API_ENTRY(thr);
- obj_idx = duk_require_normalize_index(ctx, obj_idx); /* make absolute */
+ obj_idx = duk_require_normalize_index(thr, obj_idx); /* make absolute */
+ if (DUK_UNLIKELY(nargs < 0)) {
+ DUK_ERROR_TYPE_INVALID_ARGS(thr);
+ }
- duk__call_prop_prep_stack(ctx, obj_idx, nargs);
+ duk__call_prop_prep_stack(thr, obj_idx, nargs);
- duk_call_method(ctx, nargs);
+ duk_call_method(thr, nargs);
}
-DUK_EXTERNAL duk_int_t duk_pcall(duk_context *ctx, duk_idx_t nargs) {
- duk_hthread *thr = (duk_hthread *) ctx;
- duk_small_uint_t call_flags;
+DUK_LOCAL duk_ret_t duk__pcall_raw(duk_hthread *thr, void *udata) {
+ duk__pcall_args *args;
duk_idx_t idx_func;
- duk_int_t rc;
+ duk_int_t ret;
- DUK_ASSERT_CTX_VALID(ctx);
- DUK_ASSERT(thr != NULL);
+ DUK_ASSERT_CTX_VALID(thr);
+ DUK_ASSERT(udata != NULL);
- idx_func = duk_get_top(ctx) - nargs - 1; /* must work for nargs <= 0 */
- if (idx_func < 0 || nargs < 0) {
- /* We can't reliably pop anything here because the stack input
- * shape is incorrect. So we throw an error; if the caller has
- * no catch point for this, a fatal error will occur. Another
- * alternative would be to just return an error. But then the
- * stack would be in an unknown state which might cause some
- * very hard to diagnose problems later on. Also note that even
- * if we did not throw an error here, the underlying call handler
- * might STILL throw an out-of-memory error or some other internal
- * fatal error.
- */
+ args = (duk__pcall_args *) udata;
+ idx_func = duk__call_get_idx_func_unvalidated(thr, args->nargs, 1);
+ DUK_ASSERT(duk_is_valid_index(thr, idx_func));
+
+ duk_insert_undefined(thr, idx_func + 1);
+
+ ret = duk_handle_call_unprotected(thr, idx_func, args->call_flags);
+ DUK_ASSERT(ret == 0);
+ DUK_UNREF(ret);
+
+ return 1;
+}
+
+DUK_EXTERNAL duk_int_t duk_pcall(duk_hthread *thr, duk_idx_t nargs) {
+ duk__pcall_args args;
+
+ DUK_ASSERT_API_ENTRY(thr);
+
+ args.nargs = nargs;
+ if (DUK_UNLIKELY(nargs < 0)) {
DUK_ERROR_TYPE_INVALID_ARGS(thr);
return DUK_EXEC_ERROR; /* unreachable */
}
+ args.call_flags = 0;
- /* awkward; we assume there is space for this */
- duk_push_undefined(ctx);
- duk_insert(ctx, idx_func + 1);
+ return duk_safe_call(thr, duk__pcall_raw, (void *) &args /*udata*/, nargs + 1 /*nargs*/, 1 /*nrets*/);
+}
- call_flags = 0; /* respect reclimit, not constructor */
+DUK_LOCAL duk_ret_t duk__pcall_method_raw(duk_hthread *thr, void *udata) {
+ duk__pcall_method_args *args;
+ duk_idx_t idx_func;
+ duk_int_t ret;
- rc = duk_handle_call_protected(thr, /* thread */
- nargs, /* num_stack_args */
- call_flags); /* call_flags */
+ DUK_ASSERT_CTX_VALID(thr);
+ DUK_ASSERT(udata != NULL);
- return rc;
+ args = (duk__pcall_method_args *) udata;
+
+ idx_func = duk__call_get_idx_func_unvalidated(thr, args->nargs, 2);
+ DUK_ASSERT(duk_is_valid_index(thr, idx_func));
+
+ ret = duk_handle_call_unprotected(thr, idx_func, args->call_flags);
+ DUK_ASSERT(ret == 0);
+ DUK_UNREF(ret);
+
+ return 1;
}
-DUK_EXTERNAL duk_int_t duk_pcall_method(duk_context *ctx, duk_idx_t nargs) {
- duk_hthread *thr = (duk_hthread *) ctx;
- duk_small_uint_t call_flags;
- duk_idx_t idx_func;
- duk_int_t rc;
+DUK_INTERNAL duk_int_t duk_pcall_method_flags(duk_hthread *thr, duk_idx_t nargs, duk_small_uint_t call_flags) {
+ duk__pcall_method_args args;
- DUK_ASSERT_CTX_VALID(ctx);
- DUK_ASSERT(thr != NULL);
+ DUK_ASSERT_API_ENTRY(thr);
- idx_func = duk_get_top(ctx) - nargs - 2; /* must work for nargs <= 0 */
- if (idx_func < 0 || nargs < 0) {
- /* See comments in duk_pcall(). */
+ args.nargs = nargs;
+ if (DUK_UNLIKELY(nargs < 0)) {
DUK_ERROR_TYPE_INVALID_ARGS(thr);
return DUK_EXEC_ERROR; /* unreachable */
}
+ args.call_flags = call_flags;
- call_flags = 0; /* respect reclimit, not constructor */
+ return duk_safe_call(thr, duk__pcall_method_raw, (void *) &args /*udata*/, nargs + 2 /*nargs*/, 1 /*nrets*/);
+}
- rc = duk_handle_call_protected(thr, /* thread */
- nargs, /* num_stack_args */
- call_flags); /* call_flags */
+DUK_EXTERNAL duk_int_t duk_pcall_method(duk_hthread *thr, duk_idx_t nargs) {
+ DUK_ASSERT_API_ENTRY(thr);
- return rc;
+ return duk_pcall_method_flags(thr, nargs, 0);
}
-struct duk__pcall_prop_args {
- duk_idx_t obj_idx;
- duk_idx_t nargs;
-};
-typedef struct duk__pcall_prop_args duk__pcall_prop_args;
-
-DUK_LOCAL duk_ret_t duk__pcall_prop_raw(duk_context *ctx, void *udata) {
- duk_idx_t obj_idx;
- duk_idx_t nargs;
+DUK_LOCAL duk_ret_t duk__pcall_prop_raw(duk_hthread *thr, void *udata) {
duk__pcall_prop_args *args;
+ duk_idx_t obj_idx;
+ duk_int_t ret;
- DUK_ASSERT_CTX_VALID(ctx);
+ DUK_ASSERT_CTX_VALID(thr);
DUK_ASSERT(udata != NULL);
args = (duk__pcall_prop_args *) udata;
- obj_idx = args->obj_idx;
- nargs = args->nargs;
- obj_idx = duk_require_normalize_index(ctx, obj_idx); /* make absolute */
- duk__call_prop_prep_stack(ctx, obj_idx, nargs);
- duk_call_method(ctx, nargs);
+ obj_idx = duk_require_normalize_index(thr, args->obj_idx); /* make absolute */
+ duk__call_prop_prep_stack(thr, obj_idx, args->nargs);
+
+ ret = duk_handle_call_unprotected_nargs(thr, args->nargs, args->call_flags);
+ DUK_ASSERT(ret == 0);
+ DUK_UNREF(ret);
return 1;
}
-DUK_EXTERNAL duk_int_t duk_pcall_prop(duk_context *ctx, duk_idx_t obj_idx, duk_idx_t nargs) {
+DUK_EXTERNAL duk_int_t duk_pcall_prop(duk_hthread *thr, duk_idx_t obj_idx, duk_idx_t nargs) {
duk__pcall_prop_args args;
- /*
- * Must be careful to catch errors related to value stack manipulation
- * and property lookup, not just the call itself.
- */
-
- DUK_ASSERT_CTX_VALID(ctx);
+ DUK_ASSERT_API_ENTRY(thr);
args.obj_idx = obj_idx;
args.nargs = nargs;
+ if (DUK_UNLIKELY(nargs < 0)) {
+ DUK_ERROR_TYPE_INVALID_ARGS(thr);
+ return DUK_EXEC_ERROR; /* unreachable */
+ }
+ args.call_flags = 0;
- /* Inputs: explicit arguments (nargs), +1 for key. If the value stack
- * does not contain enough args, an error is thrown; this matches
- * behavior of the other protected call API functions.
- */
- return duk_safe_call(ctx, duk__pcall_prop_raw, (void *) &args /*udata*/, nargs + 1 /*nargs*/, 1 /*nrets*/);
+ return duk_safe_call(thr, duk__pcall_prop_raw, (void *) &args /*udata*/, nargs + 1 /*nargs*/, 1 /*nrets*/);
}
-DUK_EXTERNAL duk_int_t duk_safe_call(duk_context *ctx, duk_safe_call_function func, void *udata, duk_idx_t nargs, duk_idx_t nrets) {
- duk_hthread *thr = (duk_hthread *) ctx;
+DUK_EXTERNAL duk_int_t duk_safe_call(duk_hthread *thr, duk_safe_call_function func, void *udata, duk_idx_t nargs, duk_idx_t nrets) {
duk_int_t rc;
- DUK_ASSERT_CTX_VALID(ctx);
- DUK_ASSERT(thr != NULL);
-
- if (duk_get_top(ctx) < nargs || nrets < 0) {
- /* See comments in duk_pcall(). */
+ DUK_ASSERT_API_ENTRY(thr);
+
+ /* nargs condition; fail if: top - bottom < nargs
+ * <=> top < bottom + nargs
+ * nrets condition; fail if: end - (top - nargs) < nrets
+ * <=> end - top + nargs < nrets
+ * <=> end + nargs < top + nrets
+ */
+ /* XXX: check for any reserve? */
+
+ if (DUK_UNLIKELY((nargs | nrets) < 0 || /* nargs < 0 || nrets < 0; OR sign bits */
+ thr->valstack_top < thr->valstack_bottom + nargs || /* nargs too large compared to top */
+ thr->valstack_end + nargs < thr->valstack_top + nrets)) { /* nrets too large compared to reserve */
+ DUK_D(DUK_DPRINT("not enough stack reserve for safe call or invalid arguments: "
+ "nargs=%ld < 0 (?), nrets=%ld < 0 (?), top=%ld < bottom=%ld + nargs=%ld (?), "
+ "end=%ld + nargs=%ld < top=%ld + nrets=%ld (?)",
+ (long) nargs,
+ (long) nrets,
+ (long) (thr->valstack_top - thr->valstack),
+ (long) (thr->valstack_bottom - thr->valstack),
+ (long) nargs,
+ (long) (thr->valstack_end - thr->valstack),
+ (long) nargs,
+ (long) (thr->valstack_top - thr->valstack),
+ (long) nrets));
DUK_ERROR_TYPE_INVALID_ARGS(thr);
return DUK_EXEC_ERROR; /* unreachable */
}
@@ -13937,248 +14434,53 @@ DUK_EXTERNAL duk_int_t duk_safe_call(duk_context *ctx, duk_safe_call_function fu
return rc;
}
-DUK_EXTERNAL void duk_new(duk_context *ctx, duk_idx_t nargs) {
- /*
- * There are two [[Construct]] operations in the specification:
- *
- * - E5 Section 13.2.2: for Function objects
- * - E5 Section 15.3.4.5.2: for "bound" Function objects
- *
- * The chain of bound functions is resolved in Section 15.3.4.5.2,
- * with arguments "piling up" until the [[Construct]] internal
- * method is called on the final, actual Function object. Note
- * that the "prototype" property is looked up *only* from the
- * final object, *before* calling the constructor.
- *
- * Currently we follow the bound function chain here to get the
- * "prototype" property value from the final, non-bound function.
- * However, we let duk_handle_call() handle the argument "piling"
- * when the constructor is called. The bound function chain is
- * thus now processed twice.
- *
- * When constructing new Array instances, an unnecessary object is
- * created and discarded now: the standard [[Construct]] creates an
- * object, and calls the Array constructor. The Array constructor
- * returns an Array instance, which is used as the result value for
- * the "new" operation; the object created before the Array constructor
- * call is discarded.
- *
- * This would be easy to fix, e.g. by knowing that the Array constructor
- * will always create a replacement object and skip creating the fallback
- * object in that case.
- *
- * Note: functions called via "new" need to know they are called as a
- * constructor. For instance, built-in constructors behave differently
- * depending on how they are called.
- */
-
- /* XXX: merge this with duk_js_call.c, as this function implements
- * core semantics (or perhaps merge the two files altogether).
- */
-
- duk_hthread *thr = (duk_hthread *) ctx;
- duk_hobject *proto;
- duk_hobject *cons;
- duk_hobject *fallback;
- duk_idx_t idx_cons;
- duk_small_uint_t call_flags;
-
- DUK_ASSERT_CTX_VALID(ctx);
-
- /* [... constructor arg1 ... argN] */
-
- idx_cons = duk_require_normalize_index(ctx, -nargs - 1);
-
- DUK_DDD(DUK_DDDPRINT("top=%ld, nargs=%ld, idx_cons=%ld",
- (long) duk_get_top(ctx), (long) nargs, (long) idx_cons));
-
- /* XXX: code duplication */
-
- /*
- * Figure out the final, non-bound constructor, to get "prototype"
- * property.
- */
-
- duk_dup(ctx, idx_cons);
- for (;;) {
- duk_tval *tv;
- tv = DUK_GET_TVAL_NEGIDX(ctx, -1);
- DUK_ASSERT(tv != NULL);
-
- if (DUK_TVAL_IS_OBJECT(tv)) {
- cons = DUK_TVAL_GET_OBJECT(tv);
- DUK_ASSERT(cons != NULL);
- if (!DUK_HOBJECT_IS_CALLABLE(cons) || !DUK_HOBJECT_HAS_CONSTRUCTABLE(cons)) {
- /* Checking callability of the immediate target
- * is important, same for constructability.
- * Checking it for functions down the bound
- * function chain is not strictly necessary
- * because .bind() should normally reject them.
- * But it's good to check anyway because it's
- * technically possible to edit the bound function
- * chain via internal keys.
- */
- goto not_constructable;
- }
- if (!DUK_HOBJECT_HAS_BOUNDFUNC(cons)) {
- break;
- }
- } else if (DUK_TVAL_IS_LIGHTFUNC(tv)) {
- /* Lightfuncs cannot be bound. */
- break;
- } else {
- /* Anything else is not constructable. */
- goto not_constructable;
- }
- duk_get_prop_stridx_short(ctx, -1, DUK_STRIDX_INT_TARGET); /* -> [... cons target] */
- duk_remove_m2(ctx); /* -> [... target] */
- }
- DUK_ASSERT(duk_is_callable(ctx, -1));
- DUK_ASSERT(duk_is_lightfunc(ctx, -1) ||
- (duk_get_hobject(ctx, -1) != NULL && !DUK_HOBJECT_HAS_BOUNDFUNC(duk_get_hobject(ctx, -1))));
-
- /* [... constructor arg1 ... argN final_cons] */
-
- /*
- * Create "fallback" object to be used as the object instance,
- * unless the constructor returns a replacement value.
- * Its internal prototype needs to be set based on "prototype"
- * property of the constructor.
- */
-
- duk_push_object(ctx); /* class Object, extensible */
-
- /* [... constructor arg1 ... argN final_cons fallback] */
-
- duk_get_prop_stridx_short(ctx, -2, DUK_STRIDX_PROTOTYPE);
- proto = duk_get_hobject(ctx, -1);
- if (!proto) {
- DUK_DDD(DUK_DDDPRINT("constructor has no 'prototype' property, or value not an object "
- "-> leave standard Object prototype as fallback prototype"));
- } else {
- DUK_DDD(DUK_DDDPRINT("constructor has 'prototype' property with object value "
- "-> set fallback prototype to that value: %!iO", (duk_heaphdr *) proto));
- fallback = duk_get_hobject(ctx, -2);
- DUK_ASSERT(fallback != NULL);
- DUK_HOBJECT_SET_PROTOTYPE_UPDREF(thr, fallback, proto);
- }
- duk_pop(ctx);
-
- /* [... constructor arg1 ... argN final_cons fallback] */
-
- /*
- * Manipulate callstack for the call.
- */
-
- duk_dup_top(ctx);
- duk_insert(ctx, idx_cons + 1); /* use fallback as 'this' value */
- duk_insert(ctx, idx_cons); /* also stash it before constructor,
- * in case we need it (as the fallback value)
- */
- duk_pop(ctx); /* pop final_cons */
-
-
- /* [... fallback constructor fallback(this) arg1 ... argN];
- * Note: idx_cons points to first 'fallback', not 'constructor'.
- */
-
- DUK_DDD(DUK_DDDPRINT("before call, idx_cons+1 (constructor) -> %!T, idx_cons+2 (fallback/this) -> %!T, "
- "nargs=%ld, top=%ld",
- (duk_tval *) duk_get_tval(ctx, idx_cons + 1),
- (duk_tval *) duk_get_tval(ctx, idx_cons + 2),
- (long) nargs,
- (long) duk_get_top(ctx)));
-
- /*
- * Call the constructor function (called in "constructor mode").
- */
-
- call_flags = DUK_CALL_FLAG_CONSTRUCTOR_CALL; /* not protected, respect reclimit, is a constructor call */
-
- duk_handle_call_unprotected(thr, /* thread */
- nargs, /* num_stack_args */
- call_flags); /* call_flags */
-
- /* [... fallback retval] */
-
- DUK_DDD(DUK_DDDPRINT("constructor call finished, fallback=%!iT, retval=%!iT",
- (duk_tval *) duk_get_tval(ctx, -2),
- (duk_tval *) duk_get_tval(ctx, -1)));
-
- /*
- * Determine whether to use the constructor return value as the created
- * object instance or not.
- */
-
- if (duk_check_type_mask(ctx, -1, DUK_TYPE_MASK_OBJECT |
- DUK_TYPE_MASK_BUFFER |
- DUK_TYPE_MASK_LIGHTFUNC)) {
- duk_remove_m2(ctx);
- } else {
- duk_pop(ctx);
- }
+DUK_EXTERNAL void duk_new(duk_hthread *thr, duk_idx_t nargs) {
+ duk_idx_t idx_func;
- /*
- * Augment created errors upon creation (not when they are thrown or
- * rethrown). __FILE__ and __LINE__ are not desirable here; the call
- * stack reflects the caller which is correct.
- */
+ DUK_ASSERT_API_ENTRY(thr);
-#if defined(DUK_USE_AUGMENT_ERROR_CREATE)
- duk_hthread_sync_currpc(thr);
- duk_err_augment_error_create(thr, thr, NULL, 0, 1 /*noblame_fileline*/);
-#endif
+ idx_func = duk__call_get_idx_func(thr, nargs, 1);
+ DUK_ASSERT(duk_is_valid_index(thr, idx_func));
- /* [... retval] */
+ duk_push_object(thr); /* default instance; internal proto updated by call handling */
+ duk_insert(thr, idx_func + 1);
- return;
-
- not_constructable:
-#if defined(DUK_USE_VERBOSE_ERRORS)
-#if defined(DUK_USE_PARANOID_ERRORS)
- DUK_ERROR_FMT1(thr, DUK_ERR_TYPE_ERROR, "%s not constructable", duk_get_type_name(ctx, -1));
-#else
- DUK_ERROR_FMT1(thr, DUK_ERR_TYPE_ERROR, "%s not constructable", duk_push_string_readable(ctx, -1));
-#endif
-#else
- DUK_ERROR_TYPE(thr, "not constructable");
-#endif
+ duk_handle_call_unprotected(thr, idx_func, DUK_CALL_FLAG_CONSTRUCT);
}
-DUK_LOCAL duk_ret_t duk__pnew_helper(duk_context *ctx, void *udata) {
+DUK_LOCAL duk_ret_t duk__pnew_helper(duk_hthread *thr, void *udata) {
duk_idx_t nargs;
DUK_ASSERT(udata != NULL);
nargs = *((duk_idx_t *) udata);
- duk_new(ctx, nargs);
+ duk_new(thr, nargs);
return 1;
}
-DUK_EXTERNAL duk_int_t duk_pnew(duk_context *ctx, duk_idx_t nargs) {
+DUK_EXTERNAL duk_int_t duk_pnew(duk_hthread *thr, duk_idx_t nargs) {
duk_int_t rc;
- DUK_ASSERT_CTX_VALID(ctx);
+ DUK_ASSERT_API_ENTRY(thr);
/* 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.
+ * simply use a protected duk_handle_call() because pushing the
+ * default instance might throw.
*/
- rc = duk_safe_call(ctx, duk__pnew_helper, (void *) &nargs /*udata*/, nargs + 1 /*nargs*/, 1 /*nrets*/);
+ if (DUK_UNLIKELY(nargs < 0)) {
+ DUK_ERROR_TYPE_INVALID_ARGS(thr);
+ return DUK_EXEC_ERROR; /* unreachable */
+ }
+
+ rc = duk_safe_call(thr, duk__pnew_helper, (void *) &nargs /*udata*/, nargs + 1 /*nargs*/, 1 /*nrets*/);
return rc;
}
-DUK_EXTERNAL duk_bool_t duk_is_constructor_call(duk_context *ctx) {
- duk_hthread *thr = (duk_hthread *) ctx;
+DUK_EXTERNAL duk_bool_t duk_is_constructor_call(duk_hthread *thr) {
duk_activation *act;
- DUK_ASSERT_CTX_VALID(ctx);
- DUK_ASSERT(thr != NULL);
- DUK_ASSERT_DISABLE(thr->callstack_top >= 0);
+ DUK_ASSERT_API_ENTRY(thr);
act = thr->callstack_curr;
if (act != NULL) {
@@ -14190,14 +14492,15 @@ DUK_EXTERNAL duk_bool_t duk_is_constructor_call(duk_context *ctx) {
/* XXX: Make this obsolete by adding a function flag for rejecting a
* non-constructor call automatically?
*/
-DUK_INTERNAL void duk_require_constructor_call(duk_context *ctx) {
- if (!duk_is_constructor_call(ctx)) {
- DUK_ERROR_TYPE((duk_hthread *) ctx, DUK_STR_CONSTRUCT_ONLY);
+DUK_INTERNAL void duk_require_constructor_call(duk_hthread *thr) {
+ DUK_ASSERT_API_ENTRY(thr);
+
+ if (!duk_is_constructor_call(thr)) {
+ DUK_ERROR_TYPE(thr, DUK_STR_CONSTRUCT_ONLY);
}
}
-DUK_EXTERNAL duk_bool_t duk_is_strict_call(duk_context *ctx) {
- duk_hthread *thr = (duk_hthread *) ctx;
+DUK_EXTERNAL duk_bool_t duk_is_strict_call(duk_hthread *thr) {
duk_activation *act;
/* For user code this could just return 1 (strict) always
@@ -14209,9 +14512,7 @@ DUK_EXTERNAL duk_bool_t duk_is_strict_call(duk_context *ctx) {
* the internal call sites.
*/
- DUK_ASSERT_CTX_VALID(ctx);
- DUK_ASSERT(thr != NULL);
- DUK_ASSERT_DISABLE(thr->callstack_top >= 0);
+ DUK_ASSERT_API_ENTRY(thr);
act = thr->callstack_curr;
if (act != NULL) {
@@ -14226,14 +14527,11 @@ DUK_EXTERNAL duk_bool_t duk_is_strict_call(duk_context *ctx) {
* Duktape/C function magic
*/
-DUK_EXTERNAL duk_int_t duk_get_current_magic(duk_context *ctx) {
- duk_hthread *thr = (duk_hthread *) ctx;
+DUK_EXTERNAL duk_int_t duk_get_current_magic(duk_hthread *thr) {
duk_activation *act;
duk_hobject *func;
- DUK_ASSERT_CTX_VALID(ctx);
- DUK_ASSERT(thr != NULL);
- DUK_ASSERT_DISABLE(thr->callstack_top >= 0);
+ DUK_ASSERT_API_ENTRY(thr);
act = thr->callstack_curr;
if (act) {
@@ -14254,14 +14552,13 @@ DUK_EXTERNAL duk_int_t duk_get_current_magic(duk_context *ctx) {
return 0;
}
-DUK_EXTERNAL duk_int_t duk_get_magic(duk_context *ctx, duk_idx_t idx) {
- duk_hthread *thr = (duk_hthread *) ctx;
+DUK_EXTERNAL duk_int_t duk_get_magic(duk_hthread *thr, duk_idx_t idx) {
duk_tval *tv;
duk_hobject *h;
- DUK_ASSERT_CTX_VALID(ctx);
+ DUK_ASSERT_API_ENTRY(thr);
- tv = duk_require_tval(ctx, idx);
+ tv = duk_require_tval(thr, idx);
if (DUK_TVAL_IS_OBJECT(tv)) {
h = DUK_TVAL_GET_OBJECT(tv);
DUK_ASSERT(h != NULL);
@@ -14280,12 +14577,12 @@ DUK_EXTERNAL duk_int_t duk_get_magic(duk_context *ctx, duk_idx_t idx) {
return 0;
}
-DUK_EXTERNAL void duk_set_magic(duk_context *ctx, duk_idx_t idx, duk_int_t magic) {
+DUK_EXTERNAL void duk_set_magic(duk_hthread *thr, duk_idx_t idx, duk_int_t magic) {
duk_hnatfunc *nf;
- DUK_ASSERT_CTX_VALID(ctx);
+ DUK_ASSERT_API_ENTRY(thr);
- nf = duk_require_hnatfunc(ctx, idx);
+ nf = duk_require_hnatfunc(thr, idx);
DUK_ASSERT(nf != NULL);
nf->magic = (duk_int16_t) magic;
}
@@ -14294,30 +14591,40 @@ DUK_EXTERNAL void duk_set_magic(duk_context *ctx, duk_idx_t idx, duk_int_t magic
* Misc helpers
*/
-DUK_INTERNAL void duk_resolve_nonbound_function(duk_context *ctx) {
- duk_uint_t sanity;
+/* Resolve a bound function on value stack top to a non-bound target
+ * (leave other values as is).
+ */
+DUK_INTERNAL void duk_resolve_nonbound_function(duk_hthread *thr) {
duk_tval *tv;
- sanity = DUK_HOBJECT_BOUND_CHAIN_SANITY;
- do {
- tv = DUK_GET_TVAL_NEGIDX(ctx, -1);
- if (DUK_TVAL_IS_LIGHTFUNC(tv)) {
- /* Lightweight function: never bound, so terminate. */
- break;
- } else if (DUK_TVAL_IS_OBJECT(tv)) {
- duk_hobject *func;
+ DUK_ASSERT_HTHREAD_VALID(thr);
- func = DUK_TVAL_GET_OBJECT(tv);
- DUK_ASSERT(func != NULL);
- if (!DUK_HOBJECT_IS_CALLABLE(func) || !DUK_HOBJECT_HAS_BOUNDFUNC(func)) {
- break;
- }
- duk_get_prop_stridx_short(ctx, -1, DUK_STRIDX_INT_TARGET);
- duk_replace(ctx, -2);
- } else {
- break;
+ tv = DUK_GET_TVAL_NEGIDX(thr, -1);
+ if (DUK_TVAL_IS_OBJECT(tv)) {
+ duk_hobject *h;
+
+ h = DUK_TVAL_GET_OBJECT(tv);
+ DUK_ASSERT(h != NULL);
+ if (DUK_HOBJECT_HAS_BOUNDFUNC(h)) {
+ duk_push_tval(thr, &((duk_hboundfunc *) h)->target);
+ duk_replace(thr, -2);
+#if 0
+ DUK_TVAL_SET_TVAL(tv, &((duk_hboundfunc *) h)->target);
+ DUK_TVAL_INCREF(thr, tv);
+ DUK_HOBJECT_DECREF_NORZ(thr, h);
+#endif
+ /* Rely on Function.prototype.bind() on never creating a bound
+ * function whose target is not proper. This is now safe
+ * because the target is not even an internal property but a
+ * struct member.
+ */
+ DUK_ASSERT(duk_is_lightfunc(thr, -1) || duk_is_callable(thr, -1));
}
- } while (--sanity > 0);
+ }
+
+ /* Lightfuncs cannot be bound but are always callable and
+ * constructable.
+ */
}
/*
* Encoding and decoding basic formats: hex, base64.
@@ -14333,21 +14640,21 @@ DUK_INTERNAL void duk_resolve_nonbound_function(duk_context *ctx) {
* buffer and string values because they're the most common. In particular,
* avoid creating a temporary string or buffer when possible.
*/
-DUK_LOCAL const duk_uint8_t *duk__prep_codec_arg(duk_context *ctx, duk_idx_t idx, duk_size_t *out_len) {
+DUK_LOCAL const duk_uint8_t *duk__prep_codec_arg(duk_hthread *thr, duk_idx_t idx, duk_size_t *out_len) {
void *ptr;
duk_bool_t isbuffer;
- DUK_ASSERT(duk_is_valid_index(ctx, idx)); /* checked by caller */
+ DUK_ASSERT(duk_is_valid_index(thr, idx)); /* checked by caller */
/* XXX: with def_ptr set to a stack related pointer, isbuffer could
* be removed from the helper?
*/
- ptr = duk_get_buffer_data_raw(ctx, idx, out_len, NULL /*def_ptr*/, 0 /*def_size*/, 0 /*throw_flag*/, &isbuffer);
+ ptr = duk_get_buffer_data_raw(thr, idx, out_len, NULL /*def_ptr*/, 0 /*def_size*/, 0 /*throw_flag*/, &isbuffer);
if (isbuffer) {
DUK_ASSERT(*out_len == 0 || ptr != NULL);
return (const duk_uint8_t *) ptr;
}
- return (const duk_uint8_t *) duk_to_lstring(ctx, idx, out_len);
+ return (const duk_uint8_t *) duk_to_lstring(thr, idx, out_len);
}
#if defined(DUK_USE_BASE64_FASTPATH)
@@ -14696,22 +15003,21 @@ DUK_LOCAL duk_bool_t duk__base64_decode_helper(const duk_uint8_t *src, duk_size_
}
#endif /* DUK_USE_BASE64_FASTPATH */
-DUK_EXTERNAL const char *duk_base64_encode(duk_context *ctx, duk_idx_t idx) {
- duk_hthread *thr = (duk_hthread *) ctx;
+DUK_EXTERNAL const char *duk_base64_encode(duk_hthread *thr, duk_idx_t idx) {
const duk_uint8_t *src;
duk_size_t srclen;
duk_size_t dstlen;
duk_uint8_t *dst;
const char *ret;
- DUK_ASSERT_CTX_VALID(ctx);
+ DUK_ASSERT_API_ENTRY(thr);
/* XXX: optimize for string inputs: no need to coerce to a buffer
* which makes a copy of the input.
*/
- idx = duk_require_normalize_index(ctx, idx);
- src = duk__prep_codec_arg(ctx, idx, &srclen);
+ idx = duk_require_normalize_index(thr, idx);
+ src = duk__prep_codec_arg(thr, idx, &srclen);
/* Note: for srclen=0, src may be NULL */
/* Computation must not wrap; this limit works for 32-bit size_t:
@@ -14723,21 +15029,20 @@ DUK_EXTERNAL const char *duk_base64_encode(duk_context *ctx, duk_idx_t idx) {
goto type_error;
}
dstlen = (srclen + 2) / 3 * 4;
- dst = (duk_uint8_t *) duk_push_fixed_buffer_nozero(ctx, dstlen);
+ dst = (duk_uint8_t *) duk_push_fixed_buffer_nozero(thr, dstlen);
duk__base64_encode_helper((const duk_uint8_t *) src, srclen, dst);
- ret = duk_buffer_to_string(ctx, -1); /* Safe, result is ASCII. */
- duk_replace(ctx, idx);
+ ret = duk_buffer_to_string(thr, -1); /* Safe, result is ASCII. */
+ duk_replace(thr, idx);
return ret;
type_error:
- DUK_ERROR_TYPE(thr, DUK_STR_ENCODE_FAILED);
+ DUK_ERROR_TYPE(thr, DUK_STR_BASE64_ENCODE_FAILED);
return NULL; /* never here */
}
-DUK_EXTERNAL void duk_base64_decode(duk_context *ctx, duk_idx_t idx) {
- duk_hthread *thr = (duk_hthread *) ctx;
+DUK_EXTERNAL void duk_base64_decode(duk_hthread *thr, duk_idx_t idx) {
const duk_uint8_t *src;
duk_size_t srclen;
duk_size_t dstlen;
@@ -14745,14 +15050,14 @@ DUK_EXTERNAL void duk_base64_decode(duk_context *ctx, duk_idx_t idx) {
duk_uint8_t *dst_final;
duk_bool_t retval;
- DUK_ASSERT_CTX_VALID(ctx);
+ DUK_ASSERT_API_ENTRY(thr);
/* XXX: optimize for buffer inputs: no need to coerce to a string
* which causes an unnecessary interning.
*/
- idx = duk_require_normalize_index(ctx, idx);
- src = duk__prep_codec_arg(ctx, idx, &srclen);
+ idx = duk_require_normalize_index(thr, idx);
+ src = duk__prep_codec_arg(thr, idx, &srclen);
/* Computation must not wrap, only srclen + 3 is at risk of
* wrapping because after that the number gets smaller.
@@ -14763,7 +15068,7 @@ DUK_EXTERNAL void duk_base64_decode(duk_context *ctx, duk_idx_t idx) {
goto type_error;
}
dstlen = (srclen + 3) / 4 * 3; /* upper limit, assuming no whitespace etc */
- dst = (duk_uint8_t *) duk_push_dynamic_buffer(ctx, dstlen);
+ dst = (duk_uint8_t *) duk_push_dynamic_buffer(thr, dstlen);
/* Note: for dstlen=0, dst may be NULL */
retval = duk__base64_decode_helper((const duk_uint8_t *) src, srclen, dst, &dst_final);
@@ -14772,15 +15077,15 @@ DUK_EXTERNAL void duk_base64_decode(duk_context *ctx, duk_idx_t idx) {
}
/* XXX: convert to fixed buffer? */
- (void) duk_resize_buffer(ctx, -1, (duk_size_t) (dst_final - dst));
- duk_replace(ctx, idx);
+ (void) duk_resize_buffer(thr, -1, (duk_size_t) (dst_final - dst));
+ duk_replace(thr, idx);
return;
type_error:
- DUK_ERROR_TYPE(thr, DUK_STR_DECODE_FAILED);
+ DUK_ERROR_TYPE(thr, DUK_STR_BASE64_DECODE_FAILED);
}
-DUK_EXTERNAL const char *duk_hex_encode(duk_context *ctx, duk_idx_t idx) {
+DUK_EXTERNAL const char *duk_hex_encode(duk_hthread *thr, duk_idx_t idx) {
const duk_uint8_t *inp;
duk_size_t len;
duk_size_t i;
@@ -14791,14 +15096,14 @@ DUK_EXTERNAL const char *duk_hex_encode(duk_context *ctx, duk_idx_t idx) {
duk_uint16_t *p16;
#endif
- DUK_ASSERT_CTX_VALID(ctx);
+ DUK_ASSERT_API_ENTRY(thr);
- idx = duk_require_normalize_index(ctx, idx);
- inp = duk__prep_codec_arg(ctx, idx, &len);
+ idx = duk_require_normalize_index(thr, idx);
+ inp = duk__prep_codec_arg(thr, idx, &len);
DUK_ASSERT(inp != NULL || len == 0);
/* Fixed buffer, no zeroing because we'll fill all the data. */
- buf = (duk_uint8_t *) duk_push_fixed_buffer_nozero(ctx, len * 2);
+ buf = (duk_uint8_t *) duk_push_fixed_buffer_nozero(thr, len * 2);
DUK_ASSERT(buf != NULL);
#if defined(DUK_USE_HEX_FASTPATH)
@@ -14831,13 +15136,12 @@ DUK_EXTERNAL const char *duk_hex_encode(duk_context *ctx, duk_idx_t idx) {
* caller coerce to string if necessary?
*/
- ret = duk_buffer_to_string(ctx, -1); /* Safe, result is ASCII. */
- duk_replace(ctx, idx);
+ ret = duk_buffer_to_string(thr, -1); /* Safe, result is ASCII. */
+ duk_replace(thr, idx);
return ret;
}
-DUK_EXTERNAL void duk_hex_decode(duk_context *ctx, duk_idx_t idx) {
- duk_hthread *thr = (duk_hthread *) ctx;
+DUK_EXTERNAL void duk_hex_decode(duk_hthread *thr, duk_idx_t idx) {
const duk_uint8_t *inp;
duk_size_t len;
duk_size_t i;
@@ -14849,10 +15153,10 @@ DUK_EXTERNAL void duk_hex_decode(duk_context *ctx, duk_idx_t idx) {
duk_size_t len_safe;
#endif
- DUK_ASSERT_CTX_VALID(ctx);
+ DUK_ASSERT_API_ENTRY(thr);
- idx = duk_require_normalize_index(ctx, idx);
- inp = duk__prep_codec_arg(ctx, idx, &len);
+ idx = duk_require_normalize_index(thr, idx);
+ inp = duk__prep_codec_arg(thr, idx, &len);
DUK_ASSERT(inp != NULL || len == 0);
if (len & 0x01) {
@@ -14860,7 +15164,7 @@ DUK_EXTERNAL void duk_hex_decode(duk_context *ctx, duk_idx_t idx) {
}
/* Fixed buffer, no zeroing because we'll fill all the data. */
- buf = (duk_uint8_t *) duk_push_fixed_buffer_nozero(ctx, len / 2);
+ buf = (duk_uint8_t *) duk_push_fixed_buffer_nozero(thr, len / 2);
DUK_ASSERT(buf != NULL);
#if defined(DUK_USE_HEX_FASTPATH)
@@ -14913,68 +15217,70 @@ DUK_EXTERNAL void duk_hex_decode(duk_context *ctx, duk_idx_t idx) {
}
#endif /* DUK_USE_HEX_FASTPATH */
- duk_replace(ctx, idx);
+ duk_replace(thr, idx);
return;
type_error:
- DUK_ERROR_TYPE(thr, DUK_STR_DECODE_FAILED);
+ DUK_ERROR_TYPE(thr, DUK_STR_HEX_DECODE_FAILED);
}
#if defined(DUK_USE_JSON_SUPPORT)
-DUK_EXTERNAL const char *duk_json_encode(duk_context *ctx, duk_idx_t idx) {
+DUK_EXTERNAL const char *duk_json_encode(duk_hthread *thr, duk_idx_t idx) {
#if defined(DUK_USE_ASSERTIONS)
duk_idx_t top_at_entry;
#endif
const char *ret;
- DUK_ASSERT_CTX_VALID(ctx);
+ DUK_ASSERT_API_ENTRY(thr);
#if defined(DUK_USE_ASSERTIONS)
- top_at_entry = duk_get_top(ctx);
+ top_at_entry = duk_get_top(thr);
#endif
- idx = duk_require_normalize_index(ctx, idx);
- duk_bi_json_stringify_helper(ctx,
+ idx = duk_require_normalize_index(thr, idx);
+ duk_bi_json_stringify_helper(thr,
idx /*idx_value*/,
DUK_INVALID_INDEX /*idx_replacer*/,
DUK_INVALID_INDEX /*idx_space*/,
0 /*flags*/);
- DUK_ASSERT(duk_is_string(ctx, -1));
- duk_replace(ctx, idx);
- ret = duk_get_string(ctx, idx);
+ DUK_ASSERT(duk_is_string(thr, -1));
+ duk_replace(thr, idx);
+ ret = duk_get_string(thr, idx);
- DUK_ASSERT(duk_get_top(ctx) == top_at_entry);
+ DUK_ASSERT(duk_get_top(thr) == top_at_entry);
return ret;
}
-DUK_EXTERNAL void duk_json_decode(duk_context *ctx, duk_idx_t idx) {
+DUK_EXTERNAL void duk_json_decode(duk_hthread *thr, duk_idx_t idx) {
#if defined(DUK_USE_ASSERTIONS)
duk_idx_t top_at_entry;
#endif
- DUK_ASSERT_CTX_VALID(ctx);
+ DUK_ASSERT_API_ENTRY(thr);
#if defined(DUK_USE_ASSERTIONS)
- top_at_entry = duk_get_top(ctx);
+ top_at_entry = duk_get_top(thr);
#endif
- idx = duk_require_normalize_index(ctx, idx);
- duk_bi_json_parse_helper(ctx,
+ idx = duk_require_normalize_index(thr, idx);
+ duk_bi_json_parse_helper(thr,
idx /*idx_value*/,
DUK_INVALID_INDEX /*idx_reviver*/,
0 /*flags*/);
- duk_replace(ctx, idx);
+ duk_replace(thr, idx);
- DUK_ASSERT(duk_get_top(ctx) == top_at_entry);
+ DUK_ASSERT(duk_get_top(thr) == top_at_entry);
}
#else /* DUK_USE_JSON_SUPPORT */
-DUK_EXTERNAL const char *duk_json_encode(duk_context *ctx, duk_idx_t idx) {
+DUK_EXTERNAL const char *duk_json_encode(duk_hthread *thr, duk_idx_t idx) {
+ DUK_ASSERT_API_ENTRY(thr);
DUK_UNREF(idx);
- DUK_ERROR_UNSUPPORTED((duk_hthread *) ctx);
+ DUK_ERROR_UNSUPPORTED(thr);
}
-DUK_EXTERNAL void duk_json_decode(duk_context *ctx, duk_idx_t idx) {
+DUK_EXTERNAL void duk_json_decode(duk_hthread *thr, duk_idx_t idx) {
+ DUK_ASSERT_API_ENTRY(thr);
DUK_UNREF(idx);
- DUK_ERROR_UNSUPPORTED((duk_hthread *) ctx);
+ DUK_ERROR_UNSUPPORTED(thr);
}
#endif /* DUK_USE_JSON_SUPPORT */
/*
@@ -14991,10 +15297,10 @@ struct duk__compile_raw_args {
};
/* Eval is just a wrapper now. */
-DUK_EXTERNAL duk_int_t duk_eval_raw(duk_context *ctx, const char *src_buffer, duk_size_t src_length, duk_uint_t flags) {
+DUK_EXTERNAL duk_int_t duk_eval_raw(duk_hthread *thr, const char *src_buffer, duk_size_t src_length, duk_uint_t flags) {
duk_int_t rc;
- DUK_ASSERT_CTX_VALID(ctx);
+ DUK_ASSERT_API_ENTRY(thr);
/* Note: strictness is *not* inherited from the current Duktape/C.
* This would be confusing because the current strictness state
@@ -15005,7 +15311,7 @@ DUK_EXTERNAL duk_int_t duk_eval_raw(duk_context *ctx, const char *src_buffer, du
/* [ ... source? filename? ] (depends on flags) */
- rc = duk_compile_raw(ctx, src_buffer, src_length, flags | DUK_COMPILE_EVAL); /* may be safe, or non-safe depending on flags */
+ rc = duk_compile_raw(thr, src_buffer, src_length, flags | DUK_COMPILE_EVAL); /* may be safe, or non-safe depending on flags */
/* [ ... closure/error ] */
@@ -15014,12 +15320,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 */
+ duk_push_global_object(thr); /* explicit 'this' binding, see GH-164 */
if (flags & DUK_COMPILE_SAFE) {
- rc = duk_pcall_method(ctx, 0);
+ rc = duk_pcall_method(thr, 0);
} else {
- duk_call_method(ctx, 0);
+ duk_call_method(thr, 0);
rc = DUK_EXEC_SUCCESS;
}
@@ -15027,20 +15333,19 @@ DUK_EXTERNAL duk_int_t duk_eval_raw(duk_context *ctx, const char *src_buffer, du
got_rc:
if (flags & DUK_COMPILE_NORESULT) {
- duk_pop(ctx);
+ duk_pop(thr);
}
return rc;
}
/* Helper which can be called both directly and with duk_safe_call(). */
-DUK_LOCAL duk_ret_t duk__do_compile(duk_context *ctx, void *udata) {
- duk_hthread *thr = (duk_hthread *) ctx;
+DUK_LOCAL duk_ret_t duk__do_compile(duk_hthread *thr, void *udata) {
duk__compile_raw_args *comp_args;
duk_uint_t flags;
duk_hcompfunc *h_templ;
- DUK_ASSERT_CTX_VALID(ctx);
+ DUK_ASSERT_CTX_VALID(thr);
DUK_ASSERT(udata != NULL);
/* Note: strictness is not inherited from the current Duktape/C
@@ -15057,7 +15362,7 @@ DUK_LOCAL duk_ret_t duk__do_compile(duk_context *ctx, void *udata) {
if (flags & DUK_COMPILE_NOFILENAME) {
/* Automatic filename: 'eval' or 'input'. */
- duk_push_hstring_stridx(ctx, (flags & DUK_COMPILE_EVAL) ? DUK_STRIDX_EVAL : DUK_STRIDX_INPUT);
+ duk_push_hstring_stridx(thr, (flags & DUK_COMPILE_EVAL) ? DUK_STRIDX_EVAL : DUK_STRIDX_INPUT);
}
/* [ ... source? filename ] */
@@ -15065,7 +15370,7 @@ DUK_LOCAL duk_ret_t duk__do_compile(duk_context *ctx, void *udata) {
if (!comp_args->src_buffer) {
duk_hstring *h_sourcecode;
- h_sourcecode = duk_get_hstring(ctx, -2);
+ h_sourcecode = duk_get_hstring(thr, -2);
if ((flags & DUK_COMPILE_NOSOURCE) || /* args incorrect */
(h_sourcecode == NULL)) { /* e.g. duk_push_string_file_raw() pushed undefined */
DUK_ERROR_TYPE(thr, DUK_STR_NO_SOURCECODE);
@@ -15089,29 +15394,29 @@ DUK_LOCAL duk_ret_t duk__do_compile(duk_context *ctx, void *udata) {
if (flags & DUK_COMPILE_NOSOURCE) {
;
} else {
- duk_remove_m2(ctx);
+ duk_remove_m2(thr);
}
/* [ ... func_template ] */
- h_templ = (duk_hcompfunc *) duk_known_hobject(ctx, -1);
+ h_templ = (duk_hcompfunc *) duk_known_hobject(thr, -1);
duk_js_push_closure(thr,
h_templ,
thr->builtins[DUK_BIDX_GLOBAL_ENV],
thr->builtins[DUK_BIDX_GLOBAL_ENV],
1 /*add_auto_proto*/);
- duk_remove_m2(ctx); /* -> [ ... closure ] */
+ duk_remove_m2(thr); /* -> [ ... closure ] */
/* [ ... closure ] */
return 1;
}
-DUK_EXTERNAL duk_int_t duk_compile_raw(duk_context *ctx, const char *src_buffer, duk_size_t src_length, duk_uint_t flags) {
+DUK_EXTERNAL duk_int_t duk_compile_raw(duk_hthread *thr, const char *src_buffer, duk_size_t src_length, duk_uint_t flags) {
duk__compile_raw_args comp_args_alloc;
duk__compile_raw_args *comp_args = &comp_args_alloc;
- DUK_ASSERT_CTX_VALID(ctx);
+ DUK_ASSERT_API_ENTRY(thr);
if ((flags & DUK_COMPILE_STRLEN) && (src_buffer != NULL)) {
/* String length is computed here to avoid multiple evaluation
@@ -15138,13 +15443,13 @@ DUK_EXTERNAL duk_int_t duk_compile_raw(duk_context *ctx, const char *src_buffer,
nargs = flags & 0x07;
DUK_ASSERT(nargs == ((flags & DUK_COMPILE_NOSOURCE) ? 0 : 1) +
((flags & DUK_COMPILE_NOFILENAME) ? 0 : 1));
- rc = duk_safe_call(ctx, duk__do_compile, (void *) comp_args, nargs, nrets);
+ rc = duk_safe_call(thr, duk__do_compile, (void *) comp_args, nargs, nrets);
/* [ ... closure ] */
return rc;
}
- (void) duk__do_compile(ctx, (void *) comp_args);
+ (void) duk__do_compile(thr, (void *) comp_args);
/* [ ... closure ] */
return DUK_EXEC_SUCCESS;
@@ -15156,48 +15461,49 @@ DUK_EXTERNAL duk_int_t duk_compile_raw(duk_context *ctx, const char *src_buffer,
/* #include duk_internal.h -> already included */
#if defined(DUK_USE_JSON_SUPPORT)
-DUK_EXTERNAL void duk_push_context_dump(duk_context *ctx) {
+DUK_EXTERNAL void duk_push_context_dump(duk_hthread *thr) {
duk_idx_t idx;
duk_idx_t top;
- DUK_ASSERT_CTX_VALID(ctx);
+ DUK_ASSERT_API_ENTRY(thr);
/* We don't duk_require_stack() here now, but rely on the caller having
* enough space.
*/
- top = duk_get_top(ctx);
- duk_push_array(ctx);
+ top = duk_get_top(thr);
+ duk_push_array(thr);
for (idx = 0; idx < top; idx++) {
- duk_dup(ctx, idx);
- duk_put_prop_index(ctx, -2, idx);
+ duk_dup(thr, idx);
+ duk_put_prop_index(thr, -2, (duk_uarridx_t) idx);
}
/* XXX: conversion errors should not propagate outwards.
* Perhaps values need to be coerced individually?
*/
- duk_bi_json_stringify_helper(ctx,
- duk_get_top_index(ctx), /*idx_value*/
+ duk_bi_json_stringify_helper(thr,
+ duk_get_top_index(thr), /*idx_value*/
DUK_INVALID_INDEX, /*idx_replacer*/
DUK_INVALID_INDEX, /*idx_space*/
DUK_JSON_FLAG_EXT_CUSTOM |
DUK_JSON_FLAG_ASCII_ONLY |
DUK_JSON_FLAG_AVOID_KEY_QUOTES /*flags*/);
- duk_push_sprintf(ctx, "ctx: top=%ld, stack=%s", (long) top, (const char *) duk_safe_to_string(ctx, -1));
- duk_replace(ctx, -3); /* [ ... arr jsonx(arr) res ] -> [ ... res jsonx(arr) ] */
- duk_pop(ctx);
- DUK_ASSERT(duk_is_string(ctx, -1));
+ duk_push_sprintf(thr, "ctx: top=%ld, stack=%s", (long) top, (const char *) duk_safe_to_string(thr, -1));
+ duk_replace(thr, -3); /* [ ... arr jsonx(arr) res ] -> [ ... res jsonx(arr) ] */
+ duk_pop(thr);
+ DUK_ASSERT(duk_is_string(thr, -1));
}
#else /* DUK_USE_JSON_SUPPORT */
-DUK_EXTERNAL void duk_push_context_dump(duk_context *ctx) {
- DUK_ERROR_UNSUPPORTED((duk_hthread *) ctx);
+DUK_EXTERNAL void duk_push_context_dump(duk_hthread *thr) {
+ DUK_ASSERT_API_ENTRY(thr);
+ DUK_ERROR_UNSUPPORTED(thr);
}
#endif /* DUK_USE_JSON_SUPPORT */
#if defined(DUK_USE_DEBUGGER_SUPPORT)
-DUK_EXTERNAL void duk_debugger_attach(duk_context *ctx,
+DUK_EXTERNAL void duk_debugger_attach(duk_hthread *thr,
duk_debug_read_function read_cb,
duk_debug_write_function write_cb,
duk_debug_peek_function peek_cb,
@@ -15206,7 +15512,6 @@ DUK_EXTERNAL void duk_debugger_attach(duk_context *ctx,
duk_debug_request_function request_cb,
duk_debug_detached_function detached_cb,
void *udata) {
- duk_hthread *thr = (duk_hthread *) ctx;
duk_heap *heap;
const char *str;
duk_size_t len;
@@ -15217,7 +15522,7 @@ DUK_EXTERNAL void duk_debugger_attach(duk_context *ctx,
DUK_D(DUK_DPRINT("application called duk_debugger_attach()"));
- DUK_ASSERT_CTX_VALID(ctx);
+ DUK_ASSERT_API_ENTRY(thr);
DUK_ASSERT(read_cb != NULL);
DUK_ASSERT(write_cb != NULL);
/* Other callbacks are optional. */
@@ -15237,10 +15542,9 @@ DUK_EXTERNAL void duk_debugger_attach(duk_context *ctx,
heap->dbg_processing = 0;
heap->dbg_state_dirty = 0;
heap->dbg_force_restart = 0;
- heap->dbg_step_type = DUK_STEP_TYPE_NONE;
- heap->dbg_step_thread = NULL;
- heap->dbg_step_csindex = 0;
- heap->dbg_step_startline = 0;
+ heap->dbg_pause_flags = 0;
+ heap->dbg_pause_act = NULL;
+ heap->dbg_pause_startline = 0;
heap->dbg_exec_counter = 0;
heap->dbg_last_counter = 0;
heap->dbg_last_time = 0.0;
@@ -15249,45 +15553,38 @@ DUK_EXTERNAL void duk_debugger_attach(duk_context *ctx,
/* Send version identification and flush right afterwards. Note that
* we must write raw, unframed bytes here.
*/
- duk_push_sprintf(ctx, "%ld %ld %s %s\n",
+ duk_push_sprintf(thr, "%ld %ld %s %s\n",
(long) DUK_DEBUG_PROTOCOL_VERSION,
(long) DUK_VERSION,
(const char *) DUK_GIT_DESCRIBE,
(const char *) DUK_USE_TARGET_INFO);
- str = duk_get_lstring(ctx, -1, &len);
+ str = duk_get_lstring(thr, -1, &len);
DUK_ASSERT(str != NULL);
duk_debug_write_bytes(thr, (const duk_uint8_t *) str, len);
duk_debug_write_flush(thr);
- duk_pop(ctx);
+ duk_pop(thr);
}
-DUK_EXTERNAL void duk_debugger_detach(duk_context *ctx) {
- duk_hthread *thr;
-
+DUK_EXTERNAL void duk_debugger_detach(duk_hthread *thr) {
DUK_D(DUK_DPRINT("application called duk_debugger_detach()"));
- DUK_ASSERT_CTX_VALID(ctx);
- thr = (duk_hthread *) ctx;
- DUK_ASSERT(thr != NULL);
+ DUK_ASSERT_API_ENTRY(thr);
DUK_ASSERT(thr->heap != NULL);
/* Can be called multiple times with no harm. */
duk_debug_do_detach(thr->heap);
}
-DUK_EXTERNAL void duk_debugger_cooperate(duk_context *ctx) {
- duk_hthread *thr;
+DUK_EXTERNAL void duk_debugger_cooperate(duk_hthread *thr) {
duk_bool_t processed_messages;
- DUK_ASSERT_CTX_VALID(ctx);
- thr = (duk_hthread *) ctx;
- DUK_ASSERT(thr != NULL);
+ DUK_ASSERT_API_ENTRY(thr);
DUK_ASSERT(thr->heap != NULL);
if (!duk_debug_is_attached(thr->heap)) {
return;
}
- if (thr->callstack_top > 0 || thr->heap->dbg_processing) {
+ if (thr->callstack_curr != NULL || thr->heap->dbg_processing) {
/* Calling duk_debugger_cooperate() while Duktape is being
* called into is not supported. This is not a 100% check
* but prevents any damage in most cases.
@@ -15299,20 +15596,17 @@ DUK_EXTERNAL void duk_debugger_cooperate(duk_context *ctx) {
DUK_UNREF(processed_messages);
}
-DUK_EXTERNAL duk_bool_t duk_debugger_notify(duk_context *ctx, duk_idx_t nvalues) {
- duk_hthread *thr;
+DUK_EXTERNAL duk_bool_t duk_debugger_notify(duk_hthread *thr, duk_idx_t nvalues) {
duk_idx_t top;
duk_idx_t idx;
duk_bool_t ret = 0;
- DUK_ASSERT_CTX_VALID(ctx);
- thr = (duk_hthread *) ctx;
- DUK_ASSERT(thr != NULL);
+ DUK_ASSERT_API_ENTRY(thr);
DUK_ASSERT(thr->heap != NULL);
DUK_D(DUK_DPRINT("application called duk_debugger_notify() with nvalues=%ld", (long) nvalues));
- top = duk_get_top(ctx);
+ top = duk_get_top(thr);
if (top < nvalues) {
DUK_ERROR_RANGE(thr, "not enough stack values for notify");
return ret; /* unreachable */
@@ -15320,7 +15614,7 @@ DUK_EXTERNAL duk_bool_t duk_debugger_notify(duk_context *ctx, duk_idx_t nvalues)
if (duk_debug_is_attached(thr->heap)) {
duk_debug_write_notify(thr, DUK_DBG_CMD_APPNOTIFY);
for (idx = top - nvalues; idx < top; idx++) {
- duk_tval *tv = DUK_GET_TVAL_POSIDX(ctx, idx);
+ duk_tval *tv = DUK_GET_TVAL_POSIDX(thr, idx);
duk_debug_write_tval(thr, tv);
}
duk_debug_write_eom(thr);
@@ -15334,16 +15628,12 @@ DUK_EXTERNAL duk_bool_t duk_debugger_notify(duk_context *ctx, duk_idx_t nvalues)
ret = 1;
}
}
- duk_pop_n(ctx, nvalues);
+ duk_pop_n(thr, nvalues);
return ret;
}
-DUK_EXTERNAL void duk_debugger_pause(duk_context *ctx) {
- duk_hthread *thr;
-
- DUK_ASSERT_CTX_VALID(ctx);
- thr = (duk_hthread *) ctx;
- DUK_ASSERT(thr != NULL);
+DUK_EXTERNAL void duk_debugger_pause(duk_hthread *thr) {
+ DUK_ASSERT_API_ENTRY(thr);
DUK_ASSERT(thr->heap != NULL);
DUK_D(DUK_DPRINT("application called duk_debugger_pause()"));
@@ -15367,7 +15657,7 @@ DUK_EXTERNAL void duk_debugger_pause(duk_context *ctx) {
#else /* DUK_USE_DEBUGGER_SUPPORT */
-DUK_EXTERNAL void duk_debugger_attach(duk_context *ctx,
+DUK_EXTERNAL void duk_debugger_attach(duk_hthread *thr,
duk_debug_read_function read_cb,
duk_debug_write_function write_cb,
duk_debug_peek_function peek_cb,
@@ -15376,7 +15666,7 @@ DUK_EXTERNAL void duk_debugger_attach(duk_context *ctx,
duk_debug_request_function request_cb,
duk_debug_detached_function detached_cb,
void *udata) {
- DUK_ASSERT_CTX_VALID(ctx);
+ DUK_ASSERT_API_ENTRY(thr);
DUK_UNREF(read_cb);
DUK_UNREF(write_cb);
DUK_UNREF(peek_cb);
@@ -15385,40 +15675,40 @@ DUK_EXTERNAL void duk_debugger_attach(duk_context *ctx,
DUK_UNREF(request_cb);
DUK_UNREF(detached_cb);
DUK_UNREF(udata);
- DUK_ERROR_TYPE((duk_hthread *) ctx, "no debugger support");
+ DUK_ERROR_TYPE(thr, "no debugger support");
}
-DUK_EXTERNAL void duk_debugger_detach(duk_context *ctx) {
- DUK_ASSERT_CTX_VALID(ctx);
- DUK_ERROR_TYPE((duk_hthread *) ctx, "no debugger support");
+DUK_EXTERNAL void duk_debugger_detach(duk_hthread *thr) {
+ DUK_ASSERT_API_ENTRY(thr);
+ DUK_ERROR_TYPE(thr, "no debugger support");
}
-DUK_EXTERNAL void duk_debugger_cooperate(duk_context *ctx) {
+DUK_EXTERNAL void duk_debugger_cooperate(duk_hthread *thr) {
/* nop */
- DUK_ASSERT_CTX_VALID(ctx);
- DUK_UNREF(ctx);
+ DUK_ASSERT_API_ENTRY(thr);
+ DUK_UNREF(thr);
}
-DUK_EXTERNAL duk_bool_t duk_debugger_notify(duk_context *ctx, duk_idx_t nvalues) {
+DUK_EXTERNAL duk_bool_t duk_debugger_notify(duk_hthread *thr, duk_idx_t nvalues) {
duk_idx_t top;
- DUK_ASSERT_CTX_VALID(ctx);
+ DUK_ASSERT_API_ENTRY(thr);
- top = duk_get_top(ctx);
+ top = duk_get_top(thr);
if (top < nvalues) {
- DUK_ERROR_RANGE_INVALID_COUNT((duk_hthread *) ctx);
+ DUK_ERROR_RANGE_INVALID_COUNT(thr);
return 0; /* unreachable */
}
/* No debugger support, just pop values. */
- duk_pop_n(ctx, nvalues);
+ duk_pop_n(thr, nvalues);
return 0;
}
-DUK_EXTERNAL void duk_debugger_pause(duk_context *ctx) {
+DUK_EXTERNAL void duk_debugger_pause(duk_hthread *thr) {
/* Treat like debugger statement: nop */
- DUK_ASSERT_CTX_VALID(ctx);
- DUK_UNREF(ctx);
+ DUK_ASSERT_API_ENTRY(thr);
+ DUK_UNREF(thr);
}
#endif /* DUK_USE_DEBUGGER_SUPPORT */
@@ -15437,14 +15727,13 @@ struct duk_internal_thread_state {
duk_int_t call_recursion_depth;
};
-DUK_EXTERNAL
-duk_context *duk_create_heap(duk_alloc_function alloc_func,
- duk_realloc_function realloc_func,
- duk_free_function free_func,
- void *heap_udata,
- duk_fatal_function fatal_handler) {
+DUK_EXTERNAL duk_hthread *duk_create_heap(duk_alloc_function alloc_func,
+ duk_realloc_function realloc_func,
+ duk_free_function free_func,
+ void *heap_udata,
+ duk_fatal_function fatal_handler) {
duk_heap *heap = NULL;
- duk_context *ctx;
+ duk_hthread *thr;
/* Assume that either all memory funcs are NULL or non-NULL, mixed
* cases will now be unsafe.
@@ -15483,33 +15772,31 @@ duk_context *duk_create_heap(duk_alloc_function alloc_func,
if (!heap) {
return NULL;
}
- ctx = (duk_context *) heap->heap_thread;
- DUK_ASSERT(ctx != NULL);
- DUK_ASSERT(((duk_hthread *) ctx)->heap != NULL);
- return ctx;
+ thr = heap->heap_thread;
+ DUK_ASSERT(thr != NULL);
+ DUK_ASSERT(thr->heap != NULL);
+ return thr;
}
-DUK_EXTERNAL void duk_destroy_heap(duk_context *ctx) {
- duk_hthread *thr = (duk_hthread *) ctx;
+DUK_EXTERNAL void duk_destroy_heap(duk_hthread *thr) {
duk_heap *heap;
- if (!ctx) {
+ if (!thr) {
return;
}
+ DUK_ASSERT_API_ENTRY(thr);
heap = thr->heap;
DUK_ASSERT(heap != NULL);
duk_heap_free(heap);
}
-DUK_EXTERNAL void duk_suspend(duk_context *ctx, duk_thread_state *state) {
- duk_hthread *thr = (duk_hthread *) ctx;
+DUK_EXTERNAL void duk_suspend(duk_hthread *thr, duk_thread_state *state) {
duk_internal_thread_state *snapshot = (duk_internal_thread_state *) (void *) state;
duk_heap *heap;
duk_ljstate *lj;
- DUK_ASSERT_CTX_VALID(ctx);
- DUK_ASSERT(thr != NULL);
+ DUK_ASSERT_API_ENTRY(thr);
DUK_ASSERT(thr->heap != NULL);
DUK_ASSERT(state != NULL); /* unvalidated */
@@ -15528,8 +15815,8 @@ DUK_EXTERNAL void duk_suspend(duk_context *ctx, duk_thread_state *state) {
heap = thr->heap;
lj = &heap->lj;
- duk_push_tval(ctx, &lj->value1);
- duk_push_tval(ctx, &lj->value2);
+ duk_push_tval(thr, &lj->value1);
+ duk_push_tval(thr, &lj->value2);
/* XXX: creating_error == 0 is asserted above, so no need to store. */
DUK_MEMCPY((void *) &snapshot->lj, (const void *) lj, sizeof(duk_ljstate));
@@ -15546,13 +15833,11 @@ DUK_EXTERNAL void duk_suspend(duk_context *ctx, duk_thread_state *state) {
heap->call_recursion_depth = 0;
}
-DUK_EXTERNAL void duk_resume(duk_context *ctx, const duk_thread_state *state) {
- duk_hthread *thr = (duk_hthread *) ctx;
+DUK_EXTERNAL void duk_resume(duk_hthread *thr, const duk_thread_state *state) {
const duk_internal_thread_state *snapshot = (const duk_internal_thread_state *) (const void *) state;
duk_heap *heap;
- DUK_ASSERT_CTX_VALID(ctx);
- DUK_ASSERT(thr != NULL);
+ DUK_ASSERT_API_ENTRY(thr);
DUK_ASSERT(thr->heap != NULL);
DUK_ASSERT(state != NULL); /* unvalidated */
@@ -15569,20 +15854,21 @@ DUK_EXTERNAL void duk_resume(duk_context *ctx, const duk_thread_state *state) {
heap->curr_thread = snapshot->curr_thread;
heap->call_recursion_depth = snapshot->call_recursion_depth;
- duk_pop_2(ctx);
+ duk_pop_2(thr);
}
/* XXX: better place for this */
-DUK_EXTERNAL void duk_set_global_object(duk_context *ctx) {
- duk_hthread *thr = (duk_hthread *) ctx;
+DUK_EXTERNAL void duk_set_global_object(duk_hthread *thr) {
duk_hobject *h_glob;
duk_hobject *h_prev_glob;
duk_hobjenv *h_env;
duk_hobject *h_prev_env;
- DUK_D(DUK_DPRINT("replace global object with: %!T", duk_get_tval(ctx, -1)));
+ DUK_ASSERT_API_ENTRY(thr);
+
+ DUK_D(DUK_DPRINT("replace global object with: %!T", duk_get_tval(thr, -1)));
- h_glob = duk_require_hobject(ctx, -1);
+ h_glob = duk_require_hobject(thr, -1);
DUK_ASSERT(h_glob != NULL);
/*
@@ -15627,7 +15913,7 @@ DUK_EXTERNAL void duk_set_global_object(duk_context *ctx) {
/* [ ... new_glob ] */
- duk_pop(ctx);
+ duk_pop(thr);
/* [ ... ] */
}
@@ -15640,7 +15926,7 @@ DUK_EXTERNAL void duk_set_global_object(duk_context *ctx) {
/* For footprint efficient multiple value setting: arrays are much better than
* varargs, format string with parsing is often better than string pointer arrays.
*/
-DUK_LOCAL void duk__inspect_multiple_uint(duk_context *ctx, const char *fmt, duk_int_t *vals) {
+DUK_LOCAL void duk__inspect_multiple_uint(duk_hthread *thr, const char *fmt, duk_int_t *vals) {
duk_int_t val;
const char *p;
const char *p_curr;
@@ -15657,9 +15943,9 @@ DUK_LOCAL void duk__inspect_multiple_uint(duk_context *ctx, const char *fmt, duk
val = *vals++;
if (val >= 0) {
/* Negative values are markers to skip key. */
- duk_push_string(ctx, p_curr);
- duk_push_uint(ctx, val);
- duk_put_prop(ctx, -3);
+ duk_push_string(thr, p_curr);
+ duk_push_int(thr, val);
+ duk_put_prop(thr, -3);
}
}
}
@@ -15687,8 +15973,7 @@ DUK_LOCAL void duk__inspect_multiple_uint(duk_context *ctx, const char *fmt, duk
#define DUK__IDX_TSTATE 12
#define DUK__IDX_VARIANT 13
-DUK_EXTERNAL void duk_inspect_value(duk_context *ctx, duk_idx_t idx) {
- duk_hthread *thr = (duk_hthread *) ctx;
+DUK_EXTERNAL void duk_inspect_value(duk_hthread *thr, duk_idx_t idx) {
duk_tval *tv;
duk_heaphdr *h;
/* The temporary values should be in an array rather than individual
@@ -15697,31 +15982,31 @@ DUK_EXTERNAL void duk_inspect_value(duk_context *ctx, duk_idx_t idx) {
*/
duk_int_t vals[14];
- DUK_UNREF(thr);
+ DUK_ASSERT_API_ENTRY(thr);
/* Assume two's complement and set everything to -1. */
DUK_MEMSET((void *) &vals, (int) 0xff, sizeof(vals));
DUK_ASSERT(vals[DUK__IDX_TYPE] == -1); /* spot check one */
- tv = duk_get_tval_or_unused(ctx, idx);
+ tv = duk_get_tval_or_unused(thr, idx);
h = (DUK_TVAL_IS_HEAP_ALLOCATED(tv) ? DUK_TVAL_GET_HEAPHDR(tv) : NULL);
vals[DUK__IDX_TYPE] = duk_get_type_tval(tv);
- vals[DUK__IDX_ITAG] = (duk_uint_t) DUK_TVAL_GET_TAG(tv);
+ vals[DUK__IDX_ITAG] = (duk_int_t) DUK_TVAL_GET_TAG(tv);
- duk_push_bare_object(ctx); /* Invalidates 'tv'. */
+ duk_push_bare_object(thr); /* Invalidates 'tv'. */
tv = NULL;
if (h == NULL) {
goto finish;
}
- duk_push_pointer(ctx, (void *) h);
- duk_put_prop_string(ctx, -2, "hptr");
+ duk_push_pointer(thr, (void *) h);
+ duk_put_prop_string(thr, -2, "hptr");
#if 0
/* Covers a lot of information, e.g. buffer and string variants. */
- duk_push_uint(ctx, (duk_uint_t) DUK_HEAPHDR_GET_FLAGS(h));
- duk_put_prop_string(ctx, -2, "hflags");
+ duk_push_uint(thr, (duk_uint_t) DUK_HEAPHDR_GET_FLAGS(h));
+ duk_put_prop_string(thr, -2, "hflags");
#endif
#if defined(DUK_USE_REFERENCE_COUNTING)
@@ -15800,62 +16085,61 @@ DUK_EXTERNAL void duk_inspect_value(duk_context *ctx, duk_idx_t idx) {
vals[DUK__IDX_VARIANT] = 1; /* buffer variant 1: dynamic */
vals[DUK__IDX_HBYTES] = (duk_uint_t) (sizeof(duk_hbuffer_dynamic));
}
- vals[DUK__IDX_DBYTES] = (duk_uint_t) (DUK_HBUFFER_GET_SIZE(h_buf));
+ vals[DUK__IDX_DBYTES] = (duk_int_t) (DUK_HBUFFER_GET_SIZE(h_buf));
} else {
DUK_ASSERT(vals[DUK__IDX_VARIANT] == 0); /* buffer variant 0: fixed */
- vals[DUK__IDX_HBYTES] = (duk_uint_t) (sizeof(duk_hbuffer_fixed) + DUK_HBUFFER_GET_SIZE(h_buf));
+ vals[DUK__IDX_HBYTES] = (duk_int_t) (sizeof(duk_hbuffer_fixed) + DUK_HBUFFER_GET_SIZE(h_buf));
}
break;
}
}
finish:
- duk__inspect_multiple_uint(ctx,
+ duk__inspect_multiple_uint(thr,
"type" "\x00" "itag" "\x00" "refc" "\x00" "hbytes" "\x00" "class" "\x00"
"pbytes" "\x00" "esize" "\x00" "enext" "\x00" "asize" "\x00" "hsize" "\x00"
"bcbytes" "\x00" "dbytes" "\x00" "tstate" "\x00" "variant" "\x00" "\x00",
(duk_int_t *) &vals);
}
-DUK_EXTERNAL void duk_inspect_callstack_entry(duk_context *ctx, duk_int_t level) {
- duk_hthread *thr = (duk_hthread *) ctx;
+DUK_EXTERNAL void duk_inspect_callstack_entry(duk_hthread *thr, duk_int_t level) {
duk_activation *act;
duk_uint_fast32_t pc;
duk_uint_fast32_t line;
- DUK_ASSERT_CTX_VALID(ctx);
+ DUK_ASSERT_API_ENTRY(thr);
- /* -1 = top callstack entry, callstack[callstack_top - 1]
- * -callstack_top = bottom callstack entry, callstack[0]
+ /* -1 = top callstack entry
+ * -2 = caller of level -1
+ * etc
*/
- if (level >= 0 || -level > (duk_int_t) thr->callstack_top) {
- duk_push_undefined(ctx);
+ act = duk_hthread_get_activation_for_level(thr, level);
+ if (act == NULL) {
+ duk_push_undefined(thr);
return;
}
- duk_push_bare_object(ctx);
- DUK_ASSERT(level >= -((duk_int_t) thr->callstack_top) && level <= -1);
+ duk_push_bare_object(thr);
- act = thr->callstack + thr->callstack_top + level;
/* 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_tval(ctx, &act->tv_func);
+ duk_push_tval(thr, &act->tv_func);
- duk_push_uint(ctx, (duk_uint_t) pc);
- duk_put_prop_stridx_short(ctx, -3, DUK_STRIDX_PC);
+ duk_push_uint(thr, (duk_uint_t) pc);
+ duk_put_prop_stridx_short(thr, -3, DUK_STRIDX_PC);
#if defined(DUK_USE_PC2LINE)
- line = duk_hobject_pc2line_query(ctx, -1, pc);
+ line = duk_hobject_pc2line_query(thr, -1, pc);
#else
line = 0;
#endif
- duk_push_uint(ctx, (duk_uint_t) line);
- duk_put_prop_stridx_short(ctx, -3, DUK_STRIDX_LINE_NUMBER);
+ duk_push_uint(thr, (duk_uint_t) line);
+ duk_put_prop_stridx_short(thr, -3, DUK_STRIDX_LINE_NUMBER);
- duk_put_prop_stridx_short(ctx, -2, DUK_STRIDX_LC_FUNCTION);
+ duk_put_prop_stridx_short(thr, -2, DUK_STRIDX_LC_FUNCTION);
/* Providing access to e.g. act->lex_env would be dangerous: these
* internal structures must never be accessible to the application.
* Duktape relies on them having consistent data, and this consistency
@@ -15884,50 +16168,38 @@ DUK_EXTERNAL void duk_inspect_callstack_entry(duk_context *ctx, duk_int_t level)
/* #include duk_internal.h -> already included */
-DUK_EXTERNAL void *duk_alloc_raw(duk_context *ctx, duk_size_t size) {
- duk_hthread *thr = (duk_hthread *) ctx;
-
- DUK_ASSERT_CTX_VALID(ctx);
+DUK_EXTERNAL void *duk_alloc_raw(duk_hthread *thr, duk_size_t size) {
+ DUK_ASSERT_API_ENTRY(thr);
return DUK_ALLOC_RAW(thr->heap, size);
}
-DUK_EXTERNAL void duk_free_raw(duk_context *ctx, void *ptr) {
- duk_hthread *thr = (duk_hthread *) ctx;
-
- DUK_ASSERT_CTX_VALID(ctx);
+DUK_EXTERNAL void duk_free_raw(duk_hthread *thr, void *ptr) {
+ DUK_ASSERT_API_ENTRY(thr);
DUK_FREE_RAW(thr->heap, ptr);
}
-DUK_EXTERNAL void *duk_realloc_raw(duk_context *ctx, void *ptr, duk_size_t size) {
- duk_hthread *thr = (duk_hthread *) ctx;
-
- DUK_ASSERT_CTX_VALID(ctx);
+DUK_EXTERNAL void *duk_realloc_raw(duk_hthread *thr, void *ptr, duk_size_t size) {
+ DUK_ASSERT_API_ENTRY(thr);
return DUK_REALLOC_RAW(thr->heap, ptr, size);
}
-DUK_EXTERNAL void *duk_alloc(duk_context *ctx, duk_size_t size) {
- duk_hthread *thr = (duk_hthread *) ctx;
-
- DUK_ASSERT_CTX_VALID(ctx);
+DUK_EXTERNAL void *duk_alloc(duk_hthread *thr, duk_size_t size) {
+ DUK_ASSERT_API_ENTRY(thr);
return DUK_ALLOC(thr->heap, size);
}
-DUK_EXTERNAL void duk_free(duk_context *ctx, void *ptr) {
- duk_hthread *thr = (duk_hthread *) ctx;
+DUK_EXTERNAL void duk_free(duk_hthread *thr, void *ptr) {
+ DUK_ASSERT_API_ENTRY(thr);
- DUK_ASSERT_CTX_VALID(ctx);
-
- DUK_FREE(thr->heap, ptr);
+ DUK_FREE_CHECKED(thr, ptr);
}
-DUK_EXTERNAL void *duk_realloc(duk_context *ctx, void *ptr, duk_size_t size) {
- duk_hthread *thr = (duk_hthread *) ctx;
-
- DUK_ASSERT_CTX_VALID(ctx);
+DUK_EXTERNAL void *duk_realloc(duk_hthread *thr, void *ptr, duk_size_t size) {
+ DUK_ASSERT_API_ENTRY(thr);
/*
* Note: since this is an exposed API call, there should be
@@ -15942,11 +16214,10 @@ DUK_EXTERNAL void *duk_realloc(duk_context *ctx, void *ptr, duk_size_t size) {
return DUK_REALLOC(thr->heap, ptr, size);
}
-DUK_EXTERNAL void duk_get_memory_functions(duk_context *ctx, duk_memory_functions *out_funcs) {
- duk_hthread *thr = (duk_hthread *) ctx;
+DUK_EXTERNAL void duk_get_memory_functions(duk_hthread *thr, duk_memory_functions *out_funcs) {
duk_heap *heap;
- DUK_ASSERT_CTX_VALID(ctx);
+ DUK_ASSERT_API_ENTRY(thr);
DUK_ASSERT(out_funcs != NULL);
DUK_ASSERT(thr != NULL);
DUK_ASSERT(thr->heap != NULL);
@@ -15958,12 +16229,11 @@ DUK_EXTERNAL void duk_get_memory_functions(duk_context *ctx, duk_memory_function
out_funcs->udata = heap->heap_udata;
}
-DUK_EXTERNAL void duk_gc(duk_context *ctx, duk_uint_t flags) {
- duk_hthread *thr = (duk_hthread *) ctx;
+DUK_EXTERNAL void duk_gc(duk_hthread *thr, duk_uint_t flags) {
duk_heap *heap;
duk_small_uint_t ms_flags;
- DUK_ASSERT_CTX_VALID(ctx);
+ DUK_ASSERT_API_ENTRY(thr);
heap = thr->heap;
DUK_ASSERT(heap != NULL);
@@ -15986,94 +16256,98 @@ DUK_EXTERNAL void duk_gc(duk_context *ctx, duk_uint_t flags) {
* defineProperty, getOwnPropertyDescriptor).
*/
-DUK_EXTERNAL duk_bool_t duk_get_prop(duk_context *ctx, duk_idx_t obj_idx) {
- duk_hthread *thr = (duk_hthread *) ctx;
+DUK_EXTERNAL duk_bool_t duk_get_prop(duk_hthread *thr, duk_idx_t obj_idx) {
duk_tval *tv_obj;
duk_tval *tv_key;
duk_bool_t rc;
- DUK_ASSERT_CTX_VALID(ctx);
+ DUK_ASSERT_API_ENTRY(thr);
/* Note: copying tv_obj and tv_key to locals to shield against a valstack
* resize is not necessary for a property get right now.
*/
- tv_obj = duk_require_tval(ctx, obj_idx);
- tv_key = duk_require_tval(ctx, -1);
+ tv_obj = duk_require_tval(thr, obj_idx);
+ tv_key = duk_require_tval(thr, -1);
rc = duk_hobject_getprop(thr, tv_obj, tv_key);
DUK_ASSERT(rc == 0 || rc == 1);
/* a value is left on stack regardless of rc */
- duk_remove_m2(ctx); /* remove key */
+ duk_remove_m2(thr); /* remove key */
+ DUK_ASSERT(duk_is_undefined(thr, -1) || rc == 1);
return rc; /* 1 if property found, 0 otherwise */
}
-DUK_EXTERNAL duk_bool_t duk_get_prop_string(duk_context *ctx, duk_idx_t obj_idx, const char *key) {
- DUK_ASSERT_CTX_VALID(ctx);
+DUK_EXTERNAL duk_bool_t duk_get_prop_string(duk_hthread *thr, duk_idx_t obj_idx, const char *key) {
+ DUK_ASSERT_API_ENTRY(thr);
DUK_ASSERT(key != NULL);
- obj_idx = duk_require_normalize_index(ctx, obj_idx);
- duk_push_string(ctx, key);
- return duk_get_prop(ctx, obj_idx);
+ obj_idx = duk_require_normalize_index(thr, obj_idx);
+ duk_push_string(thr, key);
+ return duk_get_prop(thr, obj_idx);
}
-DUK_EXTERNAL duk_bool_t duk_get_prop_lstring(duk_context *ctx, duk_idx_t obj_idx, const char *key, duk_size_t key_len) {
- DUK_ASSERT_CTX_VALID(ctx);
+DUK_EXTERNAL duk_bool_t duk_get_prop_lstring(duk_hthread *thr, duk_idx_t obj_idx, const char *key, duk_size_t key_len) {
+ DUK_ASSERT_API_ENTRY(thr);
DUK_ASSERT(key != NULL);
- obj_idx = duk_require_normalize_index(ctx, obj_idx);
- duk_push_lstring(ctx, key, key_len);
- return duk_get_prop(ctx, obj_idx);
+ obj_idx = duk_require_normalize_index(thr, obj_idx);
+ duk_push_lstring(thr, key, key_len);
+ return duk_get_prop(thr, obj_idx);
}
-DUK_EXTERNAL duk_bool_t duk_get_prop_index(duk_context *ctx, duk_idx_t obj_idx, duk_uarridx_t arr_idx) {
- DUK_ASSERT_CTX_VALID(ctx);
+DUK_EXTERNAL duk_bool_t duk_get_prop_index(duk_hthread *thr, duk_idx_t obj_idx, duk_uarridx_t arr_idx) {
+ DUK_ASSERT_API_ENTRY(thr);
- obj_idx = duk_require_normalize_index(ctx, obj_idx);
- duk_push_uarridx(ctx, arr_idx);
- return duk_get_prop(ctx, obj_idx);
+ obj_idx = duk_require_normalize_index(thr, obj_idx);
+ duk_push_uarridx(thr, arr_idx);
+ return duk_get_prop(thr, obj_idx);
}
-DUK_INTERNAL duk_bool_t duk_get_prop_stridx(duk_context *ctx, duk_idx_t obj_idx, duk_small_uint_t stridx) {
- duk_hthread *thr = (duk_hthread *) ctx;
+DUK_EXTERNAL duk_bool_t duk_get_prop_heapptr(duk_hthread *thr, duk_idx_t obj_idx, void *ptr) {
+ DUK_ASSERT_API_ENTRY(thr);
- DUK_ASSERT_CTX_VALID(ctx);
+ obj_idx = duk_require_normalize_index(thr, obj_idx);
+ duk_push_heapptr(thr, ptr); /* NULL -> 'undefined' */
+ return duk_get_prop(thr, obj_idx);
+}
+
+DUK_INTERNAL duk_bool_t duk_get_prop_stridx(duk_hthread *thr, duk_idx_t obj_idx, duk_small_uint_t stridx) {
+ DUK_ASSERT_API_ENTRY(thr);
DUK_ASSERT_STRIDX_VALID(stridx);
- DUK_UNREF(thr);
- obj_idx = duk_require_normalize_index(ctx, obj_idx);
- duk_push_hstring(ctx, DUK_HTHREAD_GET_STRING(thr, stridx));
- return duk_get_prop(ctx, obj_idx);
+ obj_idx = duk_require_normalize_index(thr, obj_idx);
+ duk_push_hstring(thr, DUK_HTHREAD_GET_STRING(thr, stridx));
+ return duk_get_prop(thr, obj_idx);
}
-DUK_INTERNAL duk_bool_t duk_get_prop_stridx_short_raw(duk_context *ctx, duk_uint_t packed_args) {
- return duk_get_prop_stridx(ctx, (duk_idx_t) (duk_int16_t) (packed_args >> 16),
+DUK_INTERNAL duk_bool_t duk_get_prop_stridx_short_raw(duk_hthread *thr, duk_uint_t packed_args) {
+ return duk_get_prop_stridx(thr, (duk_idx_t) (duk_int16_t) (packed_args >> 16),
(duk_small_uint_t) (packed_args & 0xffffUL));
}
-DUK_INTERNAL duk_bool_t duk_get_prop_stridx_boolean(duk_context *ctx, duk_idx_t obj_idx, duk_small_uint_t stridx, duk_bool_t *out_has_prop) {
+DUK_INTERNAL duk_bool_t duk_get_prop_stridx_boolean(duk_hthread *thr, duk_idx_t obj_idx, duk_small_uint_t stridx, duk_bool_t *out_has_prop) {
duk_bool_t rc;
- DUK_ASSERT_CTX_VALID(ctx);
+ DUK_ASSERT_API_ENTRY(thr);
DUK_ASSERT_STRIDX_VALID(stridx);
- rc = duk_get_prop_stridx(ctx, obj_idx, stridx);
+ rc = duk_get_prop_stridx(thr, obj_idx, stridx);
if (out_has_prop) {
*out_has_prop = rc;
}
- rc = duk_to_boolean(ctx, -1);
+ rc = duk_to_boolean(thr, -1);
DUK_ASSERT(rc == 0 || rc == 1);
- duk_pop(ctx);
+ duk_pop(thr);
return rc;
}
-DUK_LOCAL duk_bool_t duk__put_prop_shared(duk_context *ctx, duk_idx_t obj_idx, duk_idx_t idx_key) {
- duk_hthread *thr = (duk_hthread *) ctx;
+DUK_LOCAL duk_bool_t duk__put_prop_shared(duk_hthread *thr, duk_idx_t obj_idx, duk_idx_t idx_key) {
duk_tval *tv_obj;
duk_tval *tv_key;
duk_tval *tv_val;
- duk_small_int_t throw_flag;
+ duk_bool_t throw_flag;
duk_bool_t rc;
/* Note: copying tv_obj and tv_key to locals to shield against a valstack
@@ -16087,202 +16361,216 @@ DUK_LOCAL duk_bool_t duk__put_prop_shared(duk_context *ctx, duk_idx_t obj_idx, d
DUK_ASSERT((idx_key == -2 && (idx_key ^ 1) == -1) ||
(idx_key == -1 && (idx_key ^ 1) == -2));
/* XXX: Direct access; faster validation. */
- tv_obj = duk_require_tval(ctx, obj_idx);
- tv_key = duk_require_tval(ctx, idx_key);
- tv_val = duk_require_tval(ctx, idx_key ^ 1);
- throw_flag = duk_is_strict_call(ctx);
+ tv_obj = duk_require_tval(thr, obj_idx);
+ tv_key = duk_require_tval(thr, idx_key);
+ tv_val = duk_require_tval(thr, idx_key ^ 1);
+ throw_flag = duk_is_strict_call(thr);
rc = duk_hobject_putprop(thr, tv_obj, tv_key, tv_val, throw_flag);
DUK_ASSERT(rc == 0 || rc == 1);
- duk_pop_2(ctx); /* remove key and value */
+ duk_pop_2(thr); /* remove key and value */
return rc; /* 1 if property found, 0 otherwise */
}
-DUK_EXTERNAL duk_bool_t duk_put_prop(duk_context *ctx, duk_idx_t obj_idx) {
- DUK_ASSERT_CTX_VALID(ctx);
- return duk__put_prop_shared(ctx, obj_idx, -2);
+DUK_EXTERNAL duk_bool_t duk_put_prop(duk_hthread *thr, duk_idx_t obj_idx) {
+ DUK_ASSERT_API_ENTRY(thr);
+ return duk__put_prop_shared(thr, obj_idx, -2);
}
-DUK_EXTERNAL duk_bool_t duk_put_prop_string(duk_context *ctx, duk_idx_t obj_idx, const char *key) {
- DUK_ASSERT_CTX_VALID(ctx);
+DUK_EXTERNAL duk_bool_t duk_put_prop_string(duk_hthread *thr, duk_idx_t obj_idx, const char *key) {
+ DUK_ASSERT_API_ENTRY(thr);
DUK_ASSERT(key != NULL);
/* Careful here and with other duk_put_prop_xxx() helpers: the
* target object and the property value may be in the same value
* stack slot (unusual, but still conceptually clear).
*/
- obj_idx = duk_normalize_index(ctx, obj_idx);
- (void) duk_push_string(ctx, key);
- return duk__put_prop_shared(ctx, obj_idx, -1);
+ obj_idx = duk_normalize_index(thr, obj_idx);
+ (void) duk_push_string(thr, key);
+ return duk__put_prop_shared(thr, obj_idx, -1);
}
-DUK_EXTERNAL duk_bool_t duk_put_prop_lstring(duk_context *ctx, duk_idx_t obj_idx, const char *key, duk_size_t key_len) {
- DUK_ASSERT_CTX_VALID(ctx);
+DUK_EXTERNAL duk_bool_t duk_put_prop_lstring(duk_hthread *thr, duk_idx_t obj_idx, const char *key, duk_size_t key_len) {
+ DUK_ASSERT_API_ENTRY(thr);
DUK_ASSERT(key != NULL);
- obj_idx = duk_normalize_index(ctx, obj_idx);
- (void) duk_push_lstring(ctx, key, key_len);
- return duk__put_prop_shared(ctx, obj_idx, -1);
+ obj_idx = duk_normalize_index(thr, obj_idx);
+ (void) duk_push_lstring(thr, key, key_len);
+ return duk__put_prop_shared(thr, obj_idx, -1);
}
-DUK_EXTERNAL duk_bool_t duk_put_prop_index(duk_context *ctx, duk_idx_t obj_idx, duk_uarridx_t arr_idx) {
- DUK_ASSERT_CTX_VALID(ctx);
+DUK_EXTERNAL duk_bool_t duk_put_prop_index(duk_hthread *thr, duk_idx_t obj_idx, duk_uarridx_t arr_idx) {
+ DUK_ASSERT_API_ENTRY(thr);
- obj_idx = duk_require_normalize_index(ctx, obj_idx);
- duk_push_uarridx(ctx, arr_idx);
- return duk__put_prop_shared(ctx, obj_idx, -1);
+ obj_idx = duk_require_normalize_index(thr, obj_idx);
+ duk_push_uarridx(thr, arr_idx);
+ return duk__put_prop_shared(thr, obj_idx, -1);
}
-DUK_INTERNAL duk_bool_t duk_put_prop_stridx(duk_context *ctx, duk_idx_t obj_idx, duk_small_uint_t stridx) {
- duk_hthread *thr = (duk_hthread *) ctx;
+DUK_EXTERNAL duk_bool_t duk_put_prop_heapptr(duk_hthread *thr, duk_idx_t obj_idx, void *ptr) {
+ DUK_ASSERT_API_ENTRY(thr);
+
+ obj_idx = duk_require_normalize_index(thr, obj_idx);
+ duk_push_heapptr(thr, ptr); /* NULL -> 'undefined' */
+ return duk__put_prop_shared(thr, obj_idx, -1);
+}
- DUK_ASSERT_CTX_VALID(ctx);
+
+DUK_INTERNAL duk_bool_t duk_put_prop_stridx(duk_hthread *thr, duk_idx_t obj_idx, duk_small_uint_t stridx) {
+ DUK_ASSERT_API_ENTRY(thr);
DUK_ASSERT_STRIDX_VALID(stridx);
- DUK_UNREF(thr);
- obj_idx = duk_require_normalize_index(ctx, obj_idx);
- duk_push_hstring(ctx, DUK_HTHREAD_GET_STRING(thr, stridx));
- return duk__put_prop_shared(ctx, obj_idx, -1);
+ obj_idx = duk_require_normalize_index(thr, obj_idx);
+ duk_push_hstring(thr, DUK_HTHREAD_GET_STRING(thr, stridx));
+ return duk__put_prop_shared(thr, obj_idx, -1);
}
-DUK_INTERNAL duk_bool_t duk_put_prop_stridx_short_raw(duk_context *ctx, duk_uint_t packed_args) {
- return duk_put_prop_stridx(ctx, (duk_idx_t) (duk_int16_t) (packed_args >> 16),
+DUK_INTERNAL duk_bool_t duk_put_prop_stridx_short_raw(duk_hthread *thr, duk_uint_t packed_args) {
+ return duk_put_prop_stridx(thr, (duk_idx_t) (duk_int16_t) (packed_args >> 16),
(duk_small_uint_t) (packed_args & 0xffffUL));
}
-DUK_EXTERNAL duk_bool_t duk_del_prop(duk_context *ctx, duk_idx_t obj_idx) {
- duk_hthread *thr = (duk_hthread *) ctx;
+DUK_EXTERNAL duk_bool_t duk_del_prop(duk_hthread *thr, duk_idx_t obj_idx) {
duk_tval *tv_obj;
duk_tval *tv_key;
- duk_small_int_t throw_flag;
+ duk_bool_t throw_flag;
duk_bool_t rc;
- DUK_ASSERT_CTX_VALID(ctx);
+ DUK_ASSERT_API_ENTRY(thr);
/* Note: copying tv_obj and tv_key to locals to shield against a valstack
* resize is not necessary for a property delete right now.
*/
- tv_obj = duk_require_tval(ctx, obj_idx);
- tv_key = duk_require_tval(ctx, -1);
- throw_flag = duk_is_strict_call(ctx);
+ tv_obj = duk_require_tval(thr, obj_idx);
+ tv_key = duk_require_tval(thr, -1);
+ throw_flag = duk_is_strict_call(thr);
rc = duk_hobject_delprop(thr, tv_obj, tv_key, throw_flag);
DUK_ASSERT(rc == 0 || rc == 1);
- duk_pop(ctx); /* remove key */
+ duk_pop(thr); /* remove key */
return rc;
}
-DUK_EXTERNAL duk_bool_t duk_del_prop_string(duk_context *ctx, duk_idx_t obj_idx, const char *key) {
- DUK_ASSERT_CTX_VALID(ctx);
+DUK_EXTERNAL duk_bool_t duk_del_prop_string(duk_hthread *thr, duk_idx_t obj_idx, const char *key) {
+ DUK_ASSERT_API_ENTRY(thr);
DUK_ASSERT(key != NULL);
- obj_idx = duk_require_normalize_index(ctx, obj_idx);
- duk_push_string(ctx, key);
- return duk_del_prop(ctx, obj_idx);
+ obj_idx = duk_require_normalize_index(thr, obj_idx);
+ duk_push_string(thr, key);
+ return duk_del_prop(thr, obj_idx);
}
-DUK_EXTERNAL duk_bool_t duk_del_prop_lstring(duk_context *ctx, duk_idx_t obj_idx, const char *key, duk_size_t key_len) {
- DUK_ASSERT_CTX_VALID(ctx);
+DUK_EXTERNAL duk_bool_t duk_del_prop_lstring(duk_hthread *thr, duk_idx_t obj_idx, const char *key, duk_size_t key_len) {
+ DUK_ASSERT_API_ENTRY(thr);
DUK_ASSERT(key != NULL);
- obj_idx = duk_require_normalize_index(ctx, obj_idx);
- duk_push_lstring(ctx, key, key_len);
- return duk_del_prop(ctx, obj_idx);
+ obj_idx = duk_require_normalize_index(thr, obj_idx);
+ duk_push_lstring(thr, key, key_len);
+ return duk_del_prop(thr, obj_idx);
}
-DUK_EXTERNAL duk_bool_t duk_del_prop_index(duk_context *ctx, duk_idx_t obj_idx, duk_uarridx_t arr_idx) {
- DUK_ASSERT_CTX_VALID(ctx);
+DUK_EXTERNAL duk_bool_t duk_del_prop_index(duk_hthread *thr, duk_idx_t obj_idx, duk_uarridx_t arr_idx) {
+ DUK_ASSERT_API_ENTRY(thr);
- obj_idx = duk_require_normalize_index(ctx, obj_idx);
- duk_push_uarridx(ctx, arr_idx);
- return duk_del_prop(ctx, obj_idx);
+ obj_idx = duk_require_normalize_index(thr, obj_idx);
+ duk_push_uarridx(thr, arr_idx);
+ return duk_del_prop(thr, obj_idx);
}
-DUK_INTERNAL duk_bool_t duk_del_prop_stridx(duk_context *ctx, duk_idx_t obj_idx, duk_small_uint_t stridx) {
- duk_hthread *thr = (duk_hthread *) ctx;
+DUK_EXTERNAL duk_bool_t duk_del_prop_heapptr(duk_hthread *thr, duk_idx_t obj_idx, void *ptr) {
+ DUK_ASSERT_API_ENTRY(thr);
- DUK_ASSERT_CTX_VALID(ctx);
+ obj_idx = duk_require_normalize_index(thr, obj_idx);
+ duk_push_heapptr(thr, ptr); /* NULL -> 'undefined' */
+ return duk_del_prop(thr, obj_idx);
+}
+
+DUK_INTERNAL duk_bool_t duk_del_prop_stridx(duk_hthread *thr, duk_idx_t obj_idx, duk_small_uint_t stridx) {
+ DUK_ASSERT_API_ENTRY(thr);
DUK_ASSERT_STRIDX_VALID(stridx);
- DUK_UNREF(thr);
- obj_idx = duk_require_normalize_index(ctx, obj_idx);
- duk_push_hstring(ctx, DUK_HTHREAD_GET_STRING(thr, stridx));
- return duk_del_prop(ctx, obj_idx);
+ obj_idx = duk_require_normalize_index(thr, obj_idx);
+ duk_push_hstring(thr, DUK_HTHREAD_GET_STRING(thr, stridx));
+ return duk_del_prop(thr, obj_idx);
}
#if 0
-DUK_INTERNAL duk_bool_t duk_del_prop_stridx_short_raw(duk_context *ctx, duk_uint_t packed_args) {
- return duk_del_prop_stridx(ctx, (duk_idx_t) (duk_int16_t) (packed_args >> 16),
+DUK_INTERNAL duk_bool_t duk_del_prop_stridx_short_raw(duk_hthread *thr, duk_uint_t packed_args) {
+ return duk_del_prop_stridx(thr, (duk_idx_t) (duk_int16_t) (packed_args >> 16),
(duk_small_uint_t) (packed_args & 0xffffUL));
}
#endif
-DUK_EXTERNAL duk_bool_t duk_has_prop(duk_context *ctx, duk_idx_t obj_idx) {
- duk_hthread *thr = (duk_hthread *) ctx;
+DUK_EXTERNAL duk_bool_t duk_has_prop(duk_hthread *thr, duk_idx_t obj_idx) {
duk_tval *tv_obj;
duk_tval *tv_key;
duk_bool_t rc;
- DUK_ASSERT_CTX_VALID(ctx);
+ DUK_ASSERT_API_ENTRY(thr);
/* Note: copying tv_obj and tv_key to locals to shield against a valstack
* resize is not necessary for a property existence check right now.
*/
- tv_obj = duk_require_tval(ctx, obj_idx);
- tv_key = duk_require_tval(ctx, -1);
+ tv_obj = duk_require_tval(thr, obj_idx);
+ tv_key = duk_require_tval(thr, -1);
rc = duk_hobject_hasprop(thr, tv_obj, tv_key);
DUK_ASSERT(rc == 0 || rc == 1);
- duk_pop(ctx); /* remove key */
+ duk_pop(thr); /* remove key */
return rc; /* 1 if property found, 0 otherwise */
}
-DUK_EXTERNAL duk_bool_t duk_has_prop_string(duk_context *ctx, duk_idx_t obj_idx, const char *key) {
- DUK_ASSERT_CTX_VALID(ctx);
+DUK_EXTERNAL duk_bool_t duk_has_prop_string(duk_hthread *thr, duk_idx_t obj_idx, const char *key) {
+ DUK_ASSERT_API_ENTRY(thr);
DUK_ASSERT(key != NULL);
- obj_idx = duk_require_normalize_index(ctx, obj_idx);
- duk_push_string(ctx, key);
- return duk_has_prop(ctx, obj_idx);
+ obj_idx = duk_require_normalize_index(thr, obj_idx);
+ duk_push_string(thr, key);
+ return duk_has_prop(thr, obj_idx);
}
-DUK_EXTERNAL duk_bool_t duk_has_prop_lstring(duk_context *ctx, duk_idx_t obj_idx, const char *key, duk_size_t key_len) {
- DUK_ASSERT_CTX_VALID(ctx);
+DUK_EXTERNAL duk_bool_t duk_has_prop_lstring(duk_hthread *thr, duk_idx_t obj_idx, const char *key, duk_size_t key_len) {
+ DUK_ASSERT_API_ENTRY(thr);
DUK_ASSERT(key != NULL);
- obj_idx = duk_require_normalize_index(ctx, obj_idx);
- duk_push_lstring(ctx, key, key_len);
- return duk_has_prop(ctx, obj_idx);
+ obj_idx = duk_require_normalize_index(thr, obj_idx);
+ duk_push_lstring(thr, key, key_len);
+ return duk_has_prop(thr, obj_idx);
}
-DUK_EXTERNAL duk_bool_t duk_has_prop_index(duk_context *ctx, duk_idx_t obj_idx, duk_uarridx_t arr_idx) {
- DUK_ASSERT_CTX_VALID(ctx);
+DUK_EXTERNAL duk_bool_t duk_has_prop_index(duk_hthread *thr, duk_idx_t obj_idx, duk_uarridx_t arr_idx) {
+ DUK_ASSERT_API_ENTRY(thr);
- obj_idx = duk_require_normalize_index(ctx, obj_idx);
- duk_push_uarridx(ctx, arr_idx);
- return duk_has_prop(ctx, obj_idx);
+ obj_idx = duk_require_normalize_index(thr, obj_idx);
+ duk_push_uarridx(thr, arr_idx);
+ return duk_has_prop(thr, obj_idx);
}
-DUK_INTERNAL duk_bool_t duk_has_prop_stridx(duk_context *ctx, duk_idx_t obj_idx, duk_small_uint_t stridx) {
- duk_hthread *thr = (duk_hthread *) ctx;
+DUK_EXTERNAL duk_bool_t duk_has_prop_heapptr(duk_hthread *thr, duk_idx_t obj_idx, void *ptr) {
+ DUK_ASSERT_API_ENTRY(thr);
- DUK_ASSERT_CTX_VALID(ctx);
+ obj_idx = duk_require_normalize_index(thr, obj_idx);
+ duk_push_heapptr(thr, ptr); /* NULL -> 'undefined' */
+ return duk_has_prop(thr, obj_idx);
+}
+
+DUK_INTERNAL duk_bool_t duk_has_prop_stridx(duk_hthread *thr, duk_idx_t obj_idx, duk_small_uint_t stridx) {
+ DUK_ASSERT_API_ENTRY(thr);
DUK_ASSERT_STRIDX_VALID(stridx);
- DUK_UNREF(thr);
- obj_idx = duk_require_normalize_index(ctx, obj_idx);
- duk_push_hstring(ctx, DUK_HTHREAD_GET_STRING(thr, stridx));
- return duk_has_prop(ctx, obj_idx);
+ obj_idx = duk_require_normalize_index(thr, obj_idx);
+ duk_push_hstring(thr, DUK_HTHREAD_GET_STRING(thr, stridx));
+ return duk_has_prop(thr, obj_idx);
}
#if 0
-DUK_INTERNAL duk_bool_t duk_has_prop_stridx_short_raw(duk_context *ctx, duk_uint_t packed_args) {
- return duk_has_prop_stridx(ctx, (duk_idx_t) (duk_int16_t) (packed_args >> 16),
+DUK_INTERNAL duk_bool_t duk_has_prop_stridx_short_raw(duk_hthread *thr, duk_uint_t packed_args) {
+ return duk_has_prop_stridx(thr, (duk_idx_t) (duk_int16_t) (packed_args >> 16),
(duk_small_uint_t) (packed_args & 0xffffUL));
}
#endif
@@ -16292,103 +16580,103 @@ DUK_INTERNAL duk_bool_t duk_has_prop_stridx_short_raw(duk_context *ctx, duk_uint
* not invoked by this method. The caller must be careful to invoke any such
* behaviors if necessary.
*/
-DUK_INTERNAL void duk_xdef_prop(duk_context *ctx, duk_idx_t obj_idx, duk_small_uint_t desc_flags) {
- duk_hthread *thr = (duk_hthread *) ctx;
+DUK_INTERNAL void duk_xdef_prop(duk_hthread *thr, duk_idx_t obj_idx, duk_small_uint_t desc_flags) {
duk_hobject *obj;
duk_hstring *key;
- DUK_ASSERT_CTX_VALID(ctx);
+ DUK_ASSERT_API_ENTRY(thr);
- obj = duk_require_hobject(ctx, obj_idx);
+ obj = duk_require_hobject(thr, obj_idx);
DUK_ASSERT(obj != NULL);
- key = duk_to_property_key_hstring(ctx, -2);
+ key = duk_to_property_key_hstring(thr, -2);
DUK_ASSERT(key != NULL);
- DUK_ASSERT(duk_require_tval(ctx, -1) != NULL);
+ DUK_ASSERT(duk_require_tval(thr, -1) != NULL);
duk_hobject_define_property_internal(thr, obj, key, desc_flags);
- duk_pop(ctx); /* pop key */
+ duk_pop(thr); /* pop key */
}
-DUK_INTERNAL void duk_xdef_prop_index(duk_context *ctx, duk_idx_t obj_idx, duk_uarridx_t arr_idx, duk_small_uint_t desc_flags) {
- duk_hthread *thr = (duk_hthread *) ctx;
+DUK_INTERNAL void duk_xdef_prop_index(duk_hthread *thr, duk_idx_t obj_idx, duk_uarridx_t arr_idx, duk_small_uint_t desc_flags) {
duk_hobject *obj;
- DUK_ASSERT_CTX_VALID(ctx);
+ DUK_ASSERT_API_ENTRY(thr);
- obj = duk_require_hobject(ctx, obj_idx);
+ obj = duk_require_hobject(thr, obj_idx);
DUK_ASSERT(obj != NULL);
duk_hobject_define_property_internal_arridx(thr, obj, arr_idx, desc_flags);
/* value popped by call */
}
-DUK_INTERNAL void duk_xdef_prop_stridx(duk_context *ctx, duk_idx_t obj_idx, duk_small_uint_t stridx, duk_small_uint_t desc_flags) {
- duk_hthread *thr = (duk_hthread *) ctx;
+DUK_INTERNAL void duk_xdef_prop_stridx(duk_hthread *thr, duk_idx_t obj_idx, duk_small_uint_t stridx, duk_small_uint_t desc_flags) {
duk_hobject *obj;
duk_hstring *key;
- DUK_ASSERT_CTX_VALID(ctx);
+ DUK_ASSERT_API_ENTRY(thr);
DUK_ASSERT_STRIDX_VALID(stridx);
- obj = duk_require_hobject(ctx, obj_idx);
+ obj = duk_require_hobject(thr, obj_idx);
DUK_ASSERT(obj != NULL);
key = DUK_HTHREAD_GET_STRING(thr, stridx);
DUK_ASSERT(key != NULL);
- DUK_ASSERT(duk_require_tval(ctx, -1) != NULL);
+ DUK_ASSERT(duk_require_tval(thr, -1) != NULL);
duk_hobject_define_property_internal(thr, obj, key, desc_flags);
/* value popped by call */
}
-DUK_INTERNAL void duk_xdef_prop_stridx_short_raw(duk_context *ctx, duk_uint_t packed_args) {
- duk_xdef_prop_stridx(ctx, (duk_idx_t) (duk_int8_t) (packed_args >> 24),
+DUK_INTERNAL void duk_xdef_prop_stridx_short_raw(duk_hthread *thr, duk_uint_t packed_args) {
+ duk_xdef_prop_stridx(thr, (duk_idx_t) (duk_int8_t) (packed_args >> 24),
(duk_small_uint_t) (packed_args >> 8) & 0xffffUL,
(duk_small_uint_t) (packed_args & 0xffL));
}
-DUK_INTERNAL void duk_xdef_prop_stridx_builtin(duk_context *ctx, duk_idx_t obj_idx, duk_small_uint_t stridx, duk_small_int_t builtin_idx, duk_small_uint_t desc_flags) {
- duk_hthread *thr = (duk_hthread *) ctx;
+#if 0 /*unused*/
+DUK_INTERNAL void duk_xdef_prop_stridx_builtin(duk_hthread *thr, duk_idx_t obj_idx, duk_small_uint_t stridx, duk_small_int_t builtin_idx, duk_small_uint_t desc_flags) {
duk_hobject *obj;
duk_hstring *key;
- DUK_ASSERT_CTX_VALID(ctx);
+ DUK_ASSERT_API_ENTRY(thr);
DUK_ASSERT_STRIDX_VALID(stridx);
DUK_ASSERT_BIDX_VALID(builtin_idx);
- obj = duk_require_hobject(ctx, obj_idx);
+ obj = duk_require_hobject(thr, obj_idx);
DUK_ASSERT(obj != NULL);
key = DUK_HTHREAD_GET_STRING(thr, stridx);
DUK_ASSERT(key != NULL);
- duk_push_hobject(ctx, thr->builtins[builtin_idx]);
+ duk_push_hobject(thr, thr->builtins[builtin_idx]);
duk_hobject_define_property_internal(thr, obj, key, desc_flags);
/* value popped by call */
}
+#endif
/* This is a rare property helper; it sets the global thrower (E5 Section 13.2.3)
* setter/getter into an object property. This is needed by the 'arguments'
* object creation code, function instance creation code, and Function.prototype.bind().
*/
-DUK_INTERNAL void duk_xdef_prop_stridx_thrower(duk_context *ctx, duk_idx_t obj_idx, duk_small_uint_t stridx) {
- obj_idx = duk_require_normalize_index(ctx, obj_idx);
- duk_push_hstring_stridx(ctx, stridx);
- duk_push_hobject_bidx(ctx, DUK_BIDX_TYPE_ERROR_THROWER);
- duk_dup_top(ctx);
- duk_def_prop(ctx, obj_idx, DUK_DEFPROP_HAVE_SETTER | DUK_DEFPROP_HAVE_GETTER | DUK_DEFPROP_FORCE); /* attributes always 0 */
+DUK_INTERNAL void duk_xdef_prop_stridx_thrower(duk_hthread *thr, duk_idx_t obj_idx, duk_small_uint_t stridx) {
+ DUK_ASSERT_API_ENTRY(thr);
+
+ obj_idx = duk_require_normalize_index(thr, obj_idx);
+ duk_push_hstring_stridx(thr, stridx);
+ duk_push_hobject_bidx(thr, DUK_BIDX_TYPE_ERROR_THROWER);
+ duk_dup_top(thr);
+ duk_def_prop(thr, obj_idx, DUK_DEFPROP_HAVE_SETTER | DUK_DEFPROP_HAVE_GETTER | DUK_DEFPROP_FORCE); /* attributes always 0 */
}
/* Object.getOwnPropertyDescriptor() equivalent C binding. */
-DUK_EXTERNAL void duk_get_prop_desc(duk_context *ctx, duk_idx_t obj_idx, duk_uint_t flags) {
+DUK_EXTERNAL void duk_get_prop_desc(duk_hthread *thr, duk_idx_t obj_idx, duk_uint_t flags) {
+ DUK_ASSERT_API_ENTRY(thr);
DUK_UNREF(flags); /* no flags defined yet */
- duk_hobject_object_get_own_property_descriptor(ctx, obj_idx); /* [ ... key ] -> [ ... desc ] */
+ duk_hobject_object_get_own_property_descriptor(thr, obj_idx); /* [ ... key ] -> [ ... desc ] */
}
/* Object.defineProperty() equivalent C binding. */
-DUK_EXTERNAL void duk_def_prop(duk_context *ctx, duk_idx_t obj_idx, duk_uint_t flags) {
- duk_hthread *thr = (duk_hthread *) ctx;
+DUK_EXTERNAL void duk_def_prop(duk_hthread *thr, duk_idx_t obj_idx, duk_uint_t flags) {
duk_idx_t idx_base;
duk_hobject *obj;
duk_hstring *key;
@@ -16398,9 +16686,9 @@ DUK_EXTERNAL void duk_def_prop(duk_context *ctx, duk_idx_t obj_idx, duk_uint_t f
duk_uint_t is_data_desc;
duk_uint_t is_acc_desc;
- DUK_ASSERT_CTX_VALID(ctx);
+ DUK_ASSERT_API_ENTRY(thr);
- obj = duk_require_hobject(ctx, obj_idx);
+ obj = duk_require_hobject(thr, obj_idx);
is_data_desc = flags & (DUK_DEFPROP_HAVE_VALUE | DUK_DEFPROP_HAVE_WRITABLE);
is_acc_desc = flags & (DUK_DEFPROP_HAVE_GETTER | DUK_DEFPROP_HAVE_SETTER);
@@ -16412,12 +16700,12 @@ DUK_EXTERNAL void duk_def_prop(duk_context *ctx, duk_idx_t obj_idx, duk_uint_t f
goto fail_invalid_desc;
}
- idx_base = duk_get_top_index(ctx);
+ idx_base = duk_get_top_index(thr);
if (flags & DUK_DEFPROP_HAVE_SETTER) {
- duk_require_type_mask(ctx, idx_base, DUK_TYPE_MASK_UNDEFINED |
+ duk_require_type_mask(thr, idx_base, DUK_TYPE_MASK_UNDEFINED |
DUK_TYPE_MASK_OBJECT |
DUK_TYPE_MASK_LIGHTFUNC);
- set = duk_get_hobject_promote_lfunc(ctx, idx_base);
+ set = duk_get_hobject_promote_lfunc(thr, idx_base);
if (set != NULL && !DUK_HOBJECT_IS_CALLABLE(set)) {
goto fail_not_callable;
}
@@ -16426,10 +16714,10 @@ DUK_EXTERNAL void duk_def_prop(duk_context *ctx, duk_idx_t obj_idx, duk_uint_t f
set = NULL;
}
if (flags & DUK_DEFPROP_HAVE_GETTER) {
- duk_require_type_mask(ctx, idx_base, DUK_TYPE_MASK_UNDEFINED |
+ duk_require_type_mask(thr, idx_base, DUK_TYPE_MASK_UNDEFINED |
DUK_TYPE_MASK_OBJECT |
DUK_TYPE_MASK_LIGHTFUNC);
- get = duk_get_hobject_promote_lfunc(ctx, idx_base);
+ get = duk_get_hobject_promote_lfunc(thr, idx_base);
if (get != NULL && !DUK_HOBJECT_IS_CALLABLE(get)) {
goto fail_not_callable;
}
@@ -16443,12 +16731,12 @@ DUK_EXTERNAL void duk_def_prop(duk_context *ctx, duk_idx_t obj_idx, duk_uint_t f
} else {
idx_value = (duk_idx_t) -1;
}
- key = duk_to_property_key_hstring(ctx, idx_base);
+ key = duk_to_property_key_hstring(thr, idx_base);
DUK_ASSERT(key != NULL);
- duk_require_valid_index(ctx, idx_base);
+ duk_require_valid_index(thr, idx_base);
- duk_hobject_define_property_helper(ctx,
+ duk_hobject_define_property_helper(thr,
flags /*defprop_flags*/,
obj,
key,
@@ -16459,7 +16747,7 @@ DUK_EXTERNAL void duk_def_prop(duk_context *ctx, duk_idx_t obj_idx, duk_uint_t f
/* Clean up stack */
- duk_set_top(ctx, idx_base);
+ duk_set_top(thr, idx_base);
/* [ ... obj ... ] */
@@ -16481,73 +16769,140 @@ DUK_EXTERNAL void duk_def_prop(duk_context *ctx, duk_idx_t obj_idx, duk_uint_t f
* and are not exposed through the API.
*/
-DUK_EXTERNAL void duk_compact(duk_context *ctx, duk_idx_t obj_idx) {
- duk_hthread *thr = (duk_hthread *) ctx;
+DUK_EXTERNAL void duk_compact(duk_hthread *thr, duk_idx_t obj_idx) {
duk_hobject *obj;
- DUK_ASSERT_CTX_VALID(ctx);
+ DUK_ASSERT_API_ENTRY(thr);
- obj = duk_get_hobject(ctx, obj_idx);
+ obj = duk_get_hobject(thr, obj_idx);
if (obj) {
/* Note: this may fail, caller should protect the call if necessary */
duk_hobject_compact_props(thr, obj);
}
}
-DUK_INTERNAL void duk_compact_m1(duk_context *ctx) {
- duk_compact(ctx, -1);
+DUK_INTERNAL void duk_compact_m1(duk_hthread *thr) {
+ DUK_ASSERT_API_ENTRY(thr);
+
+ duk_compact(thr, -1);
}
/* XXX: the duk_hobject_enum.c stack APIs should be reworked */
-DUK_EXTERNAL void duk_enum(duk_context *ctx, duk_idx_t obj_idx, duk_uint_t enum_flags) {
- DUK_ASSERT_CTX_VALID(ctx);
+DUK_EXTERNAL void duk_enum(duk_hthread *thr, duk_idx_t obj_idx, duk_uint_t enum_flags) {
+ DUK_ASSERT_API_ENTRY(thr);
- duk_dup(ctx, obj_idx);
- duk_require_hobject_promote_mask(ctx, -1, DUK_TYPE_MASK_LIGHTFUNC | DUK_TYPE_MASK_BUFFER);
- duk_hobject_enumerator_create(ctx, enum_flags); /* [target] -> [enum] */
+ duk_dup(thr, obj_idx);
+ duk_require_hobject_promote_mask(thr, -1, DUK_TYPE_MASK_LIGHTFUNC | DUK_TYPE_MASK_BUFFER);
+ duk_hobject_enumerator_create(thr, enum_flags); /* [target] -> [enum] */
}
-DUK_EXTERNAL duk_bool_t duk_next(duk_context *ctx, duk_idx_t enum_index, duk_bool_t get_value) {
- DUK_ASSERT_CTX_VALID(ctx);
+DUK_EXTERNAL duk_bool_t duk_next(duk_hthread *thr, duk_idx_t enum_index, duk_bool_t get_value) {
+ DUK_ASSERT_API_ENTRY(thr);
- duk_require_hobject(ctx, enum_index);
- duk_dup(ctx, enum_index);
- return duk_hobject_enumerator_next(ctx, get_value);
+ duk_require_hobject(thr, enum_index);
+ duk_dup(thr, enum_index);
+ return duk_hobject_enumerator_next(thr, get_value);
+}
+
+DUK_INTERNAL void duk_seal_freeze_raw(duk_hthread *thr, duk_idx_t obj_idx, duk_bool_t is_freeze) {
+ duk_tval *tv;
+ duk_hobject *h;
+
+ DUK_ASSERT_API_ENTRY(thr);
+
+ tv = duk_require_tval(thr, obj_idx);
+ DUK_ASSERT(tv != NULL);
+
+ /* Seal/freeze are quite rare in practice so it'd be nice to get the
+ * correct behavior simply via automatic promotion (at the cost of some
+ * memory churn). However, the promoted objects don't behave the same,
+ * e.g. promoted lightfuncs are extensible.
+ */
+
+ switch (DUK_TVAL_GET_TAG(tv)) {
+ case DUK_TAG_BUFFER:
+ /* Plain buffer: already sealed, but not frozen (and can't be frozen
+ * because index properties can't be made non-writable.
+ */
+ if (is_freeze) {
+ goto fail_cannot_freeze;
+ }
+ break;
+ case DUK_TAG_LIGHTFUNC:
+ /* Lightfunc: already sealed and frozen, success. */
+ break;
+ case DUK_TAG_OBJECT:
+ h = DUK_TVAL_GET_OBJECT(tv);
+ DUK_ASSERT(h != NULL);
+ if (is_freeze && DUK_HOBJECT_IS_BUFOBJ(h)) {
+ /* Buffer objects cannot be frozen because there's no internal
+ * support for making virtual array indices non-writable.
+ */
+ DUK_DD(DUK_DDPRINT("cannot freeze a buffer object"));
+ goto fail_cannot_freeze;
+ }
+ duk_hobject_object_seal_freeze_helper(thr, h, is_freeze);
+
+ /* Sealed and frozen objects cannot gain any more properties,
+ * so this is a good time to compact them.
+ */
+ duk_hobject_compact_props(thr, h);
+ break;
+ default:
+ /* ES2015 Sections 19.1.2.5, 19.1.2.17 */
+ break;
+ }
+ return;
+
+ fail_cannot_freeze:
+ DUK_ERROR_TYPE_INVALID_ARGS(thr); /* XXX: proper error message */
+}
+
+DUK_EXTERNAL void duk_seal(duk_hthread *thr, duk_idx_t obj_idx) {
+ DUK_ASSERT_API_ENTRY(thr);
+
+ duk_seal_freeze_raw(thr, obj_idx, 0 /*is_freeze*/);
+}
+
+DUK_EXTERNAL void duk_freeze(duk_hthread *thr, duk_idx_t obj_idx) {
+ DUK_ASSERT_API_ENTRY(thr);
+
+ duk_seal_freeze_raw(thr, obj_idx, 1 /*is_freeze*/);
}
/*
* Helpers for writing multiple properties
*/
-DUK_EXTERNAL void duk_put_function_list(duk_context *ctx, duk_idx_t obj_idx, const duk_function_list_entry *funcs) {
+DUK_EXTERNAL void duk_put_function_list(duk_hthread *thr, duk_idx_t obj_idx, const duk_function_list_entry *funcs) {
const duk_function_list_entry *ent = funcs;
- DUK_ASSERT_CTX_VALID(ctx);
+ DUK_ASSERT_API_ENTRY(thr);
- obj_idx = duk_require_normalize_index(ctx, obj_idx);
+ obj_idx = duk_require_normalize_index(thr, obj_idx);
if (ent != NULL) {
while (ent->key != NULL) {
- duk_push_c_function(ctx, ent->value, ent->nargs);
- duk_put_prop_string(ctx, obj_idx, ent->key);
+ duk_push_c_function(thr, ent->value, ent->nargs);
+ duk_put_prop_string(thr, obj_idx, ent->key);
ent++;
}
}
}
-DUK_EXTERNAL void duk_put_number_list(duk_context *ctx, duk_idx_t obj_idx, const duk_number_list_entry *numbers) {
+DUK_EXTERNAL void duk_put_number_list(duk_hthread *thr, duk_idx_t obj_idx, const duk_number_list_entry *numbers) {
const duk_number_list_entry *ent = numbers;
duk_tval *tv;
- DUK_ASSERT_CTX_VALID(ctx);
+ DUK_ASSERT_API_ENTRY(thr);
- obj_idx = duk_require_normalize_index(ctx, obj_idx);
+ obj_idx = duk_require_normalize_index(thr, obj_idx);
if (ent != NULL) {
while (ent->key != NULL) {
- tv = ((duk_hthread *) ctx)->valstack_top++;
+ tv = thr->valstack_top++;
DUK_ASSERT(DUK_TVAL_IS_UNDEFINED(tv)); /* value stack init policy */
DUK_TVAL_SET_NUMBER_CHKFAST_SLOW(tv, ent->value); /* no need for decref/incref */
- duk_put_prop_string(ctx, obj_idx, ent->key);
+ duk_put_prop_string(thr, obj_idx, ent->key);
ent++;
}
}
@@ -16557,65 +16912,61 @@ DUK_EXTERNAL void duk_put_number_list(duk_context *ctx, duk_idx_t obj_idx, const
* Shortcut for accessing global object properties
*/
-DUK_EXTERNAL duk_bool_t duk_get_global_string(duk_context *ctx, const char *key) {
- duk_hthread *thr = (duk_hthread *) ctx;
+DUK_EXTERNAL duk_bool_t duk_get_global_string(duk_hthread *thr, const char *key) {
duk_bool_t ret;
- DUK_ASSERT_CTX_VALID(ctx);
+ DUK_ASSERT_API_ENTRY(thr);
DUK_ASSERT(thr->builtins[DUK_BIDX_GLOBAL] != NULL);
/* XXX: direct implementation */
- duk_push_hobject(ctx, thr->builtins[DUK_BIDX_GLOBAL]);
- ret = duk_get_prop_string(ctx, -1, key);
- duk_remove_m2(ctx);
+ duk_push_hobject(thr, thr->builtins[DUK_BIDX_GLOBAL]);
+ ret = duk_get_prop_string(thr, -1, key);
+ duk_remove_m2(thr);
return ret;
}
-DUK_EXTERNAL duk_bool_t duk_get_global_lstring(duk_context *ctx, const char *key, duk_size_t key_len) {
- duk_hthread *thr = (duk_hthread *) ctx;
+DUK_EXTERNAL duk_bool_t duk_get_global_lstring(duk_hthread *thr, const char *key, duk_size_t key_len) {
duk_bool_t ret;
- DUK_ASSERT_CTX_VALID(ctx);
+ DUK_ASSERT_API_ENTRY(thr);
DUK_ASSERT(thr->builtins[DUK_BIDX_GLOBAL] != NULL);
/* XXX: direct implementation */
- duk_push_hobject(ctx, thr->builtins[DUK_BIDX_GLOBAL]);
- ret = duk_get_prop_lstring(ctx, -1, key, key_len);
- duk_remove_m2(ctx);
+ duk_push_hobject(thr, thr->builtins[DUK_BIDX_GLOBAL]);
+ ret = duk_get_prop_lstring(thr, -1, key, key_len);
+ duk_remove_m2(thr);
return ret;
}
-DUK_EXTERNAL duk_bool_t duk_put_global_string(duk_context *ctx, const char *key) {
- duk_hthread *thr = (duk_hthread *) ctx;
+DUK_EXTERNAL duk_bool_t duk_put_global_string(duk_hthread *thr, const char *key) {
duk_bool_t ret;
- DUK_ASSERT_CTX_VALID(ctx);
+ DUK_ASSERT_API_ENTRY(thr);
DUK_ASSERT(thr->builtins[DUK_BIDX_GLOBAL] != NULL);
/* XXX: direct implementation */
- duk_push_hobject(ctx, thr->builtins[DUK_BIDX_GLOBAL]);
- duk_insert(ctx, -2);
- ret = duk_put_prop_string(ctx, -2, key); /* [ ... global val ] -> [ ... global ] */
- duk_pop(ctx);
+ duk_push_hobject(thr, thr->builtins[DUK_BIDX_GLOBAL]);
+ duk_insert(thr, -2);
+ ret = duk_put_prop_string(thr, -2, key); /* [ ... global val ] -> [ ... global ] */
+ duk_pop(thr);
return ret;
}
-DUK_EXTERNAL duk_bool_t duk_put_global_lstring(duk_context *ctx, const char *key, duk_size_t key_len) {
- duk_hthread *thr = (duk_hthread *) ctx;
+DUK_EXTERNAL duk_bool_t duk_put_global_lstring(duk_hthread *thr, const char *key, duk_size_t key_len) {
duk_bool_t ret;
- DUK_ASSERT_CTX_VALID(ctx);
+ DUK_ASSERT_API_ENTRY(thr);
DUK_ASSERT(thr->builtins[DUK_BIDX_GLOBAL] != NULL);
/* XXX: direct implementation */
- duk_push_hobject(ctx, thr->builtins[DUK_BIDX_GLOBAL]);
- duk_insert(ctx, -2);
- ret = duk_put_prop_lstring(ctx, -2, key, key_len); /* [ ... global val ] -> [ ... global ] */
- duk_pop(ctx);
+ duk_push_hobject(thr, thr->builtins[DUK_BIDX_GLOBAL]);
+ duk_insert(thr, -2);
+ ret = duk_put_prop_lstring(thr, -2, key, key_len); /* [ ... global val ] -> [ ... global ] */
+ duk_pop(thr);
return ret;
}
@@ -16623,38 +16974,35 @@ DUK_EXTERNAL duk_bool_t duk_put_global_lstring(duk_context *ctx, const char *key
* Object prototype
*/
-DUK_EXTERNAL void duk_get_prototype(duk_context *ctx, duk_idx_t idx) {
- duk_hthread *thr = (duk_hthread *) ctx;
+DUK_EXTERNAL void duk_get_prototype(duk_hthread *thr, duk_idx_t idx) {
duk_hobject *obj;
duk_hobject *proto;
- DUK_ASSERT_CTX_VALID(ctx);
- DUK_UNREF(thr);
+ DUK_ASSERT_API_ENTRY(thr);
- obj = duk_require_hobject(ctx, idx);
+ obj = duk_require_hobject(thr, idx);
DUK_ASSERT(obj != NULL);
/* XXX: shared helper for duk_push_hobject_or_undefined()? */
proto = DUK_HOBJECT_GET_PROTOTYPE(thr->heap, obj);
if (proto) {
- duk_push_hobject(ctx, proto);
+ duk_push_hobject(thr, proto);
} else {
- duk_push_undefined(ctx);
+ duk_push_undefined(thr);
}
}
-DUK_EXTERNAL void duk_set_prototype(duk_context *ctx, duk_idx_t idx) {
- duk_hthread *thr = (duk_hthread *) ctx;
+DUK_EXTERNAL void duk_set_prototype(duk_hthread *thr, duk_idx_t idx) {
duk_hobject *obj;
duk_hobject *proto;
- DUK_ASSERT_CTX_VALID(ctx);
+ DUK_ASSERT_API_ENTRY(thr);
- obj = duk_require_hobject(ctx, idx);
+ obj = duk_require_hobject(thr, idx);
DUK_ASSERT(obj != NULL);
- duk_require_type_mask(ctx, -1, DUK_TYPE_MASK_UNDEFINED |
+ duk_require_type_mask(thr, -1, DUK_TYPE_MASK_UNDEFINED |
DUK_TYPE_MASK_OBJECT);
- proto = duk_get_hobject(ctx, -1);
+ proto = duk_get_hobject(thr, -1);
/* proto can also be NULL here (allowed explicitly) */
#if defined(DUK_USE_ROM_OBJECTS)
@@ -16666,7 +17014,7 @@ DUK_EXTERNAL void duk_set_prototype(duk_context *ctx, duk_idx_t idx) {
DUK_HOBJECT_SET_PROTOTYPE_UPDREF(thr, obj, proto);
- duk_pop(ctx);
+ duk_pop(thr);
}
/*
@@ -16679,21 +17027,21 @@ DUK_EXTERNAL void duk_set_prototype(duk_context *ctx, duk_idx_t idx) {
* XXX: same issue as with Duktape.fin: there's no way to delete the property
* now (just set it to undefined).
*/
-DUK_EXTERNAL void duk_get_finalizer(duk_context *ctx, duk_idx_t idx) {
- DUK_ASSERT_CTX_VALID(ctx);
+DUK_EXTERNAL void duk_get_finalizer(duk_hthread *thr, duk_idx_t idx) {
+ DUK_ASSERT_API_ENTRY(thr);
- duk_get_prop_stridx(ctx, idx, DUK_STRIDX_INT_FINALIZER);
+ duk_get_prop_stridx(thr, idx, DUK_STRIDX_INT_FINALIZER);
}
-DUK_EXTERNAL void duk_set_finalizer(duk_context *ctx, duk_idx_t idx) {
+DUK_EXTERNAL void duk_set_finalizer(duk_hthread *thr, duk_idx_t idx) {
duk_hobject *h;
duk_bool_t callable;
- DUK_ASSERT_CTX_VALID(ctx);
+ DUK_ASSERT_API_ENTRY(thr);
- h = duk_require_hobject(ctx, idx); /* Get before 'put' so that 'idx' is correct. */
- callable = duk_is_callable(ctx, -1);
- duk_put_prop_stridx(ctx, idx, DUK_STRIDX_INT_FINALIZER);
+ h = duk_require_hobject(thr, idx); /* Get before 'put' so that 'idx' is correct. */
+ callable = duk_is_callable(thr, -1);
+ duk_put_prop_stridx(thr, idx, DUK_STRIDX_INT_FINALIZER);
/* In addition to setting the finalizer property, keep a "have
* finalizer" flag in duk_hobject in sync so that refzero can do
@@ -16713,16 +17061,16 @@ DUK_EXTERNAL void duk_set_finalizer(duk_context *ctx, duk_idx_t idx) {
}
}
#else /* DUK_USE_FINALIZER_SUPPORT */
-DUK_EXTERNAL void duk_get_finalizer(duk_context *ctx, duk_idx_t idx) {
- DUK_ASSERT_CTX_VALID(ctx);
+DUK_EXTERNAL void duk_get_finalizer(duk_hthread *thr, duk_idx_t idx) {
+ DUK_ASSERT_API_ENTRY(thr);
DUK_UNREF(idx);
- DUK_ERROR_UNSUPPORTED((duk_hthread *) ctx);
+ DUK_ERROR_UNSUPPORTED(thr);
}
-DUK_EXTERNAL void duk_set_finalizer(duk_context *ctx, duk_idx_t idx) {
- DUK_ASSERT_CTX_VALID(ctx);
+DUK_EXTERNAL void duk_set_finalizer(duk_hthread *thr, duk_idx_t idx) {
+ DUK_ASSERT_API_ENTRY(thr);
DUK_UNREF(idx);
- DUK_ERROR_UNSUPPORTED((duk_hthread *) ctx);
+ DUK_ERROR_UNSUPPORTED(thr);
}
#endif /* DUK_USE_FINALIZER_SUPPORT */
/*
@@ -16743,7 +17091,7 @@ DUK_EXTERNAL void duk_set_finalizer(duk_context *ctx, duk_idx_t idx) {
* Forward declarations
*/
-DUK_LOCAL_DECL duk_idx_t duk__push_c_function_raw(duk_context *ctx, duk_c_function func, duk_idx_t nargs, duk_uint_t flags);
+DUK_LOCAL_DECL duk_idx_t duk__push_c_function_raw(duk_hthread *thr, duk_c_function func, duk_idx_t nargs, duk_uint_t flags, duk_small_uint_t proto_bidx);
/*
* Global state for working around missing variadic macros
@@ -16758,6 +17106,10 @@ DUK_EXTERNAL duk_int_t duk_api_global_line = 0;
* Misc helpers
*/
+DUK_LOCAL const char * const duk__symbol_type_strings[4] = {
+ "hidden", "global", "local", "wellknown"
+};
+
#if !defined(DUK_USE_PACKED_TVAL)
DUK_LOCAL const duk_uint_t duk__type_from_tag[] = {
DUK_TYPE_NUMBER,
@@ -16787,12 +17139,15 @@ DUK_LOCAL const duk_uint_t duk__type_mask_from_tag[] = {
};
#endif /* !DUK_USE_PACKED_TVAL */
+/* Assert that there's room for one value. */
+#define DUK__ASSERT_SPACE() do { \
+ DUK_ASSERT(!(thr->valstack_top >= thr->valstack_end)); \
+ } while (0)
+
/* 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 { \
- DUK_ASSERT(!(thr->valstack_top >= thr->valstack_end)); \
- } while (0)
+#define DUK__CHECK_SPACE() DUK__ASSERT_SPACE()
#else
#define DUK__CHECK_SPACE() do { \
if (DUK_UNLIKELY(thr->valstack_top >= thr->valstack_end)) { \
@@ -16801,17 +17156,48 @@ DUK_LOCAL const duk_uint_t duk__type_mask_from_tag[] = {
} while (0)
#endif
-DUK_LOCAL_DECL duk_heaphdr *duk__get_tagged_heaphdr_raw(duk_context *ctx, duk_idx_t idx, duk_uint_t tag);
+DUK_LOCAL duk_small_uint_t duk__get_symbol_type(duk_hstring *h) {
+ const duk_uint8_t *data;
+ duk_size_t len;
-DUK_LOCAL duk_int_t duk__api_coerce_d2i(duk_context *ctx, duk_idx_t idx, duk_int_t def_value, duk_bool_t require) {
- duk_hthread *thr;
+ DUK_ASSERT(h != NULL);
+ DUK_ASSERT(DUK_HSTRING_HAS_SYMBOL(h));
+ DUK_ASSERT(DUK_HSTRING_GET_BYTELEN(h) >= 1); /* always true, symbol prefix */
+
+ data = (const duk_uint8_t *) DUK_HSTRING_GET_DATA(h);
+ len = DUK_HSTRING_GET_BYTELEN(h);
+ DUK_ASSERT(len >= 1);
+
+ /* XXX: differentiate between 0x82 and 0xff (hidden vs. internal?)? */
+
+ if (data[0] == 0xffU) {
+ return DUK_SYMBOL_TYPE_HIDDEN;
+ } else if (data[0] == 0x82U) {
+ return DUK_SYMBOL_TYPE_HIDDEN;
+ } else if (data[0] == 0x80U) {
+ return DUK_SYMBOL_TYPE_GLOBAL;
+ } else if (data[len - 1] != 0xffU) {
+ return DUK_SYMBOL_TYPE_LOCAL;
+ } else {
+ return DUK_SYMBOL_TYPE_WELLKNOWN;
+ }
+}
+
+DUK_LOCAL const char *duk__get_symbol_type_string(duk_hstring *h) {
+ duk_small_uint_t idx;
+ idx = duk__get_symbol_type(h);
+ DUK_ASSERT(idx < sizeof(duk__symbol_type_strings));
+ return duk__symbol_type_strings[idx];
+}
+
+DUK_LOCAL_DECL duk_heaphdr *duk__get_tagged_heaphdr_raw(duk_hthread *thr, duk_idx_t idx, duk_uint_t tag);
+
+DUK_LOCAL duk_int_t duk__api_coerce_d2i(duk_hthread *thr, duk_idx_t idx, duk_int_t def_value, duk_bool_t require) {
duk_tval *tv;
duk_small_int_t c;
duk_double_t d;
- thr = (duk_hthread *) ctx;
-
- tv = duk_get_tval_or_unused(ctx, idx);
+ tv = duk_get_tval_or_unused(thr, idx);
DUK_ASSERT(tv != NULL);
/*
@@ -16867,17 +17253,14 @@ DUK_LOCAL duk_int_t duk__api_coerce_d2i(duk_context *ctx, duk_idx_t idx, duk_int
return def_value;
}
-DUK_LOCAL duk_uint_t duk__api_coerce_d2ui(duk_context *ctx, duk_idx_t idx, duk_uint_t def_value, duk_bool_t require) {
- duk_hthread *thr;
+DUK_LOCAL duk_uint_t duk__api_coerce_d2ui(duk_hthread *thr, duk_idx_t idx, duk_uint_t def_value, duk_bool_t require) {
duk_tval *tv;
duk_small_int_t c;
duk_double_t d;
/* Same as above but for unsigned int range. */
- thr = (duk_hthread *) ctx;
-
- tv = duk_get_tval_or_unused(ctx, idx);
+ tv = duk_get_tval_or_unused(thr, idx);
DUK_ASSERT(tv != NULL);
#if defined(DUK_USE_FASTINT)
@@ -16930,12 +17313,11 @@ DUK_LOCAL duk_uint_t duk__api_coerce_d2ui(duk_context *ctx, duk_idx_t idx, duk_u
* There's some repetition because of this; keep the functions in sync.
*/
-DUK_EXTERNAL duk_idx_t duk_normalize_index(duk_context *ctx, duk_idx_t idx) {
- duk_hthread *thr = (duk_hthread *) ctx;
+DUK_EXTERNAL duk_idx_t duk_normalize_index(duk_hthread *thr, duk_idx_t idx) {
duk_uidx_t vs_size;
duk_uidx_t uidx;
- DUK_ASSERT_CTX_VALID(ctx);
+ DUK_ASSERT_API_ENTRY(thr);
DUK_ASSERT(DUK_INVALID_INDEX < 0);
/* Care must be taken to avoid pointer wrapping in the index
@@ -16966,12 +17348,11 @@ DUK_EXTERNAL duk_idx_t duk_normalize_index(duk_context *ctx, duk_idx_t idx) {
return DUK_INVALID_INDEX;
}
-DUK_EXTERNAL duk_idx_t duk_require_normalize_index(duk_context *ctx, duk_idx_t idx) {
- duk_hthread *thr = (duk_hthread *) ctx;
+DUK_EXTERNAL duk_idx_t duk_require_normalize_index(duk_hthread *thr, duk_idx_t idx) {
duk_uidx_t vs_size;
duk_uidx_t uidx;
- DUK_ASSERT_CTX_VALID(ctx);
+ DUK_ASSERT_API_ENTRY(thr);
DUK_ASSERT(DUK_INVALID_INDEX < 0);
DUK_ASSERT(thr->valstack_top >= thr->valstack_bottom);
@@ -16995,12 +17376,11 @@ DUK_EXTERNAL duk_idx_t duk_require_normalize_index(duk_context *ctx, duk_idx_t i
return 0; /* unreachable */
}
-DUK_INTERNAL duk_tval *duk_get_tval(duk_context *ctx, duk_idx_t idx) {
- duk_hthread *thr = (duk_hthread *) ctx;
+DUK_INTERNAL duk_tval *duk_get_tval(duk_hthread *thr, duk_idx_t idx) {
duk_uidx_t vs_size;
duk_uidx_t uidx;
- DUK_ASSERT_CTX_VALID(ctx);
+ DUK_ASSERT_API_ENTRY(thr);
DUK_ASSERT(DUK_INVALID_INDEX < 0);
DUK_ASSERT(thr->valstack_top >= thr->valstack_bottom);
@@ -17031,21 +17411,23 @@ DUK_INTERNAL duk_tval *duk_get_tval(duk_context *ctx, duk_idx_t idx) {
*/
DUK_LOCAL const duk_tval_unused duk__const_tval_unused = DUK_TVAL_UNUSED_INITIALIZER();
-DUK_INTERNAL duk_tval *duk_get_tval_or_unused(duk_context *ctx, duk_idx_t idx) {
+DUK_INTERNAL duk_tval *duk_get_tval_or_unused(duk_hthread *thr, duk_idx_t idx) {
duk_tval *tv;
- tv = duk_get_tval(ctx, idx);
+
+ DUK_ASSERT_API_ENTRY(thr);
+
+ tv = duk_get_tval(thr, idx);
if (tv != NULL) {
return tv;
}
return (duk_tval *) DUK_LOSE_CONST(&duk__const_tval_unused);
}
-DUK_INTERNAL duk_tval *duk_require_tval(duk_context *ctx, duk_idx_t idx) {
- duk_hthread *thr = (duk_hthread *) ctx;
+DUK_INTERNAL duk_tval *duk_require_tval(duk_hthread *thr, duk_idx_t idx) {
duk_uidx_t vs_size;
duk_uidx_t uidx;
- DUK_ASSERT_CTX_VALID(ctx);
+ DUK_ASSERT_API_ENTRY(thr);
DUK_ASSERT(DUK_INVALID_INDEX < 0);
DUK_ASSERT(thr->valstack_top >= thr->valstack_bottom);
@@ -17071,21 +17453,19 @@ DUK_INTERNAL duk_tval *duk_require_tval(duk_context *ctx, duk_idx_t idx) {
}
/* Non-critical. */
-DUK_EXTERNAL duk_bool_t duk_is_valid_index(duk_context *ctx, duk_idx_t idx) {
- DUK_ASSERT_CTX_VALID(ctx);
+DUK_EXTERNAL duk_bool_t duk_is_valid_index(duk_hthread *thr, duk_idx_t idx) {
+ DUK_ASSERT_API_ENTRY(thr);
DUK_ASSERT(DUK_INVALID_INDEX < 0);
- return (duk_normalize_index(ctx, idx) >= 0);
+ return (duk_normalize_index(thr, idx) >= 0);
}
/* Non-critical. */
-DUK_EXTERNAL void duk_require_valid_index(duk_context *ctx, duk_idx_t idx) {
- duk_hthread *thr = (duk_hthread *) ctx;
-
- DUK_ASSERT_CTX_VALID(ctx);
+DUK_EXTERNAL void duk_require_valid_index(duk_hthread *thr, duk_idx_t idx) {
+ DUK_ASSERT_API_ENTRY(thr);
DUK_ASSERT(DUK_INVALID_INDEX < 0);
- if (DUK_UNLIKELY(duk_normalize_index(ctx, idx) < 0)) {
+ if (DUK_UNLIKELY(duk_normalize_index(thr, idx) < 0)) {
DUK_ERROR_RANGE_INDEX(thr, idx);
return; /* unreachable */
}
@@ -17095,10 +17475,8 @@ DUK_EXTERNAL void duk_require_valid_index(duk_context *ctx, duk_idx_t idx) {
* Value stack top handling
*/
-DUK_EXTERNAL duk_idx_t duk_get_top(duk_context *ctx) {
- duk_hthread *thr = (duk_hthread *) ctx;
-
- DUK_ASSERT_CTX_VALID(ctx);
+DUK_EXTERNAL duk_idx_t duk_get_top(duk_hthread *thr) {
+ DUK_ASSERT_API_ENTRY(thr);
return (duk_idx_t) (thr->valstack_top - thr->valstack_bottom);
}
@@ -17106,11 +17484,10 @@ DUK_EXTERNAL duk_idx_t duk_get_top(duk_context *ctx) {
/* Internal helper to get current top but to require a minimum top value
* (TypeError if not met).
*/
-DUK_INTERNAL duk_idx_t duk_get_top_require_min(duk_context *ctx, duk_idx_t min_top) {
- duk_hthread *thr = (duk_hthread *) ctx;
+DUK_INTERNAL duk_idx_t duk_get_top_require_min(duk_hthread *thr, duk_idx_t min_top) {
duk_idx_t ret;
- DUK_ASSERT_CTX_VALID(ctx);
+ DUK_ASSERT_API_ENTRY(thr);
ret = (duk_idx_t) (thr->valstack_top - thr->valstack_bottom);
if (DUK_UNLIKELY(ret < min_top)) {
@@ -17123,14 +17500,13 @@ DUK_INTERNAL duk_idx_t duk_get_top_require_min(duk_context *ctx, duk_idx_t min_t
* 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 idx) {
- duk_hthread *thr = (duk_hthread *) ctx;
+DUK_EXTERNAL void duk_set_top(duk_hthread *thr, duk_idx_t idx) {
duk_uidx_t vs_size;
duk_uidx_t vs_limit;
duk_uidx_t uidx;
duk_tval *tv;
- DUK_ASSERT_CTX_VALID(ctx);
+ DUK_ASSERT_API_ENTRY(thr);
DUK_ASSERT(DUK_INVALID_INDEX < 0);
DUK_ASSERT(thr->valstack_top >= thr->valstack_bottom);
@@ -17219,11 +17595,98 @@ DUK_EXTERNAL void duk_set_top(duk_context *ctx, duk_idx_t idx) {
}
}
-DUK_EXTERNAL duk_idx_t duk_get_top_index(duk_context *ctx) {
- duk_hthread *thr = (duk_hthread *) ctx;
+/* Internal variant with a non-negative index and no runtime size checks. */
+#if defined(DUK_USE_PREFER_SIZE)
+DUK_INTERNAL void duk_set_top_unsafe(duk_hthread *thr, duk_idx_t idx) {
+ DUK_ASSERT_API_ENTRY(thr);
+
+ duk_set_top(thr, idx);
+}
+#else /* DUK_USE_PREFER_SIZE */
+DUK_INTERNAL void duk_set_top_unsafe(duk_hthread *thr, duk_idx_t idx) {
+ duk_uidx_t uidx;
+ duk_uidx_t vs_size;
+ duk_tval *tv;
+
+ DUK_ASSERT_API_ENTRY(thr);
+ DUK_ASSERT(thr->valstack_top >= thr->valstack_bottom);
+ DUK_ASSERT(thr->valstack_end >= thr->valstack_bottom);
+ DUK_ASSERT(idx >= 0);
+ DUK_ASSERT(idx <= (duk_idx_t) (thr->valstack_end - thr->valstack_bottom));
+
+ /* XXX: byte arithmetic */
+ uidx = (duk_uidx_t) idx;
+ vs_size = (duk_uidx_t) (thr->valstack_top - thr->valstack_bottom);
+
+ if (uidx >= vs_size) {
+ /* Stack size increases or stays the same. */
+#if defined(DUK_USE_ASSERTIONS)
+ duk_uidx_t count;
+
+ count = uidx - vs_size;
+ while (count != 0) {
+ count--;
+ tv = thr->valstack_top + count;
+ DUK_ASSERT(DUK_TVAL_IS_UNDEFINED(tv));
+ }
+#endif
+ thr->valstack_top = thr->valstack_bottom + uidx;
+ } else {
+ /* Stack size decreases. */
+#if defined(DUK_USE_REFERENCE_COUNTING)
+ duk_uidx_t count;
+ duk_tval *tv_end;
+
+ count = vs_size - uidx;
+ DUK_ASSERT(count > 0);
+ tv = thr->valstack_top;
+ tv_end = tv - count;
+ DUK_ASSERT(tv > tv_end); /* Because count > 0. */
+ do {
+ tv--;
+ DUK_ASSERT(tv >= thr->valstack_bottom);
+ DUK_TVAL_SET_UNDEFINED_UPDREF_NORZ(thr, tv);
+ } while (tv != tv_end);
+ thr->valstack_top = tv_end;
+ DUK_REFZERO_CHECK_FAST(thr);
+#else /* DUK_USE_REFERENCE_COUNTING */
+ duk_uidx_t count;
+ duk_tval *tv_end;
+
+ count = vs_size - uidx;
+ 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 */
+ }
+}
+#endif /* DUK_USE_PREFER_SIZE */
+
+/* Internal helper: set top to 'top', and set [idx_wipe_start,top[ to
+ * 'undefined' (doing nothing if idx_wipe_start == top). Indices are
+ * positive and within value stack reserve. This is used by call handling.
+ */
+DUK_INTERNAL void duk_set_top_and_wipe(duk_hthread *thr, duk_idx_t top, duk_idx_t idx_wipe_start) {
+ DUK_ASSERT_API_ENTRY(thr);
+ DUK_ASSERT(top >= 0);
+ DUK_ASSERT(idx_wipe_start >= 0);
+ DUK_ASSERT(idx_wipe_start <= top);
+ DUK_ASSERT(thr->valstack_bottom + top <= thr->valstack_end);
+ DUK_ASSERT(thr->valstack_bottom + idx_wipe_start <= thr->valstack_end);
+
+ duk_set_top_unsafe(thr, idx_wipe_start);
+ duk_set_top_unsafe(thr, top);
+}
+
+DUK_EXTERNAL duk_idx_t duk_get_top_index(duk_hthread *thr) {
duk_idx_t ret;
- DUK_ASSERT_CTX_VALID(ctx);
+ DUK_ASSERT_API_ENTRY(thr);
ret = (duk_idx_t) (thr->valstack_top - thr->valstack_bottom) - 1;
if (DUK_UNLIKELY(ret < 0)) {
@@ -17239,21 +17702,19 @@ DUK_EXTERNAL duk_idx_t duk_get_top_index(duk_context *ctx) {
/* Internal variant: call assumes there is at least one element on the value
* stack frame; this is only asserted for.
*/
-DUK_INTERNAL duk_idx_t duk_get_top_index_unsafe(duk_context *ctx) {
- duk_hthread *thr = (duk_hthread *) ctx;
+DUK_INTERNAL duk_idx_t duk_get_top_index_unsafe(duk_hthread *thr) {
duk_idx_t ret;
- DUK_ASSERT_CTX_VALID(ctx);
+ DUK_ASSERT_API_ENTRY(thr);
ret = (duk_idx_t) (thr->valstack_top - thr->valstack_bottom) - 1;
return ret;
}
-DUK_EXTERNAL duk_idx_t duk_require_top_index(duk_context *ctx) {
- duk_hthread *thr = (duk_hthread *) ctx;
+DUK_EXTERNAL duk_idx_t duk_require_top_index(duk_hthread *thr) {
duk_idx_t ret;
- DUK_ASSERT_CTX_VALID(ctx);
+ DUK_ASSERT_API_ENTRY(thr);
ret = (duk_idx_t) (thr->valstack_top - thr->valstack_bottom) - 1;
if (DUK_UNLIKELY(ret < 0)) {
@@ -17268,61 +17729,71 @@ DUK_EXTERNAL duk_idx_t duk_require_top_index(duk_context *ctx) {
*
* This resizing happens above the current "top": the value stack can be
* grown or shrunk, but the "top" is not affected. The value stack cannot
- * be resized to a size below the current "top".
+ * be resized to a size below the current reserve.
*
* The low level reallocation primitive must carefully recompute all value
* stack pointers, and must also work if ALL pointers are NULL. The resize
* is quite tricky because the valstack realloc may cause a mark-and-sweep,
* which may run finalizers. Running finalizers may resize the valstack
* recursively (the same value stack we're working on). So, after realloc
- * returns, we know that the valstack "top" should still be the same (there
- * should not be live values above the "top"), but its underlying size and
- * pointer may have changed.
+ * returns, we know that the valstack bottom, top, and reserve should still
+ * be the same (there should not be live values above the "top"), but its
+ * underlying size, alloc_end, and base pointer may have changed.
+ *
+ * 'new_size' is known to be <= DUK_USE_VALSTACK_LIMIT, which ensures that
+ * size_t and pointer arithmetic won't wrap in duk__resize_valstack().
*/
-/* XXX: perhaps refactor this to allow caller to specify some parameters, or
- * at least a 'compact' flag which skips any spare or round-up .. useful for
- * emergency gc.
+/* Low level valstack resize primitive, used for both grow and shrink. All
+ * adjustments for slack etc have already been done. Doesn't throw but does
+ * have allocation side effects.
*/
-
-DUK_LOCAL duk_bool_t duk__resize_valstack(duk_context *ctx, duk_size_t new_size) {
- duk_hthread *thr = (duk_hthread *) ctx;
- duk_ptrdiff_t old_bottom_offset;
- duk_ptrdiff_t old_top_offset;
- duk_ptrdiff_t old_end_offset_post;
-#if defined(DUK_USE_DEBUG)
- duk_ptrdiff_t old_end_offset_pre;
- duk_tval *old_valstack_pre;
- duk_tval *old_valstack_post;
-#endif
+DUK_LOCAL DUK_COLD DUK_NOINLINE duk_bool_t duk__resize_valstack(duk_hthread *thr, duk_size_t new_size) {
+ duk_tval *pre_valstack;
+ duk_tval *pre_bottom;
+ duk_tval *pre_top;
+ duk_tval *pre_end;
+ duk_tval *pre_alloc_end;
+ duk_ptrdiff_t ptr_diff;
duk_tval *new_valstack;
duk_size_t new_alloc_size;
+ duk_tval *tv_prev_alloc_end;
duk_tval *p;
- DUK_ASSERT_CTX_VALID(ctx);
- DUK_ASSERT(thr != NULL);
+ DUK_ASSERT_HTHREAD_VALID(thr);
DUK_ASSERT(thr->valstack_bottom >= thr->valstack);
DUK_ASSERT(thr->valstack_top >= thr->valstack_bottom);
DUK_ASSERT(thr->valstack_end >= thr->valstack_top);
+ DUK_ASSERT(thr->valstack_alloc_end >= thr->valstack_end);
DUK_ASSERT((duk_size_t) (thr->valstack_top - thr->valstack) <= new_size); /* can't resize below 'top' */
- DUK_ASSERT(new_size <= thr->valstack_max); /* valstack limit caller has check, prevents wrapping */
+ DUK_ASSERT(new_size <= DUK_USE_VALSTACK_LIMIT); /* valstack limit caller has check, prevents wrapping */
DUK_ASSERT(new_size <= DUK_SIZE_MAX / sizeof(duk_tval)); /* specific assert for wrapping */
- /* get pointer offsets for tweaking below */
- old_bottom_offset = (((duk_uint8_t *) thr->valstack_bottom) - ((duk_uint8_t *) thr->valstack));
- old_top_offset = (((duk_uint8_t *) thr->valstack_top) - ((duk_uint8_t *) thr->valstack));
-#if defined(DUK_USE_DEBUG)
- old_end_offset_pre = (((duk_uint8_t *) thr->valstack_end) - ((duk_uint8_t *) thr->valstack)); /* not very useful, used for debugging */
- old_valstack_pre = thr->valstack;
-#endif
+ /* Pre-realloc pointer copies for asserts and debug logs. */
+ pre_valstack = thr->valstack;
+ pre_bottom = thr->valstack_bottom;
+ pre_top = thr->valstack_top;
+ pre_end = thr->valstack_end;
+ pre_alloc_end = thr->valstack_alloc_end;
- /* Allocate a new valstack.
- *
- * 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.rst.
+ DUK_UNREF(pre_valstack);
+ DUK_UNREF(pre_bottom);
+ DUK_UNREF(pre_top);
+ DUK_UNREF(pre_end);
+ DUK_UNREF(pre_alloc_end);
+
+ /* If finalizer torture enabled, force base pointer change every time
+ * when it would be allowed.
*/
+#if defined(DUK_USE_FINALIZER_TORTURE)
+ if (thr->heap->pf_prevent_count == 0) {
+ duk_hthread_valstack_torture_realloc(thr);
+ }
+#endif
+ /* Allocate a new valstack using DUK_REALLOC_DIRECT() to deal with
+ * a side effect changing the base pointer.
+ */
new_alloc_size = sizeof(duk_tval) * new_size;
new_valstack = (duk_tval *) DUK_REALLOC_INDIRECT(thr->heap, duk_hthread_get_valstack_ptr, (void *) thr, new_alloc_size);
if (DUK_UNLIKELY(new_valstack == NULL)) {
@@ -17335,69 +17806,78 @@ DUK_LOCAL duk_bool_t duk__resize_valstack(duk_context *ctx, duk_size_t new_size)
return 0;
}
- /* Note: the realloc may have triggered a mark-and-sweep which may
- * have resized our valstack internally. However, the mark-and-sweep
- * MUST NOT leave the stack bottom/top in a different state. Particular
- * assumptions and facts:
- *
- * - The thr->valstack pointer may be different after realloc,
- * and the offset between thr->valstack_end <-> thr->valstack
- * may have changed.
- * - The offset between thr->valstack_bottom <-> thr->valstack
- * and thr->valstack_top <-> thr->valstack MUST NOT have changed,
- * 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, up to the post-realloc valstack_end.
- * - 'old_end_offset' must be computed after realloc to be correct.
- */
-
- DUK_ASSERT((((duk_uint8_t *) thr->valstack_bottom) - ((duk_uint8_t *) thr->valstack)) == old_bottom_offset);
- DUK_ASSERT((((duk_uint8_t *) thr->valstack_top) - ((duk_uint8_t *) thr->valstack)) == old_top_offset);
-
- /* success, fixup pointers */
- old_end_offset_post = (((duk_uint8_t *) thr->valstack_end) - ((duk_uint8_t *) thr->valstack)); /* must be computed after realloc */
+ /* Debug log any changes in pointer(s) by side effects. These don't
+ * necessarily imply any incorrect behavior, but should be rare in
+ * practice.
+ */
#if defined(DUK_USE_DEBUG)
- old_valstack_post = thr->valstack;
+ if (thr->valstack != pre_valstack) {
+ DUK_D(DUK_DPRINT("valstack base pointer changed during valstack resize: %p -> %p",
+ (void *) pre_valstack, (void *) thr->valstack));
+ }
+ if (thr->valstack_bottom != pre_bottom) {
+ DUK_D(DUK_DPRINT("valstack bottom pointer changed during valstack resize: %p -> %p",
+ (void *) pre_bottom, (void *) thr->valstack_bottom));
+ }
+ if (thr->valstack_top != pre_top) {
+ DUK_D(DUK_DPRINT("valstack top pointer changed during valstack resize: %p -> %p",
+ (void *) pre_top, (void *) thr->valstack_top));
+ }
+ if (thr->valstack_end != pre_end) {
+ DUK_D(DUK_DPRINT("valstack end pointer changed during valstack resize: %p -> %p",
+ (void *) pre_end, (void *) thr->valstack_end));
+ }
+ if (thr->valstack_alloc_end != pre_alloc_end) {
+ DUK_D(DUK_DPRINT("valstack alloc_end pointer changed during valstack resize: %p -> %p",
+ (void *) pre_alloc_end, (void *) thr->valstack_alloc_end));
+ }
#endif
+
+ /* Assertions: offsets for bottom, top, and end (reserve) must not
+ * have changed even with side effects because they are always
+ * restored in unwind. For alloc_end there's no guarantee: it may
+ * have grown or shrunk (but remain above 'end').
+ */
+ DUK_ASSERT(thr->valstack_bottom - thr->valstack == pre_bottom - pre_valstack);
+ DUK_ASSERT(thr->valstack_top - thr->valstack == pre_top - pre_valstack);
+ DUK_ASSERT(thr->valstack_end - thr->valstack == pre_end - pre_valstack);
+ DUK_ASSERT(thr->valstack_alloc_end >= thr->valstack_end);
+
+ /* Write new pointers. Most pointers can be handled as a pointer
+ * difference.
+ */
+ ptr_diff = (duk_ptrdiff_t) ((duk_uint8_t *) new_valstack - (duk_uint8_t *) thr->valstack);
+ tv_prev_alloc_end = (duk_tval *) (void *) ((duk_uint8_t *) thr->valstack_alloc_end + ptr_diff);
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);
+ thr->valstack_bottom = (duk_tval *) (void *) ((duk_uint8_t *) thr->valstack_bottom + ptr_diff);
+ thr->valstack_top = (duk_tval *) (void *) ((duk_uint8_t *) thr->valstack_top + ptr_diff);
+ thr->valstack_end = (duk_tval *) (void *) ((duk_uint8_t *) thr->valstack_end + ptr_diff);
+ thr->valstack_alloc_end = (duk_tval *) (void *) ((duk_uint8_t *) new_valstack + new_alloc_size);
+ /* Assertions: pointer sanity after pointer updates. */
DUK_ASSERT(thr->valstack_bottom >= thr->valstack);
DUK_ASSERT(thr->valstack_top >= thr->valstack_bottom);
DUK_ASSERT(thr->valstack_end >= thr->valstack_top);
-
- /* useful for debugging */
-#if defined(DUK_USE_DEBUG)
- if (old_end_offset_pre != old_end_offset_post) {
- DUK_D(DUK_DPRINT("valstack was resized during valstack_resize(), probably by mark-and-sweep; "
- "end offset changed: %lu -> %lu",
- (unsigned long) old_end_offset_pre,
- (unsigned long) old_end_offset_post));
- }
- if (old_valstack_pre != old_valstack_post) {
- DUK_D(DUK_DPRINT("valstack pointer changed during valstack_resize(), probably by mark-and-sweep: %p -> %p",
- (void *) old_valstack_pre,
- (void *) old_valstack_post));
- }
-#endif
-
- DUK_DD(DUK_DDPRINT("resized valstack to %lu elements (%lu bytes), bottom=%ld, top=%ld, "
- "new pointers: start=%p end=%p bottom=%p top=%p",
- (unsigned long) new_size, (unsigned long) new_alloc_size,
- (long) (thr->valstack_bottom - thr->valstack),
- (long) (thr->valstack_top - thr->valstack),
- (void *) thr->valstack, (void *) thr->valstack_end,
- (void *) thr->valstack_bottom, (void *) thr->valstack_top));
-
- /* Init newly allocated slots (only). */
- p = (duk_tval *) (void *) ((duk_uint8_t *) thr->valstack + old_end_offset_post);
- while (p < thr->valstack_end) {
+ DUK_ASSERT(thr->valstack_alloc_end >= thr->valstack_end);
+
+ DUK_D(DUK_DPRINT("resized valstack %lu -> %lu elements (%lu -> %lu bytes): "
+ "base=%p -> %p, bottom=%p -> %p (%ld), top=%p -> %p (%ld), "
+ "end=%p -> %p (%ld), alloc_end=%p -> %p (%ld);"
+ " tv_prev_alloc_end=%p (-> %ld inits; <0 means shrink)",
+ (unsigned long) (pre_alloc_end - pre_valstack),
+ (unsigned long) new_size,
+ (unsigned long) ((duk_uint8_t *) pre_alloc_end - (duk_uint8_t *) pre_valstack),
+ (unsigned long) new_alloc_size,
+ (void *) pre_valstack, (void *) thr->valstack,
+ (void *) pre_bottom, (void *) thr->valstack_bottom, (long) (thr->valstack_bottom - thr->valstack),
+ (void *) pre_top, (void *) thr->valstack_top, (long) (thr->valstack_top - thr->valstack),
+ (void *) pre_end, (void *) thr->valstack_end, (long) (thr->valstack_end - thr->valstack),
+ (void *) pre_alloc_end, (void *) thr->valstack_alloc_end, (long) (thr->valstack_alloc_end - thr->valstack),
+ (void *) tv_prev_alloc_end, (long) (thr->valstack_alloc_end - tv_prev_alloc_end)));
+
+ /* If allocation grew, init any new slots to 'undefined'. */
+ p = tv_prev_alloc_end;
+ while (p < thr->valstack_alloc_end) {
/* Never executed if new size is smaller. */
DUK_TVAL_SET_UNDEFINED(p);
p++;
@@ -17406,7 +17886,7 @@ DUK_LOCAL duk_bool_t duk__resize_valstack(duk_context *ctx, duk_size_t new_size)
/* Assert for value stack initialization policy. */
#if defined(DUK_USE_ASSERTIONS)
p = thr->valstack_top;
- while (p < thr->valstack_end) {
+ while (p < thr->valstack_alloc_end) {
DUK_ASSERT(DUK_TVAL_IS_UNDEFINED(p));
p++;
}
@@ -17415,229 +17895,257 @@ DUK_LOCAL duk_bool_t duk__resize_valstack(duk_context *ctx, duk_size_t new_size)
return 1;
}
-DUK_LOCAL DUK_COLD DUK_NOINLINE duk_bool_t duk__valstack_do_resize(duk_context *ctx,
- duk_size_t min_new_size,
- duk_small_uint_t flags) {
- duk_hthread *thr = (duk_hthread *) ctx;
- duk_size_t old_size;
+DUK_LOCAL DUK_COLD DUK_NOINLINE duk_bool_t duk__valstack_grow(duk_hthread *thr, duk_size_t min_bytes, duk_bool_t throw_on_error) {
+ duk_size_t min_size;
duk_size_t new_size;
- duk_bool_t is_shrink;
- duk_small_uint_t compact_flag = (flags & DUK_VSRESIZE_FLAG_COMPACT);
- duk_small_uint_t throw_flag = (flags & DUK_VSRESIZE_FLAG_THROW);
- DUK_ASSERT_CTX_VALID(ctx);
- DUK_ASSERT(thr != NULL);
- DUK_ASSERT(thr->valstack_bottom >= thr->valstack);
- DUK_ASSERT(thr->valstack_top >= thr->valstack_bottom);
- DUK_ASSERT(thr->valstack_end >= thr->valstack_top);
+ DUK_ASSERT(min_bytes / sizeof(duk_tval) * sizeof(duk_tval) == min_bytes);
+ min_size = min_bytes / sizeof(duk_tval); /* from bytes to slots */
-#if defined(DUK_USE_PREFER_SIZE)
- old_size = (duk_size_t) (thr->valstack_end - thr->valstack);
+#if defined(DUK_USE_VALSTACK_GROW_SHIFT)
+ /* New size is minimum size plus a proportional slack, e.g. shift of
+ * 2 means a 25% slack.
+ */
+ new_size = min_size + (min_size >> DUK_USE_VALSTACK_GROW_SHIFT);
#else
- DUK_ASSERT((duk_size_t) (thr->valstack_end - thr->valstack) == thr->valstack_size);
- old_size = thr->valstack_size;
+ /* New size is tight with no slack. This is sometimes preferred in
+ * low memory environments.
+ */
+ new_size = min_size;
#endif
- if (min_new_size <= old_size) {
- is_shrink = 1;
- } else {
- is_shrink = 0;
- }
-
- new_size = min_new_size;
- if (!compact_flag) {
- if (is_shrink) {
- /* shrink case; leave some spare */
- new_size += DUK_VALSTACK_SHRINK_SPARE;
- }
-
- /* round up roughly to next 'grow step' */
- new_size = (new_size / DUK_VALSTACK_GROW_STEP + 1) * DUK_VALSTACK_GROW_STEP;
- }
-
- DUK_DD(DUK_DDPRINT("want to %s valstack: %lu -> %lu elements (min_new_size %lu)",
- (const char *) (new_size > old_size ? "grow" : "shrink"),
- (unsigned long) old_size, (unsigned long) new_size,
- (unsigned long) min_new_size));
-
- if (DUK_UNLIKELY(new_size > thr->valstack_max)) {
+ if (DUK_UNLIKELY(new_size > DUK_USE_VALSTACK_LIMIT || new_size < min_size /*wrap*/)) {
/* Note: may be triggered even if minimal new_size would not reach the limit,
- * plan limit accordingly (taking DUK_VALSTACK_GROW_STEP into account).
+ * plan limit accordingly.
*/
- if (throw_flag) {
+ if (throw_on_error) {
DUK_ERROR_RANGE(thr, DUK_STR_VALSTACK_LIMIT);
- } else {
- return 0;
}
+ return 0;
}
- /*
- * When resizing the valstack, a mark-and-sweep may be triggered for
- * the allocation of the new valstack. If the mark-and-sweep needs
- * to use our thread for something, it may cause *the same valstack*
- * to be resized recursively. This happens e.g. when mark-and-sweep
- * finalizers are called. This is taken into account carefully in
- * duk__resize_valstack().
- *
- * 'new_size' is known to be <= valstack_max, which ensures that
- * size_t and pointer arithmetic won't wrap in duk__resize_valstack().
- */
-
- if (DUK_UNLIKELY(!duk__resize_valstack(ctx, new_size))) {
- if (is_shrink) {
- DUK_DD(DUK_DDPRINT("valstack resize failed, but is a shrink, ignore"));
- return 1;
- }
-
- DUK_DD(DUK_DDPRINT("valstack resize failed"));
-
- if (throw_flag) {
+ if (duk__resize_valstack(thr, new_size) == 0) {
+ if (throw_on_error) {
DUK_ERROR_ALLOC_FAILED(thr);
- } else {
- return 0;
}
+ return 0;
}
- DUK_DDD(DUK_DDDPRINT("valstack resize successful"));
+ thr->valstack_end = thr->valstack + min_size;
+ DUK_ASSERT(thr->valstack_alloc_end >= thr->valstack_end);
+
return 1;
}
-DUK_INTERNAL duk_bool_t duk_valstack_resize_raw(duk_context *ctx,
- duk_size_t min_new_size,
- duk_small_uint_t flags) {
- duk_hthread *thr = (duk_hthread *) ctx;
- duk_size_t old_size;
+/* Hot, inlined value stack grow check. Because value stack almost never
+ * grows, the actual resize call is in a NOINLINE helper.
+ */
+DUK_INTERNAL DUK_INLINE void duk_valstack_grow_check_throw(duk_hthread *thr, duk_size_t min_bytes) {
+ duk_tval *tv;
- DUK_DDD(DUK_DDDPRINT("check valstack resize: min_new_size=%lu, curr_size=%ld, curr_top=%ld, "
- "curr_bottom=%ld, flags=%lx",
- (unsigned long) min_new_size,
- (long) (thr->valstack_end - thr->valstack),
- (long) (thr->valstack_top - thr->valstack),
- (long) (thr->valstack_bottom - thr->valstack),
- (unsigned long) flags));
+ tv = (duk_tval *) (void *) ((duk_uint8_t *) thr->valstack + min_bytes);
+ if (DUK_LIKELY(thr->valstack_end >= tv)) {
+ return;
+ }
+ if (DUK_LIKELY(thr->valstack_alloc_end >= tv)) {
+ /* Values in [valstack_top,valstack_alloc_end[ are initialized
+ * to 'undefined' so we can just move the end pointer.
+ */
+ thr->valstack_end = tv;
+ return;
+ }
+ (void) duk__valstack_grow(thr, min_bytes, 1 /*throw_on_error*/);
+}
- DUK_ASSERT_CTX_VALID(ctx);
- DUK_ASSERT(thr != NULL);
- DUK_ASSERT(thr->valstack_bottom >= thr->valstack);
- DUK_ASSERT(thr->valstack_top >= thr->valstack_bottom);
- DUK_ASSERT(thr->valstack_end >= thr->valstack_top);
+/* Hot, inlined value stack grow check which doesn't throw. */
+DUK_INTERNAL DUK_INLINE duk_bool_t duk_valstack_grow_check_nothrow(duk_hthread *thr, duk_size_t min_bytes) {
+ duk_tval *tv;
-#if defined(DUK_USE_PREFER_SIZE)
- old_size = (duk_size_t) (thr->valstack_end - thr->valstack);
+ tv = (duk_tval *) (void *) ((duk_uint8_t *) thr->valstack + min_bytes);
+ if (DUK_LIKELY(thr->valstack_end >= tv)) {
+ return 1;
+ }
+ if (DUK_LIKELY(thr->valstack_alloc_end >= tv)) {
+ thr->valstack_end = tv;
+ return 1;
+ }
+ return duk__valstack_grow(thr, min_bytes, 0 /*throw_on_error*/);
+}
+
+/* Value stack shrink check, called from mark-and-sweep. */
+DUK_INTERNAL void duk_valstack_shrink_check_nothrow(duk_hthread *thr, duk_bool_t snug) {
+ duk_size_t alloc_bytes;
+ duk_size_t reserve_bytes;
+ duk_size_t shrink_bytes;
+
+ alloc_bytes = (duk_size_t) ((duk_uint8_t *) thr->valstack_alloc_end - (duk_uint8_t *) thr->valstack);
+ reserve_bytes = (duk_size_t) ((duk_uint8_t *) thr->valstack_end - (duk_uint8_t *) thr->valstack);
+ DUK_ASSERT(alloc_bytes >= reserve_bytes);
+
+ /* We're free to shrink the value stack allocation down to
+ * reserve_bytes but not more. If 'snug' (emergency GC)
+ * shrink whatever we can. Otherwise only shrink if the new
+ * size would be considerably smaller.
+ */
+
+#if defined(DUK_USE_VALSTACK_SHRINK_CHECK_SHIFT)
+ if (snug) {
+ shrink_bytes = reserve_bytes;
+ } else {
+ duk_size_t proportion, slack;
+
+ /* Require that value stack shrinks by at least X% of its
+ * current size. For example, shift of 2 means at least
+ * 25%. The proportion is computed as bytes and may not
+ * be a multiple of sizeof(duk_tval); that's OK here.
+ */
+ proportion = alloc_bytes >> DUK_USE_VALSTACK_SHRINK_CHECK_SHIFT;
+ if (alloc_bytes - reserve_bytes < proportion) {
+ /* Too little would be freed, do nothing. */
+ return;
+ }
+
+ /* Keep a slack after shrinking. The slack is again a
+ * proportion of the current size (the proportion should
+ * of course be smaller than the check proportion above).
+ */
+#if defined(DUK_USE_VALSTACK_SHRINK_SLACK_SHIFT)
+ DUK_ASSERT(DUK_USE_VALSTACK_SHRINK_SLACK_SHIFT > DUK_USE_VALSTACK_SHRINK_CHECK_SHIFT);
+ slack = alloc_bytes >> DUK_USE_VALSTACK_SHRINK_SLACK_SHIFT;
#else
- DUK_ASSERT((duk_size_t) (thr->valstack_end - thr->valstack) == thr->valstack_size);
- old_size = thr->valstack_size;
+ slack = 0;
#endif
+ shrink_bytes = reserve_bytes +
+ slack / sizeof(duk_tval) * sizeof(duk_tval); /* multiple of duk_tval */
+ }
+#else /* DUK_USE_VALSTACK_SHRINK_CHECK_SHIFT */
+ /* Always snug, useful in some low memory environments. */
+ DUK_UNREF(snug);
+ shrink_bytes = reserve_bytes;
+#endif /* DUK_USE_VALSTACK_SHRINK_CHECK_SHIFT */
- if (DUK_LIKELY(min_new_size <= old_size)) {
- if (DUK_LIKELY((flags & DUK_VSRESIZE_FLAG_SHRINK) == 0 ||
- old_size - min_new_size < DUK_VALSTACK_SHRINK_THRESHOLD)) {
- DUK_DDD(DUK_DDDPRINT("no need to grow or shrink valstack"));
- return 1;
- }
+ DUK_D(DUK_DPRINT("valstack shrink check: alloc_bytes=%ld, reserve_bytes=%ld, shrink_bytes=%ld (unvalidated)",
+ (long) alloc_bytes, (long) reserve_bytes, (long) shrink_bytes));
+ DUK_ASSERT(shrink_bytes >= reserve_bytes);
+ if (shrink_bytes >= alloc_bytes) {
+ /* Skip if shrink target is same as current one (or higher,
+ * though that shouldn't happen in practice).
+ */
+ return;
}
+ DUK_ASSERT(shrink_bytes / sizeof(duk_tval) * sizeof(duk_tval) == shrink_bytes);
+
+ DUK_D(DUK_DPRINT("valstack shrink check: decided to shrink, snug: %ld", (long) snug));
- return duk__valstack_do_resize(ctx, min_new_size, flags);
+ duk__resize_valstack(thr, shrink_bytes / sizeof(duk_tval));
}
-DUK_EXTERNAL duk_bool_t duk_check_stack(duk_context *ctx, duk_idx_t extra) {
- duk_hthread *thr = (duk_hthread *) ctx;
- duk_size_t min_new_size;
+DUK_EXTERNAL duk_bool_t duk_check_stack(duk_hthread *thr, duk_idx_t extra) {
+ duk_size_t min_new_bytes;
- DUK_ASSERT_CTX_VALID(ctx);
+ DUK_ASSERT_API_ENTRY(thr);
DUK_ASSERT(thr != NULL);
- if (DUK_UNLIKELY(extra < 0)) {
- /* Clamping to zero makes the API more robust to calling code
- * calculation errors.
- */
- extra = 0;
+ if (DUK_UNLIKELY(extra < 0 || extra > DUK_USE_VALSTACK_LIMIT)) {
+ if (extra < 0) {
+ /* Clamping to zero makes the API more robust to calling code
+ * calculation errors.
+ */
+ extra = 0;
+ } else {
+ /* Cause grow check to fail without wrapping arithmetic. */
+ extra = DUK_USE_VALSTACK_LIMIT;
+ }
}
- min_new_size = (thr->valstack_top - thr->valstack) + extra + DUK_VALSTACK_INTERNAL_EXTRA;
- return duk_valstack_resize_raw(ctx,
- min_new_size, /* min_new_size */
- 0 /* no shrink */ | /* flags */
- 0 /* no compact */ |
- 0 /* no throw */);
+ min_new_bytes = (duk_size_t) ((duk_uint8_t *) thr->valstack_top - (duk_uint8_t *) thr->valstack) +
+ sizeof(duk_tval) * ((duk_size_t) extra + DUK_VALSTACK_INTERNAL_EXTRA);
+ return duk_valstack_grow_check_nothrow(thr, min_new_bytes);
}
-DUK_EXTERNAL void duk_require_stack(duk_context *ctx, duk_idx_t extra) {
- duk_hthread *thr = (duk_hthread *) ctx;
- duk_size_t min_new_size;
+DUK_EXTERNAL void duk_require_stack(duk_hthread *thr, duk_idx_t extra) {
+ duk_size_t min_new_bytes;
- DUK_ASSERT_CTX_VALID(ctx);
+ DUK_ASSERT_API_ENTRY(thr);
DUK_ASSERT(thr != NULL);
- if (DUK_UNLIKELY(extra < 0)) {
- /* Clamping to zero makes the API more robust to calling code
- * calculation errors.
- */
- extra = 0;
+ if (DUK_UNLIKELY(extra < 0 || extra > DUK_USE_VALSTACK_LIMIT)) {
+ if (extra < 0) {
+ /* Clamping to zero makes the API more robust to calling code
+ * calculation errors.
+ */
+ extra = 0;
+ } else {
+ /* Cause grow check to fail without wrapping arithmetic. */
+ extra = DUK_USE_VALSTACK_LIMIT;
+ }
}
- min_new_size = (thr->valstack_top - thr->valstack) + extra + DUK_VALSTACK_INTERNAL_EXTRA;
- (void) duk_valstack_resize_raw(ctx,
- min_new_size, /* min_new_size */
- 0 /* no shrink */ | /* flags */
- 0 /* no compact */ |
- DUK_VSRESIZE_FLAG_THROW);
+ min_new_bytes = (duk_size_t) ((duk_uint8_t *) thr->valstack_top - (duk_uint8_t *) thr->valstack) +
+ sizeof(duk_tval) * ((duk_size_t) extra + DUK_VALSTACK_INTERNAL_EXTRA);
+ duk_valstack_grow_check_throw(thr, min_new_bytes);
}
-DUK_EXTERNAL duk_bool_t duk_check_stack_top(duk_context *ctx, duk_idx_t top) {
- duk_size_t min_new_size;
+DUK_EXTERNAL duk_bool_t duk_check_stack_top(duk_hthread *thr, duk_idx_t top) {
+ duk_size_t min_new_bytes;
- DUK_ASSERT_CTX_VALID(ctx);
+ DUK_ASSERT_API_ENTRY(thr);
- if (DUK_UNLIKELY(top < 0)) {
- /* Clamping to zero makes the API more robust to calling code
- * calculation errors.
- */
- top = 0;
+ if (DUK_UNLIKELY(top < 0 || top > DUK_USE_VALSTACK_LIMIT)) {
+ if (top < 0) {
+ /* Clamping to zero makes the API more robust to calling code
+ * calculation errors.
+ */
+ top = 0;
+ } else {
+ /* Cause grow check to fail without wrapping arithmetic. */
+ top = DUK_USE_VALSTACK_LIMIT;
+ }
}
- min_new_size = top + DUK_VALSTACK_INTERNAL_EXTRA;
- return duk_valstack_resize_raw(ctx,
- min_new_size, /* min_new_size */
- 0 /* no shrink */ | /* flags */
- 0 /* no compact */ |
- 0 /* no throw */);
+ DUK_ASSERT(top >= 0);
+ min_new_bytes = (duk_size_t) ((duk_uint8_t *) thr->valstack_bottom - (duk_uint8_t *) thr->valstack) +
+ sizeof(duk_tval) * ((duk_size_t) top + DUK_VALSTACK_INTERNAL_EXTRA);
+ return duk_valstack_grow_check_nothrow(thr, min_new_bytes);
}
-DUK_EXTERNAL void duk_require_stack_top(duk_context *ctx, duk_idx_t top) {
- duk_size_t min_new_size;
+DUK_EXTERNAL void duk_require_stack_top(duk_hthread *thr, duk_idx_t top) {
+ duk_size_t min_new_bytes;
- DUK_ASSERT_CTX_VALID(ctx);
+ DUK_ASSERT_API_ENTRY(thr);
- if (DUK_UNLIKELY(top < 0)) {
- /* Clamping to zero makes the API more robust to calling code
- * calculation errors.
- */
- top = 0;
+ if (DUK_UNLIKELY(top < 0 || top > DUK_USE_VALSTACK_LIMIT)) {
+ if (top < 0) {
+ /* Clamping to zero makes the API more robust to calling code
+ * calculation errors.
+ */
+ top = 0;
+ } else {
+ /* Cause grow check to fail without wrapping arithmetic. */
+ top = DUK_USE_VALSTACK_LIMIT;
+ }
}
- min_new_size = top + DUK_VALSTACK_INTERNAL_EXTRA;
- (void) duk_valstack_resize_raw(ctx,
- min_new_size, /* min_new_size */
- 0 /* no shrink */ | /* flags */
- 0 /* no compact */ |
- DUK_VSRESIZE_FLAG_THROW);
+ DUK_ASSERT(top >= 0);
+ min_new_bytes = (duk_size_t) ((duk_uint8_t *) thr->valstack_bottom - (duk_uint8_t *) thr->valstack) +
+ sizeof(duk_tval) * ((duk_size_t) top + DUK_VALSTACK_INTERNAL_EXTRA);
+ duk_valstack_grow_check_throw(thr, min_new_bytes);
}
/*
* Basic stack manipulation: swap, dup, insert, replace, etc
*/
-DUK_EXTERNAL void duk_swap(duk_context *ctx, duk_idx_t idx1, duk_idx_t idx2) {
+DUK_EXTERNAL void duk_swap(duk_hthread *thr, duk_idx_t idx1, duk_idx_t idx2) {
duk_tval *tv1;
duk_tval *tv2;
duk_tval tv_tmp;
- DUK_ASSERT_CTX_VALID(ctx);
+ DUK_ASSERT_API_ENTRY(thr);
- tv1 = duk_require_tval(ctx, idx1);
+ tv1 = duk_require_tval(thr, idx1);
DUK_ASSERT(tv1 != NULL);
- tv2 = duk_require_tval(ctx, idx2);
+ tv2 = duk_require_tval(thr, idx2);
DUK_ASSERT(tv2 != NULL);
/* If tv1==tv2 this is a NOP, no check is needed */
@@ -17646,22 +18154,20 @@ DUK_EXTERNAL void duk_swap(duk_context *ctx, duk_idx_t idx1, duk_idx_t idx2) {
DUK_TVAL_SET_TVAL(tv2, &tv_tmp);
}
-DUK_EXTERNAL void duk_swap_top(duk_context *ctx, duk_idx_t idx) {
- DUK_ASSERT_CTX_VALID(ctx);
+DUK_EXTERNAL void duk_swap_top(duk_hthread *thr, duk_idx_t idx) {
+ DUK_ASSERT_API_ENTRY(thr);
- duk_swap(ctx, idx, -1);
+ duk_swap(thr, idx, -1);
}
-DUK_EXTERNAL void duk_dup(duk_context *ctx, duk_idx_t from_idx) {
- duk_hthread *thr;
+DUK_EXTERNAL void duk_dup(duk_hthread *thr, duk_idx_t from_idx) {
duk_tval *tv_from;
duk_tval *tv_to;
- DUK_ASSERT_CTX_VALID(ctx);
- thr = (duk_hthread *) ctx;
+ DUK_ASSERT_API_ENTRY(thr);
DUK__CHECK_SPACE();
- tv_from = duk_require_tval(ctx, from_idx);
+ tv_from = duk_require_tval(thr, from_idx);
tv_to = thr->valstack_top++;
DUK_ASSERT(tv_from != NULL);
DUK_ASSERT(tv_to != NULL);
@@ -17669,16 +18175,14 @@ DUK_EXTERNAL void duk_dup(duk_context *ctx, duk_idx_t from_idx) {
DUK_TVAL_INCREF(thr, tv_to); /* no side effects */
}
-DUK_EXTERNAL void duk_dup_top(duk_context *ctx) {
+DUK_EXTERNAL void duk_dup_top(duk_hthread *thr) {
#if defined(DUK_USE_PREFER_SIZE)
- duk_dup(ctx, -1);
+ duk_dup(thr, -1);
#else
- duk_hthread *thr;
duk_tval *tv_from;
duk_tval *tv_to;
- DUK_ASSERT_CTX_VALID(ctx);
- thr = (duk_hthread *) ctx;
+ DUK_ASSERT_API_ENTRY(thr);
DUK__CHECK_SPACE();
if (DUK_UNLIKELY(thr->valstack_top - thr->valstack_bottom <= 0)) {
@@ -17694,36 +18198,42 @@ DUK_EXTERNAL void duk_dup_top(duk_context *ctx) {
#endif
}
-DUK_INTERNAL void duk_dup_0(duk_context *ctx) {
- duk_dup(ctx, 0);
+DUK_INTERNAL void duk_dup_0(duk_hthread *thr) {
+ DUK_ASSERT_API_ENTRY(thr);
+ duk_dup(thr, 0);
}
-DUK_INTERNAL void duk_dup_1(duk_context *ctx) {
- duk_dup(ctx, 1);
+DUK_INTERNAL void duk_dup_1(duk_hthread *thr) {
+ DUK_ASSERT_API_ENTRY(thr);
+ duk_dup(thr, 1);
}
-DUK_INTERNAL void duk_dup_2(duk_context *ctx) {
- duk_dup(ctx, 2);
+DUK_INTERNAL void duk_dup_2(duk_hthread *thr) {
+ DUK_ASSERT_API_ENTRY(thr);
+ duk_dup(thr, 2);
}
-DUK_INTERNAL void duk_dup_m2(duk_context *ctx) {
- duk_dup(ctx, -2);
+DUK_INTERNAL void duk_dup_m2(duk_hthread *thr) {
+ DUK_ASSERT_API_ENTRY(thr);
+ duk_dup(thr, -2);
}
-DUK_INTERNAL void duk_dup_m3(duk_context *ctx) {
- duk_dup(ctx, -3);
+DUK_INTERNAL void duk_dup_m3(duk_hthread *thr) {
+ DUK_ASSERT_API_ENTRY(thr);
+ duk_dup(thr, -3);
}
-DUK_INTERNAL void duk_dup_m4(duk_context *ctx) {
- duk_dup(ctx, -4);
+DUK_INTERNAL void duk_dup_m4(duk_hthread *thr) {
+ DUK_ASSERT_API_ENTRY(thr);
+ duk_dup(thr, -4);
}
-DUK_EXTERNAL void duk_insert(duk_context *ctx, duk_idx_t to_idx) {
+DUK_EXTERNAL void duk_insert(duk_hthread *thr, duk_idx_t to_idx) {
duk_tval *p;
duk_tval *q;
duk_tval tv_tmp;
duk_size_t nbytes;
- DUK_ASSERT_CTX_VALID(ctx);
+ DUK_ASSERT_API_ENTRY(thr);
- p = duk_require_tval(ctx, to_idx);
+ p = duk_require_tval(thr, to_idx);
DUK_ASSERT(p != NULL);
- q = duk_require_tval(ctx, -1);
+ q = duk_require_tval(thr, -1);
DUK_ASSERT(q != NULL);
DUK_ASSERT(q >= p);
@@ -17753,21 +18263,43 @@ DUK_EXTERNAL void duk_insert(duk_context *ctx, duk_idx_t to_idx) {
}
}
-DUK_EXTERNAL void duk_replace(duk_context *ctx, duk_idx_t to_idx) {
- duk_hthread *thr = (duk_hthread *) ctx;
+DUK_INTERNAL void duk_insert_undefined(duk_hthread *thr, duk_idx_t idx) {
+ DUK_ASSERT_API_ENTRY(thr);
+ DUK_ASSERT(idx >= 0); /* Doesn't support negative indices. */
+
+ duk_push_undefined(thr);
+ duk_insert(thr, idx);
+}
+
+DUK_INTERNAL void duk_insert_undefined_n(duk_hthread *thr, duk_idx_t idx, duk_idx_t count) {
+ duk_tval *tv, *tv_end;
+
+ DUK_ASSERT_API_ENTRY(thr);
+ DUK_ASSERT(idx >= 0); /* Doesn't support negative indices or count. */
+ DUK_ASSERT(count >= 0);
+
+ tv = duk_reserve_gap(thr, idx, count);
+ tv_end = tv + count;
+ while (tv != tv_end) {
+ DUK_TVAL_SET_UNDEFINED(tv);
+ tv++;
+ }
+}
+
+DUK_EXTERNAL void duk_replace(duk_hthread *thr, duk_idx_t to_idx) {
duk_tval *tv1;
duk_tval *tv2;
duk_tval tv_tmp;
- DUK_ASSERT_CTX_VALID(ctx);
+ DUK_ASSERT_API_ENTRY(thr);
- tv1 = duk_require_tval(ctx, -1);
+ tv1 = duk_require_tval(thr, -1);
DUK_ASSERT(tv1 != NULL);
- tv2 = duk_require_tval(ctx, to_idx);
+ tv2 = duk_require_tval(thr, to_idx);
DUK_ASSERT(tv2 != NULL);
/* For tv1 == tv2, both pointing to stack top, the end result
- * is same as duk_pop(ctx).
+ * is same as duk_pop(thr).
*/
DUK_TVAL_SET_TVAL(&tv_tmp, tv2);
DUK_TVAL_SET_TVAL(tv2, tv1);
@@ -17776,25 +18308,22 @@ DUK_EXTERNAL void duk_replace(duk_context *ctx, duk_idx_t to_idx) {
DUK_TVAL_DECREF(thr, &tv_tmp); /* side effects */
}
-DUK_EXTERNAL void duk_copy(duk_context *ctx, duk_idx_t from_idx, duk_idx_t to_idx) {
- duk_hthread *thr = (duk_hthread *) ctx;
+DUK_EXTERNAL void duk_copy(duk_hthread *thr, duk_idx_t from_idx, duk_idx_t to_idx) {
duk_tval *tv1;
duk_tval *tv2;
- DUK_ASSERT_CTX_VALID(ctx);
- DUK_UNREF(thr); /* w/o refcounting */
+ DUK_ASSERT_API_ENTRY(thr);
- tv1 = duk_require_tval(ctx, from_idx);
+ tv1 = duk_require_tval(thr, from_idx);
DUK_ASSERT(tv1 != NULL);
- tv2 = duk_require_tval(ctx, to_idx);
+ tv2 = duk_require_tval(thr, to_idx);
DUK_ASSERT(tv2 != NULL);
/* For tv1 == tv2, this is a no-op (no explicit check needed). */
DUK_TVAL_SET_TVAL_UPDREF(thr, tv2, tv1); /* side effects */
}
-DUK_EXTERNAL void duk_remove(duk_context *ctx, duk_idx_t idx) {
- duk_hthread *thr = (duk_hthread *) ctx;
+DUK_EXTERNAL void duk_remove(duk_hthread *thr, duk_idx_t idx) {
duk_tval *p;
duk_tval *q;
#if defined(DUK_USE_REFERENCE_COUNTING)
@@ -17802,11 +18331,11 @@ DUK_EXTERNAL void duk_remove(duk_context *ctx, duk_idx_t idx) {
#endif
duk_size_t nbytes;
- DUK_ASSERT_CTX_VALID(ctx);
+ DUK_ASSERT_API_ENTRY(thr);
- p = duk_require_tval(ctx, idx);
+ p = duk_require_tval(thr, idx);
DUK_ASSERT(p != NULL);
- q = duk_require_tval(ctx, -1);
+ q = duk_require_tval(thr, -1);
DUK_ASSERT(q != NULL);
DUK_ASSERT(q >= p);
@@ -17833,17 +18362,74 @@ DUK_EXTERNAL void duk_remove(duk_context *ctx, duk_idx_t idx) {
#endif
}
-DUK_INTERNAL_DECL void duk_remove_m2(duk_context *ctx) {
- duk_remove(ctx, -2);
+DUK_INTERNAL void duk_remove_unsafe(duk_hthread *thr, duk_idx_t idx) {
+ DUK_ASSERT_API_ENTRY(thr);
+
+ duk_remove(thr, idx); /* XXX: no optimization for now */
+}
+
+DUK_INTERNAL void duk_remove_m2(duk_hthread *thr) {
+ DUK_ASSERT_API_ENTRY(thr);
+
+ duk_remove(thr, -2);
+}
+
+DUK_INTERNAL void duk_remove_n(duk_hthread *thr, duk_idx_t idx, duk_idx_t count) {
+#if defined(DUK_USE_PREFER_SIZE)
+ /* XXX: maybe too slow even when preferring size? */
+ DUK_ASSERT_API_ENTRY(thr);
+ DUK_ASSERT(count >= 0);
+ DUK_ASSERT(idx >= 0);
+
+ while (count-- > 0) {
+ duk_remove(thr, idx);
+ }
+#else /* DUK_USE_PREFER_SIZE */
+ duk_tval *tv_src;
+ duk_tval *tv_dst;
+ duk_tval *tv_newtop;
+ duk_tval *tv;
+ duk_size_t bytes;
+
+ DUK_ASSERT_API_ENTRY(thr);
+ DUK_ASSERT(count >= 0);
+ DUK_ASSERT(idx >= 0);
+
+ tv_dst = thr->valstack_bottom + idx;
+ DUK_ASSERT(tv_dst <= thr->valstack_top);
+ tv_src = tv_dst + count;
+ DUK_ASSERT(tv_src <= thr->valstack_top);
+ bytes = (duk_size_t) ((duk_uint8_t *) thr->valstack_top - (duk_uint8_t *) tv_src);
+
+ for (tv = tv_dst; tv < tv_src; tv++) {
+ DUK_TVAL_DECREF_NORZ(thr, tv);
+ }
+
+ DUK_MEMMOVE((void *) tv_dst, (const void *) tv_src, bytes);
+
+ tv_newtop = thr->valstack_top - count;
+ for (tv = tv_newtop; tv < thr->valstack_top; tv++) {
+ DUK_TVAL_SET_UNDEFINED(tv);
+ }
+ thr->valstack_top = tv_newtop;
+
+ /* When not preferring size, only NORZ macros are used; caller
+ * is expected to DUK_REFZERO_CHECK().
+ */
+#endif /* DUK_USE_PREFER_SIZE */
+}
+
+DUK_INTERNAL void duk_remove_n_unsafe(duk_hthread *thr, duk_idx_t idx, duk_idx_t count) {
+ DUK_ASSERT_API_ENTRY(thr);
+
+ duk_remove_n(thr, idx, count); /* XXX: no optimization for now */
}
/*
* Stack slice primitives
*/
-DUK_EXTERNAL void duk_xcopymove_raw(duk_context *to_ctx, duk_context *from_ctx, duk_idx_t count, duk_bool_t is_copy) {
- duk_hthread *to_thr = (duk_hthread *) to_ctx;
- duk_hthread *from_thr = (duk_hthread *) from_ctx;
+DUK_EXTERNAL void duk_xcopymove_raw(duk_hthread *to_thr, duk_hthread *from_thr, duk_idx_t count, duk_bool_t is_copy) {
void *src;
duk_size_t nbytes;
duk_tval *p;
@@ -17851,23 +18437,25 @@ DUK_EXTERNAL void duk_xcopymove_raw(duk_context *to_ctx, duk_context *from_ctx,
/* XXX: several pointer comparison issues here */
- DUK_ASSERT_CTX_VALID(to_ctx);
- DUK_ASSERT_CTX_VALID(from_ctx);
- DUK_ASSERT(to_ctx != NULL);
- DUK_ASSERT(from_ctx != NULL);
+ DUK_ASSERT_API_ENTRY(to_thr);
+ DUK_ASSERT_CTX_VALID(to_thr);
+ DUK_ASSERT_CTX_VALID(from_thr);
+ DUK_ASSERT(to_thr->heap == from_thr->heap);
- if (DUK_UNLIKELY(to_ctx == from_ctx)) {
+ if (DUK_UNLIKELY(to_thr == from_thr)) {
DUK_ERROR_TYPE(to_thr, DUK_STR_INVALID_CONTEXT);
return;
}
- if (DUK_UNLIKELY((count < 0) ||
- (count > (duk_idx_t) to_thr->valstack_max))) {
- /* Maximum value check ensures 'nbytes' won't wrap below. */
+ if (DUK_UNLIKELY((duk_uidx_t) count > (duk_uidx_t) DUK_USE_VALSTACK_LIMIT)) {
+ /* Maximum value check ensures 'nbytes' won't wrap below.
+ * Also handles negative count.
+ */
DUK_ERROR_RANGE_INVALID_COUNT(to_thr);
return;
}
+ DUK_ASSERT(count >= 0);
- nbytes = sizeof(duk_tval) * count;
+ nbytes = sizeof(duk_tval) * (duk_size_t) count;
if (DUK_UNLIKELY(nbytes == 0)) {
return;
}
@@ -17880,7 +18468,7 @@ DUK_EXTERNAL void duk_xcopymove_raw(duk_context *to_ctx, duk_context *from_ctx,
DUK_ERROR_RANGE_INVALID_COUNT(to_thr);
}
- /* copy values (no overlap even if to_ctx == from_ctx; that's not
+ /* copy values (no overlap even if to_thr == from_thr; that's not
* allowed now anyway)
*/
DUK_ASSERT(nbytes > 0);
@@ -17910,43 +18498,72 @@ DUK_EXTERNAL void duk_xcopymove_raw(duk_context *to_ctx, duk_context *from_ctx,
}
}
+/* Internal helper: reserve a gap of 'count' elements at 'idx_base' and return a
+ * pointer to the gap. Values in the gap are garbage and MUST be initialized by
+ * the caller before any side effects may occur. The caller must ensure there's
+ * enough stack reserve for 'count' values.
+ */
+DUK_INTERNAL duk_tval *duk_reserve_gap(duk_hthread *thr, duk_idx_t idx_base, duk_idx_t count) {
+ duk_tval *tv_src;
+ duk_tval *tv_dst;
+ duk_size_t gap_bytes;
+ duk_size_t copy_bytes;
+
+ /* Caller is responsible for ensuring there's enough preallocated
+ * value stack.
+ */
+ DUK_ASSERT_API_ENTRY(thr);
+ DUK_ASSERT(count >= 0);
+ DUK_ASSERT((duk_size_t) (thr->valstack_end - thr->valstack_top) >= (duk_size_t) count);
+
+ tv_src = thr->valstack_bottom + idx_base;
+ gap_bytes = (duk_size_t) count * sizeof(duk_tval);
+ tv_dst = (duk_tval *) (void *) ((duk_uint8_t *) tv_src + gap_bytes);
+ copy_bytes = (duk_size_t) ((duk_uint8_t *) thr->valstack_top - (duk_uint8_t *) tv_src);
+ thr->valstack_top = (duk_tval *) (void *) ((duk_uint8_t *) thr->valstack_top + gap_bytes);
+ DUK_MEMMOVE((void *) tv_dst, (const void *) tv_src, copy_bytes);
+
+ /* Values in the gap are left as garbage: caller must fill them in
+ * and INCREF them before any side effects.
+ */
+ return tv_src;
+}
+
/*
* Get/opt/require
*/
-DUK_EXTERNAL void duk_require_undefined(duk_context *ctx, duk_idx_t idx) {
- duk_hthread *thr = (duk_hthread *) ctx;
+DUK_EXTERNAL void duk_require_undefined(duk_hthread *thr, duk_idx_t idx) {
duk_tval *tv;
- DUK_ASSERT_CTX_VALID(ctx);
+ DUK_ASSERT_API_ENTRY(thr);
- tv = duk_get_tval_or_unused(ctx, idx);
+ tv = duk_get_tval_or_unused(thr, idx);
DUK_ASSERT(tv != NULL);
if (DUK_UNLIKELY(!DUK_TVAL_IS_UNDEFINED(tv))) {
DUK_ERROR_REQUIRE_TYPE_INDEX(thr, idx, "undefined", DUK_STR_NOT_UNDEFINED);
}
}
-DUK_EXTERNAL void duk_require_null(duk_context *ctx, duk_idx_t idx) {
- duk_hthread *thr = (duk_hthread *) ctx;
+DUK_EXTERNAL void duk_require_null(duk_hthread *thr, duk_idx_t idx) {
duk_tval *tv;
- DUK_ASSERT_CTX_VALID(ctx);
+ DUK_ASSERT_API_ENTRY(thr);
- tv = duk_get_tval_or_unused(ctx, idx);
+ tv = duk_get_tval_or_unused(thr, idx);
DUK_ASSERT(tv != NULL);
if (DUK_UNLIKELY(!DUK_TVAL_IS_NULL(tv))) {
DUK_ERROR_REQUIRE_TYPE_INDEX(thr, idx, "null", DUK_STR_NOT_NULL);
}
}
-DUK_LOCAL DUK_ALWAYS_INLINE duk_bool_t duk__get_boolean_raw(duk_context *ctx, duk_idx_t idx, duk_bool_t def_value) {
+DUK_LOCAL DUK_ALWAYS_INLINE duk_bool_t duk__get_boolean_raw(duk_hthread *thr, duk_idx_t idx, duk_bool_t def_value) {
duk_bool_t ret;
duk_tval *tv;
- DUK_ASSERT_CTX_VALID(ctx);
+ DUK_ASSERT_CTX_VALID(thr);
- tv = duk_get_tval_or_unused(ctx, idx);
+ tv = duk_get_tval_or_unused(thr, idx);
DUK_ASSERT(tv != NULL);
if (DUK_TVAL_IS_BOOLEAN(tv)) {
ret = DUK_TVAL_GET_BOOLEAN(tv);
@@ -17959,26 +18576,25 @@ DUK_LOCAL DUK_ALWAYS_INLINE duk_bool_t duk__get_boolean_raw(duk_context *ctx, du
return ret;
}
-DUK_EXTERNAL duk_bool_t duk_get_boolean(duk_context *ctx, duk_idx_t idx) {
- DUK_ASSERT_CTX_VALID(ctx);
+DUK_EXTERNAL duk_bool_t duk_get_boolean(duk_hthread *thr, duk_idx_t idx) {
+ DUK_ASSERT_API_ENTRY(thr);
- return duk__get_boolean_raw(ctx, idx, 0); /* default: false */
+ return duk__get_boolean_raw(thr, idx, 0); /* default: false */
}
-DUK_EXTERNAL duk_bool_t duk_get_boolean_default(duk_context *ctx, duk_idx_t idx, duk_bool_t def_value) {
- DUK_ASSERT_CTX_VALID(ctx);
+DUK_EXTERNAL duk_bool_t duk_get_boolean_default(duk_hthread *thr, duk_idx_t idx, duk_bool_t def_value) {
+ DUK_ASSERT_API_ENTRY(thr);
- return duk__get_boolean_raw(ctx, idx, def_value);
+ return duk__get_boolean_raw(thr, idx, def_value);
}
-DUK_EXTERNAL duk_bool_t duk_require_boolean(duk_context *ctx, duk_idx_t idx) {
- duk_hthread *thr = (duk_hthread *) ctx;
+DUK_EXTERNAL duk_bool_t duk_require_boolean(duk_hthread *thr, duk_idx_t idx) {
duk_tval *tv;
duk_bool_t ret;
- DUK_ASSERT_CTX_VALID(ctx);
+ DUK_ASSERT_API_ENTRY(thr);
- tv = duk_get_tval_or_unused(ctx, idx);
+ tv = duk_get_tval_or_unused(thr, idx);
DUK_ASSERT(tv != NULL);
if (DUK_LIKELY(DUK_TVAL_IS_BOOLEAN(tv))) {
ret = DUK_TVAL_GET_BOOLEAN(tv);
@@ -17989,22 +18605,22 @@ DUK_EXTERNAL duk_bool_t duk_require_boolean(duk_context *ctx, duk_idx_t idx) {
}
}
-DUK_EXTERNAL duk_bool_t duk_opt_boolean(duk_context *ctx, duk_idx_t idx, duk_bool_t def_value) {
- DUK_ASSERT_CTX_VALID(ctx);
+DUK_EXTERNAL duk_bool_t duk_opt_boolean(duk_hthread *thr, duk_idx_t idx, duk_bool_t def_value) {
+ DUK_ASSERT_API_ENTRY(thr);
- if (duk_check_type_mask(ctx, idx, DUK_TYPE_MASK_NONE | DUK_TYPE_MASK_UNDEFINED)) {
+ if (duk_check_type_mask(thr, idx, DUK_TYPE_MASK_NONE | DUK_TYPE_MASK_UNDEFINED)) {
return def_value;
}
- return duk_require_boolean(ctx, idx);
+ return duk_require_boolean(thr, idx);
}
-DUK_LOCAL DUK_ALWAYS_INLINE duk_double_t duk__get_number_raw(duk_context *ctx, duk_idx_t idx, duk_double_t def_value) {
+DUK_LOCAL DUK_ALWAYS_INLINE duk_double_t duk__get_number_raw(duk_hthread *thr, duk_idx_t idx, duk_double_t def_value) {
duk_double_union ret;
duk_tval *tv;
- DUK_ASSERT_CTX_VALID(ctx);
+ DUK_ASSERT_CTX_VALID(thr);
- tv = duk_get_tval_or_unused(ctx, idx);
+ tv = duk_get_tval_or_unused(thr, idx);
DUK_ASSERT(tv != NULL);
#if defined(DUK_USE_FASTINT)
if (DUK_TVAL_IS_FASTINT(tv)) {
@@ -18027,22 +18643,23 @@ DUK_LOCAL DUK_ALWAYS_INLINE duk_double_t duk__get_number_raw(duk_context *ctx, d
return ret.d;
}
-DUK_EXTERNAL duk_double_t duk_get_number(duk_context *ctx, duk_idx_t idx) {
- return duk__get_number_raw(ctx, idx, DUK_DOUBLE_NAN); /* default: NaN */
+DUK_EXTERNAL duk_double_t duk_get_number(duk_hthread *thr, duk_idx_t idx) {
+ DUK_ASSERT_API_ENTRY(thr);
+ return duk__get_number_raw(thr, idx, DUK_DOUBLE_NAN); /* default: NaN */
}
-DUK_EXTERNAL duk_double_t duk_get_number_default(duk_context *ctx, duk_idx_t idx, duk_double_t def_value) {
- return duk__get_number_raw(ctx, idx, def_value);
+DUK_EXTERNAL duk_double_t duk_get_number_default(duk_hthread *thr, duk_idx_t idx, duk_double_t def_value) {
+ DUK_ASSERT_API_ENTRY(thr);
+ return duk__get_number_raw(thr, idx, def_value);
}
-DUK_EXTERNAL duk_double_t duk_require_number(duk_context *ctx, duk_idx_t idx) {
- duk_hthread *thr = (duk_hthread *) ctx;
+DUK_EXTERNAL duk_double_t duk_require_number(duk_hthread *thr, duk_idx_t idx) {
duk_tval *tv;
duk_double_union ret;
- DUK_ASSERT_CTX_VALID(ctx);
+ DUK_ASSERT_API_ENTRY(thr);
- tv = duk_get_tval_or_unused(ctx, idx);
+ tv = duk_get_tval_or_unused(thr, idx);
DUK_ASSERT(tv != NULL);
if (DUK_UNLIKELY(!DUK_TVAL_IS_NUMBER(tv))) {
DUK_ERROR_REQUIRE_TYPE_INDEX(thr, idx, "number", DUK_STR_NOT_NUMBER);
@@ -18058,78 +18675,78 @@ DUK_EXTERNAL duk_double_t duk_require_number(duk_context *ctx, duk_idx_t idx) {
return ret.d;
}
-DUK_EXTERNAL duk_double_t duk_opt_number(duk_context *ctx, duk_idx_t idx, duk_double_t def_value) {
- DUK_ASSERT_CTX_VALID(ctx);
+DUK_EXTERNAL duk_double_t duk_opt_number(duk_hthread *thr, duk_idx_t idx, duk_double_t def_value) {
+ DUK_ASSERT_API_ENTRY(thr);
- if (duk_check_type_mask(ctx, idx, DUK_TYPE_MASK_NONE | DUK_TYPE_MASK_UNDEFINED)) {
+ if (duk_check_type_mask(thr, idx, DUK_TYPE_MASK_NONE | DUK_TYPE_MASK_UNDEFINED)) {
/* User provided default is not NaN normalized. */
return def_value;
}
- return duk_require_number(ctx, idx);
+ return duk_require_number(thr, idx);
}
-DUK_EXTERNAL duk_int_t duk_get_int(duk_context *ctx, duk_idx_t idx) {
- DUK_ASSERT_CTX_VALID(ctx);
+DUK_EXTERNAL duk_int_t duk_get_int(duk_hthread *thr, duk_idx_t idx) {
+ DUK_ASSERT_API_ENTRY(thr);
- return (duk_int_t) duk__api_coerce_d2i(ctx, idx, 0 /*def_value*/, 0 /*require*/);
+ return (duk_int_t) duk__api_coerce_d2i(thr, idx, 0 /*def_value*/, 0 /*require*/);
}
-DUK_EXTERNAL duk_uint_t duk_get_uint(duk_context *ctx, duk_idx_t idx) {
- DUK_ASSERT_CTX_VALID(ctx);
+DUK_EXTERNAL duk_uint_t duk_get_uint(duk_hthread *thr, duk_idx_t idx) {
+ DUK_ASSERT_API_ENTRY(thr);
- return (duk_uint_t) duk__api_coerce_d2ui(ctx, idx, 0 /*def_value*/, 0 /*require*/);
+ return (duk_uint_t) duk__api_coerce_d2ui(thr, idx, 0 /*def_value*/, 0 /*require*/);
}
-DUK_EXTERNAL duk_int_t duk_get_int_default(duk_context *ctx, duk_idx_t idx, duk_int_t def_value) {
- DUK_ASSERT_CTX_VALID(ctx);
+DUK_EXTERNAL duk_int_t duk_get_int_default(duk_hthread *thr, duk_idx_t idx, duk_int_t def_value) {
+ DUK_ASSERT_API_ENTRY(thr);
- return (duk_int_t) duk__api_coerce_d2i(ctx, idx, def_value, 0 /*require*/);
+ return (duk_int_t) duk__api_coerce_d2i(thr, idx, def_value, 0 /*require*/);
}
-DUK_EXTERNAL duk_uint_t duk_get_uint_default(duk_context *ctx, duk_idx_t idx, duk_uint_t def_value) {
- DUK_ASSERT_CTX_VALID(ctx);
+DUK_EXTERNAL duk_uint_t duk_get_uint_default(duk_hthread *thr, duk_idx_t idx, duk_uint_t def_value) {
+ DUK_ASSERT_API_ENTRY(thr);
- return (duk_uint_t) duk__api_coerce_d2ui(ctx, idx, def_value, 0 /*require*/);
+ return (duk_uint_t) duk__api_coerce_d2ui(thr, idx, def_value, 0 /*require*/);
}
-DUK_EXTERNAL duk_int_t duk_require_int(duk_context *ctx, duk_idx_t idx) {
- DUK_ASSERT_CTX_VALID(ctx);
+DUK_EXTERNAL duk_int_t duk_require_int(duk_hthread *thr, duk_idx_t idx) {
+ DUK_ASSERT_API_ENTRY(thr);
- return (duk_int_t) duk__api_coerce_d2i(ctx, idx, 0 /*def_value*/, 1 /*require*/);
+ return (duk_int_t) duk__api_coerce_d2i(thr, idx, 0 /*def_value*/, 1 /*require*/);
}
-DUK_EXTERNAL duk_uint_t duk_require_uint(duk_context *ctx, duk_idx_t idx) {
- DUK_ASSERT_CTX_VALID(ctx);
+DUK_EXTERNAL duk_uint_t duk_require_uint(duk_hthread *thr, duk_idx_t idx) {
+ DUK_ASSERT_API_ENTRY(thr);
- return (duk_uint_t) duk__api_coerce_d2ui(ctx, idx, 0 /*def_value*/, 1 /*require*/);
+ return (duk_uint_t) duk__api_coerce_d2ui(thr, idx, 0 /*def_value*/, 1 /*require*/);
}
-DUK_EXTERNAL duk_int_t duk_opt_int(duk_context *ctx, duk_idx_t idx, duk_int_t def_value) {
- DUK_ASSERT_CTX_VALID(ctx);
+DUK_EXTERNAL duk_int_t duk_opt_int(duk_hthread *thr, duk_idx_t idx, duk_int_t def_value) {
+ DUK_ASSERT_API_ENTRY(thr);
- if (duk_check_type_mask(ctx, idx, DUK_TYPE_MASK_NONE | DUK_TYPE_MASK_UNDEFINED)) {
+ if (duk_check_type_mask(thr, idx, DUK_TYPE_MASK_NONE | DUK_TYPE_MASK_UNDEFINED)) {
return def_value;
}
- return duk_require_int(ctx, idx);
+ return duk_require_int(thr, idx);
}
-DUK_EXTERNAL duk_uint_t duk_opt_uint(duk_context *ctx, duk_idx_t idx, duk_uint_t def_value) {
- DUK_ASSERT_CTX_VALID(ctx);
+DUK_EXTERNAL duk_uint_t duk_opt_uint(duk_hthread *thr, duk_idx_t idx, duk_uint_t def_value) {
+ DUK_ASSERT_API_ENTRY(thr);
- if (duk_check_type_mask(ctx, idx, DUK_TYPE_MASK_NONE | DUK_TYPE_MASK_UNDEFINED)) {
+ if (duk_check_type_mask(thr, idx, DUK_TYPE_MASK_NONE | DUK_TYPE_MASK_UNDEFINED)) {
return def_value;
}
- return duk_require_uint(ctx, idx);
+ return duk_require_uint(thr, idx);
}
-DUK_EXTERNAL const char *duk_get_lstring(duk_context *ctx, duk_idx_t idx, duk_size_t *out_len) {
+DUK_EXTERNAL const char *duk_get_lstring(duk_hthread *thr, duk_idx_t idx, duk_size_t *out_len) {
duk_hstring *h;
const char *ret;
duk_size_t len;
- DUK_ASSERT_CTX_VALID(ctx);
+ DUK_ASSERT_API_ENTRY(thr);
- h = duk_get_hstring(ctx, idx);
+ h = duk_get_hstring(thr, idx);
if (h != NULL) {
len = DUK_HSTRING_GET_BYTELEN(h);
ret = (const char *) DUK_HSTRING_GET_DATA(h);
@@ -18144,12 +18761,12 @@ DUK_EXTERNAL const char *duk_get_lstring(duk_context *ctx, duk_idx_t idx, duk_si
return ret;
}
-DUK_EXTERNAL const char *duk_require_lstring(duk_context *ctx, duk_idx_t idx, duk_size_t *out_len) {
+DUK_EXTERNAL const char *duk_require_lstring(duk_hthread *thr, duk_idx_t idx, duk_size_t *out_len) {
duk_hstring *h;
- DUK_ASSERT_CTX_VALID(ctx);
+ DUK_ASSERT_API_ENTRY(thr);
- h = duk_require_hstring(ctx, idx);
+ h = duk_require_hstring(thr, idx);
DUK_ASSERT(h != NULL);
if (out_len) {
*out_len = DUK_HSTRING_GET_BYTELEN(h);
@@ -18157,12 +18774,12 @@ DUK_EXTERNAL const char *duk_require_lstring(duk_context *ctx, duk_idx_t idx, du
return (const char *) DUK_HSTRING_GET_DATA(h);
}
-DUK_INTERNAL const char *duk_require_lstring_notsymbol(duk_context *ctx, duk_idx_t idx, duk_size_t *out_len) {
+DUK_INTERNAL const char *duk_require_lstring_notsymbol(duk_hthread *thr, duk_idx_t idx, duk_size_t *out_len) {
duk_hstring *h;
- DUK_ASSERT_CTX_VALID(ctx);
+ DUK_ASSERT_API_ENTRY(thr);
- h = duk_require_hstring_notsymbol(ctx, idx);
+ h = duk_require_hstring_notsymbol(thr, idx);
DUK_ASSERT(h != NULL);
if (out_len) {
*out_len = DUK_HSTRING_GET_BYTELEN(h);
@@ -18170,12 +18787,12 @@ DUK_INTERNAL const char *duk_require_lstring_notsymbol(duk_context *ctx, duk_idx
return (const char *) DUK_HSTRING_GET_DATA(h);
}
-DUK_EXTERNAL const char *duk_get_string(duk_context *ctx, duk_idx_t idx) {
+DUK_EXTERNAL const char *duk_get_string(duk_hthread *thr, duk_idx_t idx) {
duk_hstring *h;
- DUK_ASSERT_CTX_VALID(ctx);
+ DUK_ASSERT_API_ENTRY(thr);
- h = duk_get_hstring(ctx, idx);
+ h = duk_get_hstring(thr, idx);
if (h != NULL) {
return (const char *) DUK_HSTRING_GET_DATA(h);
} else {
@@ -18183,35 +18800,35 @@ DUK_EXTERNAL const char *duk_get_string(duk_context *ctx, duk_idx_t idx) {
}
}
-DUK_EXTERNAL const char *duk_opt_lstring(duk_context *ctx, duk_idx_t idx, duk_size_t *out_len, const char *def_ptr, duk_size_t def_len) {
- DUK_ASSERT_CTX_VALID(ctx);
+DUK_EXTERNAL const char *duk_opt_lstring(duk_hthread *thr, duk_idx_t idx, duk_size_t *out_len, const char *def_ptr, duk_size_t def_len) {
+ DUK_ASSERT_API_ENTRY(thr);
- if (duk_check_type_mask(ctx, idx, DUK_TYPE_MASK_NONE | DUK_TYPE_MASK_UNDEFINED)) {
+ if (duk_check_type_mask(thr, idx, DUK_TYPE_MASK_NONE | DUK_TYPE_MASK_UNDEFINED)) {
if (out_len != NULL) {
*out_len = def_len;
}
return def_ptr;
}
- return duk_require_lstring(ctx, idx, out_len);
+ return duk_require_lstring(thr, idx, out_len);
}
-DUK_EXTERNAL const char *duk_opt_string(duk_context *ctx, duk_idx_t idx, const char *def_ptr) {
- DUK_ASSERT_CTX_VALID(ctx);
+DUK_EXTERNAL const char *duk_opt_string(duk_hthread *thr, duk_idx_t idx, const char *def_ptr) {
+ DUK_ASSERT_API_ENTRY(thr);
- if (duk_check_type_mask(ctx, idx, DUK_TYPE_MASK_NONE | DUK_TYPE_MASK_UNDEFINED)) {
+ if (duk_check_type_mask(thr, idx, DUK_TYPE_MASK_NONE | DUK_TYPE_MASK_UNDEFINED)) {
return def_ptr;
}
- return duk_require_string(ctx, idx);
+ return duk_require_string(thr, idx);
}
-DUK_EXTERNAL const char *duk_get_lstring_default(duk_context *ctx, duk_idx_t idx, duk_size_t *out_len, const char *def_ptr, duk_size_t def_len) {
+DUK_EXTERNAL const char *duk_get_lstring_default(duk_hthread *thr, duk_idx_t idx, duk_size_t *out_len, const char *def_ptr, duk_size_t def_len) {
duk_hstring *h;
const char *ret;
duk_size_t len;
- DUK_ASSERT_CTX_VALID(ctx);
+ DUK_ASSERT_API_ENTRY(thr);
- h = duk_get_hstring(ctx, idx);
+ h = duk_get_hstring(thr, idx);
if (h != NULL) {
len = DUK_HSTRING_GET_BYTELEN(h);
ret = (const char *) DUK_HSTRING_GET_DATA(h);
@@ -18226,12 +18843,12 @@ DUK_EXTERNAL const char *duk_get_lstring_default(duk_context *ctx, duk_idx_t idx
return ret;
}
-DUK_EXTERNAL const char *duk_get_string_default(duk_context *ctx, duk_idx_t idx, const char *def_value) {
+DUK_EXTERNAL const char *duk_get_string_default(duk_hthread *thr, duk_idx_t idx, const char *def_value) {
duk_hstring *h;
- DUK_ASSERT_CTX_VALID(ctx);
+ DUK_ASSERT_API_ENTRY(thr);
- h = duk_get_hstring(ctx, idx);
+ h = duk_get_hstring(thr, idx);
if (h != NULL) {
return (const char *) DUK_HSTRING_GET_DATA(h);
} else {
@@ -18239,12 +18856,12 @@ DUK_EXTERNAL const char *duk_get_string_default(duk_context *ctx, duk_idx_t idx,
}
}
-DUK_INTERNAL const char *duk_get_string_notsymbol(duk_context *ctx, duk_idx_t idx) {
+DUK_INTERNAL const char *duk_get_string_notsymbol(duk_hthread *thr, duk_idx_t idx) {
duk_hstring *h;
- DUK_ASSERT_CTX_VALID(ctx);
+ DUK_ASSERT_API_ENTRY(thr);
- h = duk_get_hstring_notsymbol(ctx, idx);
+ h = duk_get_hstring_notsymbol(thr, idx);
if (h) {
return (const char *) DUK_HSTRING_GET_DATA(h);
} else {
@@ -18252,29 +18869,41 @@ DUK_INTERNAL const char *duk_get_string_notsymbol(duk_context *ctx, duk_idx_t id
}
}
-DUK_EXTERNAL const char *duk_require_string(duk_context *ctx, duk_idx_t idx) {
- DUK_ASSERT_CTX_VALID(ctx);
+DUK_EXTERNAL const char *duk_require_string(duk_hthread *thr, duk_idx_t idx) {
+ DUK_ASSERT_API_ENTRY(thr);
- return duk_require_lstring(ctx, idx, NULL);
+ return duk_require_lstring(thr, idx, NULL);
}
-DUK_INTERNAL const char *duk_require_string_notsymbol(duk_context *ctx, duk_idx_t idx) {
+DUK_INTERNAL const char *duk_require_string_notsymbol(duk_hthread *thr, duk_idx_t idx) {
duk_hstring *h;
- DUK_ASSERT_CTX_VALID(ctx);
+ DUK_ASSERT_API_ENTRY(thr);
- h = duk_require_hstring_notsymbol(ctx, idx);
+ h = duk_require_hstring_notsymbol(thr, idx);
DUK_ASSERT(h != NULL);
return (const char *) DUK_HSTRING_GET_DATA(h);
}
-DUK_LOCAL void *duk__get_pointer_raw(duk_context *ctx, duk_idx_t idx, void *def_value) {
+DUK_EXTERNAL void duk_require_object(duk_hthread *thr, duk_idx_t idx) {
+ duk_tval *tv;
+
+ DUK_ASSERT_API_ENTRY(thr);
+
+ tv = duk_get_tval_or_unused(thr, idx);
+ DUK_ASSERT(tv != NULL);
+ if (DUK_UNLIKELY(!DUK_TVAL_IS_OBJECT(tv))) {
+ DUK_ERROR_REQUIRE_TYPE_INDEX(thr, idx, "object", DUK_STR_NOT_OBJECT);
+ }
+}
+
+DUK_LOCAL void *duk__get_pointer_raw(duk_hthread *thr, duk_idx_t idx, void *def_value) {
duk_tval *tv;
void *p;
- DUK_ASSERT_CTX_VALID(ctx);
+ DUK_ASSERT_CTX_VALID(thr);
- tv = duk_get_tval_or_unused(ctx, idx);
+ tv = duk_get_tval_or_unused(thr, idx);
DUK_ASSERT(tv != NULL);
if (!DUK_TVAL_IS_POINTER(tv)) {
return def_value;
@@ -18284,34 +18913,35 @@ DUK_LOCAL void *duk__get_pointer_raw(duk_context *ctx, duk_idx_t idx, void *def_
return p;
}
-DUK_EXTERNAL void *duk_get_pointer(duk_context *ctx, duk_idx_t idx) {
- return duk__get_pointer_raw(ctx, idx, NULL /*def_value*/);
+DUK_EXTERNAL void *duk_get_pointer(duk_hthread *thr, duk_idx_t idx) {
+ DUK_ASSERT_API_ENTRY(thr);
+ return duk__get_pointer_raw(thr, idx, NULL /*def_value*/);
}
-DUK_EXTERNAL void *duk_opt_pointer(duk_context *ctx, duk_idx_t idx, void *def_value) {
- DUK_ASSERT_CTX_VALID(ctx);
+DUK_EXTERNAL void *duk_opt_pointer(duk_hthread *thr, duk_idx_t idx, void *def_value) {
+ DUK_ASSERT_API_ENTRY(thr);
- if (duk_check_type_mask(ctx, idx, DUK_TYPE_MASK_NONE | DUK_TYPE_MASK_UNDEFINED)) {
+ if (duk_check_type_mask(thr, idx, DUK_TYPE_MASK_NONE | DUK_TYPE_MASK_UNDEFINED)) {
return def_value;
}
- return duk_require_pointer(ctx, idx);
+ return duk_require_pointer(thr, idx);
}
-DUK_EXTERNAL void *duk_get_pointer_default(duk_context *ctx, duk_idx_t idx, void *def_value) {
- return duk__get_pointer_raw(ctx, idx, def_value);
+DUK_EXTERNAL void *duk_get_pointer_default(duk_hthread *thr, duk_idx_t idx, void *def_value) {
+ DUK_ASSERT_API_ENTRY(thr);
+ return duk__get_pointer_raw(thr, idx, def_value);
}
-DUK_EXTERNAL void *duk_require_pointer(duk_context *ctx, duk_idx_t idx) {
- duk_hthread *thr = (duk_hthread *) ctx;
+DUK_EXTERNAL void *duk_require_pointer(duk_hthread *thr, duk_idx_t idx) {
duk_tval *tv;
void *p;
- DUK_ASSERT_CTX_VALID(ctx);
+ DUK_ASSERT_API_ENTRY(thr);
/* Note: here we must be wary of the fact that a pointer may be
* valid and be a NULL.
*/
- tv = duk_get_tval_or_unused(ctx, idx);
+ tv = duk_get_tval_or_unused(thr, idx);
DUK_ASSERT(tv != NULL);
if (DUK_UNLIKELY(!DUK_TVAL_IS_POINTER(tv))) {
DUK_ERROR_REQUIRE_TYPE_INDEX(thr, idx, "pointer", DUK_STR_NOT_POINTER);
@@ -18321,13 +18951,13 @@ DUK_EXTERNAL void *duk_require_pointer(duk_context *ctx, duk_idx_t idx) {
}
#if 0 /*unused*/
-DUK_INTERNAL void *duk_get_voidptr(duk_context *ctx, duk_idx_t idx) {
+DUK_INTERNAL void *duk_get_voidptr(duk_hthread *thr, duk_idx_t idx) {
duk_tval *tv;
duk_heaphdr *h;
- DUK_ASSERT_CTX_VALID(ctx);
+ DUK_ASSERT_API_ENTRY(thr);
- tv = duk_get_tval_or_unused(ctx, idx);
+ tv = duk_get_tval_or_unused(thr, idx);
DUK_ASSERT(tv != NULL);
if (!DUK_TVAL_IS_HEAP_ALLOCATED(tv)) {
return NULL;
@@ -18339,21 +18969,19 @@ DUK_INTERNAL void *duk_get_voidptr(duk_context *ctx, duk_idx_t idx) {
}
#endif
-DUK_LOCAL void *duk__get_buffer_helper(duk_context *ctx, duk_idx_t idx, duk_size_t *out_size, void *def_ptr, duk_size_t def_size, duk_bool_t throw_flag) {
- duk_hthread *thr = (duk_hthread *) ctx;
+DUK_LOCAL void *duk__get_buffer_helper(duk_hthread *thr, duk_idx_t idx, duk_size_t *out_size, void *def_ptr, duk_size_t def_size, duk_bool_t throw_flag) {
duk_hbuffer *h;
void *ret;
duk_size_t len;
duk_tval *tv;
- DUK_ASSERT_CTX_VALID(ctx);
- DUK_UNREF(thr);
+ DUK_ASSERT_CTX_VALID(thr);
if (out_size != NULL) {
*out_size = 0;
}
- tv = duk_get_tval_or_unused(ctx, idx);
+ tv = duk_get_tval_or_unused(thr, idx);
DUK_ASSERT(tv != NULL);
if (DUK_LIKELY(DUK_TVAL_IS_BUFFER(tv))) {
h = DUK_TVAL_GET_BUFFER(tv);
@@ -18375,34 +19003,34 @@ DUK_LOCAL void *duk__get_buffer_helper(duk_context *ctx, duk_idx_t idx, duk_size
return ret;
}
-DUK_EXTERNAL void *duk_get_buffer(duk_context *ctx, duk_idx_t idx, duk_size_t *out_size) {
- DUK_ASSERT_CTX_VALID(ctx);
+DUK_EXTERNAL void *duk_get_buffer(duk_hthread *thr, duk_idx_t idx, duk_size_t *out_size) {
+ DUK_ASSERT_API_ENTRY(thr);
- return duk__get_buffer_helper(ctx, idx, out_size, NULL /*def_ptr*/, 0 /*def_size*/, 0 /*throw_flag*/);
+ return duk__get_buffer_helper(thr, idx, out_size, NULL /*def_ptr*/, 0 /*def_size*/, 0 /*throw_flag*/);
}
-DUK_EXTERNAL void *duk_opt_buffer(duk_context *ctx, duk_idx_t idx, duk_size_t *out_size, void *def_ptr, duk_size_t def_size) {
- DUK_ASSERT_CTX_VALID(ctx);
+DUK_EXTERNAL void *duk_opt_buffer(duk_hthread *thr, duk_idx_t idx, duk_size_t *out_size, void *def_ptr, duk_size_t def_size) {
+ DUK_ASSERT_API_ENTRY(thr);
- if (duk_check_type_mask(ctx, idx, DUK_TYPE_MASK_NONE | DUK_TYPE_MASK_UNDEFINED)) {
+ if (duk_check_type_mask(thr, idx, DUK_TYPE_MASK_NONE | DUK_TYPE_MASK_UNDEFINED)) {
if (out_size != NULL) {
*out_size = def_size;
}
return def_ptr;
}
- return duk_require_buffer(ctx, idx, out_size);
+ return duk_require_buffer(thr, idx, out_size);
}
-DUK_EXTERNAL void *duk_get_buffer_default(duk_context *ctx, duk_idx_t idx, duk_size_t *out_size, void *def_ptr, duk_size_t def_len) {
- DUK_ASSERT_CTX_VALID(ctx);
+DUK_EXTERNAL void *duk_get_buffer_default(duk_hthread *thr, duk_idx_t idx, duk_size_t *out_size, void *def_ptr, duk_size_t def_len) {
+ DUK_ASSERT_API_ENTRY(thr);
- return duk__get_buffer_helper(ctx, idx, out_size, def_ptr, def_len, 0 /*throw_flag*/);
+ return duk__get_buffer_helper(thr, idx, out_size, def_ptr, def_len, 0 /*throw_flag*/);
}
-DUK_EXTERNAL void *duk_require_buffer(duk_context *ctx, duk_idx_t idx, duk_size_t *out_size) {
- DUK_ASSERT_CTX_VALID(ctx);
+DUK_EXTERNAL void *duk_require_buffer(duk_hthread *thr, duk_idx_t idx, duk_size_t *out_size) {
+ DUK_ASSERT_API_ENTRY(thr);
- return duk__get_buffer_helper(ctx, idx, out_size, NULL /*def_ptr*/, 0 /*def_size*/, 1 /*throw_flag*/);
+ return duk__get_buffer_helper(thr, idx, out_size, NULL /*def_ptr*/, 0 /*def_size*/, 1 /*throw_flag*/);
}
/* Get the active buffer data area for a plain buffer or a buffer object.
@@ -18410,12 +19038,10 @@ DUK_EXTERNAL void *duk_require_buffer(duk_context *ctx, duk_idx_t idx, duk_size_
* have a NULL data pointer when its size is zero, the optional 'out_isbuffer'
* argument allows caller to detect this reliably.
*/
-DUK_INTERNAL void *duk_get_buffer_data_raw(duk_context *ctx, duk_idx_t idx, duk_size_t *out_size, void *def_ptr, duk_size_t def_size, duk_bool_t throw_flag, duk_bool_t *out_isbuffer) {
- duk_hthread *thr = (duk_hthread *) ctx;
+DUK_INTERNAL void *duk_get_buffer_data_raw(duk_hthread *thr, duk_idx_t idx, duk_size_t *out_size, void *def_ptr, duk_size_t def_size, duk_bool_t throw_flag, duk_bool_t *out_isbuffer) {
duk_tval *tv;
- DUK_ASSERT_CTX_VALID(ctx);
- DUK_UNREF(thr);
+ DUK_ASSERT_API_ENTRY(thr);
if (out_isbuffer != NULL) {
*out_isbuffer = 0;
@@ -18424,7 +19050,7 @@ DUK_INTERNAL void *duk_get_buffer_data_raw(duk_context *ctx, duk_idx_t idx, duk_
*out_size = def_size;
}
- tv = duk_get_tval_or_unused(ctx, idx);
+ tv = duk_get_tval_or_unused(thr, idx);
DUK_ASSERT(tv != NULL);
if (DUK_TVAL_IS_BUFFER(tv)) {
@@ -18473,28 +19099,31 @@ DUK_INTERNAL void *duk_get_buffer_data_raw(duk_context *ctx, duk_idx_t idx, duk_
return def_ptr;
}
-DUK_EXTERNAL void *duk_get_buffer_data(duk_context *ctx, duk_idx_t idx, duk_size_t *out_size) {
- return duk_get_buffer_data_raw(ctx, idx, out_size, NULL /*def_ptr*/, 0 /*def_size*/, 0 /*throw_flag*/, NULL);
+DUK_EXTERNAL void *duk_get_buffer_data(duk_hthread *thr, duk_idx_t idx, duk_size_t *out_size) {
+ DUK_ASSERT_API_ENTRY(thr);
+ return duk_get_buffer_data_raw(thr, idx, out_size, NULL /*def_ptr*/, 0 /*def_size*/, 0 /*throw_flag*/, NULL);
}
-DUK_EXTERNAL void *duk_get_buffer_data_default(duk_context *ctx, duk_idx_t idx, duk_size_t *out_size, void *def_ptr, duk_size_t def_size) {
- return duk_get_buffer_data_raw(ctx, idx, out_size, def_ptr, def_size, 0 /*throw_flag*/, NULL);
+DUK_EXTERNAL void *duk_get_buffer_data_default(duk_hthread *thr, duk_idx_t idx, duk_size_t *out_size, void *def_ptr, duk_size_t def_size) {
+ DUK_ASSERT_API_ENTRY(thr);
+ return duk_get_buffer_data_raw(thr, idx, out_size, def_ptr, def_size, 0 /*throw_flag*/, NULL);
}
-DUK_EXTERNAL void *duk_opt_buffer_data(duk_context *ctx, duk_idx_t idx, duk_size_t *out_size, void *def_ptr, duk_size_t def_size) {
- DUK_ASSERT_CTX_VALID(ctx);
+DUK_EXTERNAL void *duk_opt_buffer_data(duk_hthread *thr, duk_idx_t idx, duk_size_t *out_size, void *def_ptr, duk_size_t def_size) {
+ DUK_ASSERT_API_ENTRY(thr);
- if (duk_check_type_mask(ctx, idx, DUK_TYPE_MASK_NONE | DUK_TYPE_MASK_UNDEFINED)) {
+ if (duk_check_type_mask(thr, idx, DUK_TYPE_MASK_NONE | DUK_TYPE_MASK_UNDEFINED)) {
if (out_size != NULL) {
*out_size = def_size;
}
return def_ptr;
}
- return duk_require_buffer_data(ctx, idx, out_size);
+ return duk_require_buffer_data(thr, idx, out_size);
}
-DUK_EXTERNAL void *duk_require_buffer_data(duk_context *ctx, duk_idx_t idx, duk_size_t *out_size) {
- return duk_get_buffer_data_raw(ctx, idx, out_size, NULL /*def_ptr*/, 0 /*def_size*/, 1 /*throw_flag*/, NULL);
+DUK_EXTERNAL void *duk_require_buffer_data(duk_hthread *thr, duk_idx_t idx, duk_size_t *out_size) {
+ DUK_ASSERT_API_ENTRY(thr);
+ return duk_get_buffer_data_raw(thr, idx, out_size, NULL /*def_ptr*/, 0 /*def_size*/, 1 /*throw_flag*/, NULL);
}
/* Raw helper for getting a value from the stack, checking its tag.
@@ -18502,13 +19131,13 @@ DUK_EXTERNAL void *duk_require_buffer_data(duk_context *ctx, duk_idx_t idx, duk_
* tag in the packed representation.
*/
-DUK_LOCAL duk_heaphdr *duk__get_tagged_heaphdr_raw(duk_context *ctx, duk_idx_t idx, duk_uint_t tag) {
+DUK_LOCAL duk_heaphdr *duk__get_tagged_heaphdr_raw(duk_hthread *thr, duk_idx_t idx, duk_uint_t tag) {
duk_tval *tv;
duk_heaphdr *ret;
- DUK_ASSERT_CTX_VALID(ctx);
+ DUK_ASSERT_CTX_VALID(thr);
- tv = duk_get_tval_or_unused(ctx, idx);
+ tv = duk_get_tval_or_unused(thr, idx);
DUK_ASSERT(tv != NULL);
if (DUK_TVAL_GET_TAG(tv) != tag) {
return (duk_heaphdr *) NULL;
@@ -18520,121 +19149,161 @@ DUK_LOCAL duk_heaphdr *duk__get_tagged_heaphdr_raw(duk_context *ctx, duk_idx_t i
}
-DUK_INTERNAL duk_hstring *duk_get_hstring(duk_context *ctx, duk_idx_t idx) {
- return (duk_hstring *) duk__get_tagged_heaphdr_raw(ctx, idx, DUK_TAG_STRING);
+DUK_INTERNAL duk_hstring *duk_get_hstring(duk_hthread *thr, duk_idx_t idx) {
+ DUK_ASSERT_API_ENTRY(thr);
+ return (duk_hstring *) duk__get_tagged_heaphdr_raw(thr, idx, DUK_TAG_STRING);
}
-DUK_INTERNAL duk_hstring *duk_get_hstring_notsymbol(duk_context *ctx, duk_idx_t idx) {
- duk_hstring *res = (duk_hstring *) duk__get_tagged_heaphdr_raw(ctx, idx, DUK_TAG_STRING);
- if (DUK_UNLIKELY(res && DUK_HSTRING_HAS_SYMBOL(res))) {
+DUK_INTERNAL duk_hstring *duk_get_hstring_notsymbol(duk_hthread *thr, duk_idx_t idx) {
+ duk_hstring *h;
+
+ DUK_ASSERT_API_ENTRY(thr);
+
+ h = (duk_hstring *) duk__get_tagged_heaphdr_raw(thr, idx, DUK_TAG_STRING);
+ if (DUK_UNLIKELY(h && DUK_HSTRING_HAS_SYMBOL(h))) {
return NULL;
}
- return res;
+ return h;
}
-DUK_INTERNAL duk_hstring *duk_require_hstring(duk_context *ctx, duk_idx_t idx) {
+DUK_INTERNAL duk_hstring *duk_require_hstring(duk_hthread *thr, duk_idx_t idx) {
duk_hstring *h;
- h = (duk_hstring *) duk__get_tagged_heaphdr_raw(ctx, idx, DUK_TAG_STRING);
+
+ DUK_ASSERT_API_ENTRY(thr);
+
+ h = (duk_hstring *) duk__get_tagged_heaphdr_raw(thr, idx, DUK_TAG_STRING);
if (DUK_UNLIKELY(h == NULL)) {
- DUK_ERROR_REQUIRE_TYPE_INDEX(ctx, idx, "string", DUK_STR_NOT_STRING);
+ DUK_ERROR_REQUIRE_TYPE_INDEX(thr, idx, "string", DUK_STR_NOT_STRING);
}
return h;
}
-DUK_INTERNAL duk_hstring *duk_require_hstring_notsymbol(duk_context *ctx, duk_idx_t idx) {
+DUK_INTERNAL duk_hstring *duk_require_hstring_notsymbol(duk_hthread *thr, duk_idx_t idx) {
duk_hstring *h;
- h = (duk_hstring *) duk__get_tagged_heaphdr_raw(ctx, idx, DUK_TAG_STRING);
+
+ DUK_ASSERT_API_ENTRY(thr);
+
+ h = (duk_hstring *) duk__get_tagged_heaphdr_raw(thr, idx, DUK_TAG_STRING);
if (DUK_UNLIKELY(h == NULL || DUK_HSTRING_HAS_SYMBOL(h))) {
- DUK_ERROR_REQUIRE_TYPE_INDEX(ctx, idx, "string", DUK_STR_NOT_STRING);
+ DUK_ERROR_REQUIRE_TYPE_INDEX(thr, idx, "string", DUK_STR_NOT_STRING);
}
return h;
}
-DUK_INTERNAL duk_hobject *duk_get_hobject(duk_context *ctx, duk_idx_t idx) {
- return (duk_hobject *) duk__get_tagged_heaphdr_raw(ctx, idx, DUK_TAG_OBJECT);
+DUK_INTERNAL duk_hobject *duk_get_hobject(duk_hthread *thr, duk_idx_t idx) {
+ DUK_ASSERT_API_ENTRY(thr);
+ return (duk_hobject *) duk__get_tagged_heaphdr_raw(thr, idx, DUK_TAG_OBJECT);
}
-DUK_INTERNAL duk_hobject *duk_require_hobject(duk_context *ctx, duk_idx_t idx) {
+DUK_INTERNAL duk_hobject *duk_require_hobject(duk_hthread *thr, duk_idx_t idx) {
duk_hobject *h;
- h = (duk_hobject *) duk__get_tagged_heaphdr_raw(ctx, idx, DUK_TAG_OBJECT);
+
+ DUK_ASSERT_API_ENTRY(thr);
+
+ h = (duk_hobject *) duk__get_tagged_heaphdr_raw(thr, idx, DUK_TAG_OBJECT);
if (DUK_UNLIKELY(h == NULL)) {
- DUK_ERROR_REQUIRE_TYPE_INDEX(ctx, idx, "object", DUK_STR_NOT_OBJECT);
+ DUK_ERROR_REQUIRE_TYPE_INDEX(thr, idx, "object", DUK_STR_NOT_OBJECT);
}
return h;
}
-DUK_INTERNAL duk_hbuffer *duk_get_hbuffer(duk_context *ctx, duk_idx_t idx) {
- return (duk_hbuffer *) duk__get_tagged_heaphdr_raw(ctx, idx, DUK_TAG_BUFFER);
+DUK_INTERNAL duk_hbuffer *duk_get_hbuffer(duk_hthread *thr, duk_idx_t idx) {
+ DUK_ASSERT_API_ENTRY(thr);
+ return (duk_hbuffer *) duk__get_tagged_heaphdr_raw(thr, idx, DUK_TAG_BUFFER);
}
-DUK_INTERNAL duk_hbuffer *duk_require_hbuffer(duk_context *ctx, duk_idx_t idx) {
+DUK_INTERNAL duk_hbuffer *duk_require_hbuffer(duk_hthread *thr, duk_idx_t idx) {
duk_hbuffer *h;
- h = (duk_hbuffer *) duk__get_tagged_heaphdr_raw(ctx, idx, DUK_TAG_BUFFER);
+
+ DUK_ASSERT_API_ENTRY(thr);
+
+ h = (duk_hbuffer *) duk__get_tagged_heaphdr_raw(thr, idx, DUK_TAG_BUFFER);
if (DUK_UNLIKELY(h == NULL)) {
- DUK_ERROR_REQUIRE_TYPE_INDEX(ctx, idx, "buffer", DUK_STR_NOT_BUFFER);
+ DUK_ERROR_REQUIRE_TYPE_INDEX(thr, idx, "buffer", DUK_STR_NOT_BUFFER);
}
return h;
}
-DUK_INTERNAL duk_hthread *duk_get_hthread(duk_context *ctx, duk_idx_t idx) {
- duk_hobject *h = (duk_hobject *) duk__get_tagged_heaphdr_raw(ctx, idx, DUK_TAG_OBJECT);
+DUK_INTERNAL duk_hthread *duk_get_hthread(duk_hthread *thr, duk_idx_t idx) {
+ duk_hobject *h;
+
+ DUK_ASSERT_API_ENTRY(thr);
+
+ h = (duk_hobject *) duk__get_tagged_heaphdr_raw(thr, idx, DUK_TAG_OBJECT);
if (DUK_UNLIKELY(h != NULL && !DUK_HOBJECT_IS_THREAD(h))) {
h = NULL;
}
return (duk_hthread *) h;
}
-DUK_INTERNAL duk_hthread *duk_require_hthread(duk_context *ctx, duk_idx_t idx) {
- duk_hthread *thr = (duk_hthread *) ctx;
- duk_hobject *h = (duk_hobject *) duk__get_tagged_heaphdr_raw(ctx, idx, DUK_TAG_OBJECT);
+DUK_INTERNAL duk_hthread *duk_require_hthread(duk_hthread *thr, duk_idx_t idx) {
+ duk_hobject *h;
+
+ DUK_ASSERT_API_ENTRY(thr);
+
+ h = (duk_hobject *) duk__get_tagged_heaphdr_raw(thr, idx, DUK_TAG_OBJECT);
if (DUK_UNLIKELY(!(h != NULL && DUK_HOBJECT_IS_THREAD(h)))) {
DUK_ERROR_REQUIRE_TYPE_INDEX(thr, idx, "thread", DUK_STR_NOT_THREAD);
}
return (duk_hthread *) h;
}
-DUK_INTERNAL duk_hcompfunc *duk_get_hcompfunc(duk_context *ctx, duk_idx_t idx) {
- duk_hobject *h = (duk_hobject *) duk__get_tagged_heaphdr_raw(ctx, idx, DUK_TAG_OBJECT);
+DUK_INTERNAL duk_hcompfunc *duk_get_hcompfunc(duk_hthread *thr, duk_idx_t idx) {
+ duk_hobject *h;
+
+ DUK_ASSERT_API_ENTRY(thr);
+
+ h = (duk_hobject *) duk__get_tagged_heaphdr_raw(thr, idx, DUK_TAG_OBJECT);
if (DUK_UNLIKELY(h != NULL && !DUK_HOBJECT_IS_COMPFUNC(h))) {
h = NULL;
}
return (duk_hcompfunc *) h;
}
-DUK_INTERNAL duk_hcompfunc *duk_require_hcompfunc(duk_context *ctx, duk_idx_t idx) {
- duk_hthread *thr = (duk_hthread *) ctx;
- duk_hobject *h = (duk_hobject *) duk__get_tagged_heaphdr_raw(ctx, idx, DUK_TAG_OBJECT);
+DUK_INTERNAL duk_hcompfunc *duk_require_hcompfunc(duk_hthread *thr, duk_idx_t idx) {
+ duk_hobject *h;
+
+ DUK_ASSERT_API_ENTRY(thr);
+
+ h = (duk_hobject *) duk__get_tagged_heaphdr_raw(thr, idx, DUK_TAG_OBJECT);
if (DUK_UNLIKELY(!(h != NULL && DUK_HOBJECT_IS_COMPFUNC(h)))) {
DUK_ERROR_REQUIRE_TYPE_INDEX(thr, idx, "compiledfunction", DUK_STR_NOT_COMPFUNC);
}
return (duk_hcompfunc *) h;
}
-DUK_INTERNAL duk_hnatfunc *duk_get_hnatfunc(duk_context *ctx, duk_idx_t idx) {
- duk_hobject *h = (duk_hobject *) duk__get_tagged_heaphdr_raw(ctx, idx, DUK_TAG_OBJECT);
+DUK_INTERNAL duk_hnatfunc *duk_get_hnatfunc(duk_hthread *thr, duk_idx_t idx) {
+ duk_hobject *h;
+
+ DUK_ASSERT_API_ENTRY(thr);
+
+ h = (duk_hobject *) duk__get_tagged_heaphdr_raw(thr, idx, DUK_TAG_OBJECT);
if (DUK_UNLIKELY(h != NULL && !DUK_HOBJECT_IS_NATFUNC(h))) {
h = NULL;
}
return (duk_hnatfunc *) h;
}
-DUK_INTERNAL duk_hnatfunc *duk_require_hnatfunc(duk_context *ctx, duk_idx_t idx) {
- duk_hthread *thr = (duk_hthread *) ctx;
- duk_hobject *h = (duk_hobject *) duk__get_tagged_heaphdr_raw(ctx, idx, DUK_TAG_OBJECT);
+DUK_INTERNAL duk_hnatfunc *duk_require_hnatfunc(duk_hthread *thr, duk_idx_t idx) {
+ duk_hobject *h;
+
+ DUK_ASSERT_API_ENTRY(thr);
+
+ h = (duk_hobject *) duk__get_tagged_heaphdr_raw(thr, idx, DUK_TAG_OBJECT);
if (DUK_UNLIKELY(!(h != NULL && DUK_HOBJECT_IS_NATFUNC(h)))) {
DUK_ERROR_REQUIRE_TYPE_INDEX(thr, idx, "nativefunction", DUK_STR_NOT_NATFUNC);
}
return (duk_hnatfunc *) h;
}
-DUK_EXTERNAL duk_c_function duk_get_c_function(duk_context *ctx, duk_idx_t idx) {
+DUK_EXTERNAL duk_c_function duk_get_c_function(duk_hthread *thr, duk_idx_t idx) {
duk_tval *tv;
duk_hobject *h;
duk_hnatfunc *f;
- DUK_ASSERT_CTX_VALID(ctx);
+ DUK_ASSERT_API_ENTRY(thr);
- tv = duk_get_tval_or_unused(ctx, idx);
+ tv = duk_get_tval_or_unused(thr, idx);
DUK_ASSERT(tv != NULL);
if (DUK_UNLIKELY(!DUK_TVAL_IS_OBJECT(tv))) {
return NULL;
@@ -18651,21 +19320,21 @@ DUK_EXTERNAL duk_c_function duk_get_c_function(duk_context *ctx, duk_idx_t idx)
return f->func;
}
-DUK_EXTERNAL duk_c_function duk_opt_c_function(duk_context *ctx, duk_idx_t idx, duk_c_function def_value) {
- DUK_ASSERT_CTX_VALID(ctx);
+DUK_EXTERNAL duk_c_function duk_opt_c_function(duk_hthread *thr, duk_idx_t idx, duk_c_function def_value) {
+ DUK_ASSERT_API_ENTRY(thr);
- if (duk_check_type_mask(ctx, idx, DUK_TYPE_MASK_NONE | DUK_TYPE_MASK_UNDEFINED)) {
+ if (duk_check_type_mask(thr, idx, DUK_TYPE_MASK_NONE | DUK_TYPE_MASK_UNDEFINED)) {
return def_value;
}
- return duk_require_c_function(ctx, idx);
+ return duk_require_c_function(thr, idx);
}
-DUK_EXTERNAL duk_c_function duk_get_c_function_default(duk_context *ctx, duk_idx_t idx, duk_c_function def_value) {
+DUK_EXTERNAL duk_c_function duk_get_c_function_default(duk_hthread *thr, duk_idx_t idx, duk_c_function def_value) {
duk_c_function ret;
- DUK_ASSERT_CTX_VALID(ctx);
+ DUK_ASSERT_API_ENTRY(thr);
- ret = duk_get_c_function(ctx, idx);
+ ret = duk_get_c_function(thr, idx);
if (ret != NULL) {
return ret;
}
@@ -18673,62 +19342,64 @@ DUK_EXTERNAL duk_c_function duk_get_c_function_default(duk_context *ctx, duk_idx
return def_value;
}
-DUK_EXTERNAL duk_c_function duk_require_c_function(duk_context *ctx, duk_idx_t idx) {
- duk_hthread *thr = (duk_hthread *) ctx;
+DUK_EXTERNAL duk_c_function duk_require_c_function(duk_hthread *thr, duk_idx_t idx) {
duk_c_function ret;
- DUK_ASSERT_CTX_VALID(ctx);
+ DUK_ASSERT_API_ENTRY(thr);
- ret = duk_get_c_function(ctx, idx);
+ ret = duk_get_c_function(thr, idx);
if (DUK_UNLIKELY(!ret)) {
DUK_ERROR_REQUIRE_TYPE_INDEX(thr, idx, "nativefunction", DUK_STR_NOT_NATFUNC);
}
return ret;
}
-DUK_EXTERNAL void duk_require_function(duk_context *ctx, duk_idx_t idx) {
- if (DUK_UNLIKELY(!duk_is_function(ctx, idx))) {
- DUK_ERROR_REQUIRE_TYPE_INDEX((duk_hthread *) ctx, idx, "function", DUK_STR_NOT_FUNCTION);
+DUK_EXTERNAL void duk_require_function(duk_hthread *thr, duk_idx_t idx) {
+ DUK_ASSERT_API_ENTRY(thr);
+ if (DUK_UNLIKELY(!duk_is_function(thr, idx))) {
+ DUK_ERROR_REQUIRE_TYPE_INDEX(thr, idx, "function", DUK_STR_NOT_FUNCTION);
}
}
-DUK_INTERNAL_DECL void duk_require_constructable(duk_context *ctx, duk_idx_t idx) {
+DUK_INTERNAL void duk_require_constructable(duk_hthread *thr, duk_idx_t idx) {
duk_hobject *h;
- h = duk_require_hobject_accept_mask(ctx, idx, DUK_TYPE_MASK_LIGHTFUNC);
+ DUK_ASSERT_API_ENTRY(thr);
+
+ h = duk_require_hobject_accept_mask(thr, idx, DUK_TYPE_MASK_LIGHTFUNC);
if (DUK_UNLIKELY(h != NULL && !DUK_HOBJECT_HAS_CONSTRUCTABLE(h))) {
- DUK_ERROR_REQUIRE_TYPE_INDEX((duk_hthread *) ctx, idx, "constructable", DUK_STR_NOT_CONSTRUCTABLE);
+ DUK_ERROR_REQUIRE_TYPE_INDEX(thr, idx, "constructable", DUK_STR_NOT_CONSTRUCTABLE);
}
/* Lightfuncs (h == NULL) are constructable. */
}
-DUK_EXTERNAL duk_context *duk_get_context(duk_context *ctx, duk_idx_t idx) {
- DUK_ASSERT_CTX_VALID(ctx);
+DUK_EXTERNAL duk_hthread *duk_get_context(duk_hthread *thr, duk_idx_t idx) {
+ DUK_ASSERT_API_ENTRY(thr);
- return (duk_context *) duk_get_hthread(ctx, idx);
+ return duk_get_hthread(thr, idx);
}
-DUK_EXTERNAL duk_context *duk_require_context(duk_context *ctx, duk_idx_t idx) {
- DUK_ASSERT_CTX_VALID(ctx);
+DUK_EXTERNAL duk_hthread *duk_require_context(duk_hthread *thr, duk_idx_t idx) {
+ DUK_ASSERT_API_ENTRY(thr);
- return (duk_context *) duk_require_hthread(ctx, idx);
+ return duk_require_hthread(thr, idx);
}
-DUK_EXTERNAL duk_context *duk_opt_context(duk_context *ctx, duk_idx_t idx, duk_context *def_value) {
- DUK_ASSERT_CTX_VALID(ctx);
+DUK_EXTERNAL duk_hthread *duk_opt_context(duk_hthread *thr, duk_idx_t idx, duk_hthread *def_value) {
+ DUK_ASSERT_API_ENTRY(thr);
- if (duk_check_type_mask(ctx, idx, DUK_TYPE_MASK_NONE | DUK_TYPE_MASK_UNDEFINED)) {
+ if (duk_check_type_mask(thr, idx, DUK_TYPE_MASK_NONE | DUK_TYPE_MASK_UNDEFINED)) {
return def_value;
}
- return duk_require_context(ctx, idx);
+ return duk_require_context(thr, idx);
}
-DUK_EXTERNAL_DECL duk_context *duk_get_context_default(duk_context *ctx, duk_idx_t idx, duk_context *def_value) {
- duk_context *ret;
+DUK_EXTERNAL duk_hthread *duk_get_context_default(duk_hthread *thr, duk_idx_t idx, duk_hthread *def_value) {
+ duk_hthread *ret;
- DUK_ASSERT_CTX_VALID(ctx);
+ DUK_ASSERT_API_ENTRY(thr);
- ret = duk_get_context(ctx, idx);
+ ret = duk_get_context(thr, idx);
if (ret != NULL) {
return ret;
}
@@ -18736,13 +19407,13 @@ DUK_EXTERNAL_DECL duk_context *duk_get_context_default(duk_context *ctx, duk_idx
return def_value;
}
-DUK_EXTERNAL void *duk_get_heapptr(duk_context *ctx, duk_idx_t idx) {
+DUK_EXTERNAL void *duk_get_heapptr(duk_hthread *thr, duk_idx_t idx) {
duk_tval *tv;
void *ret;
- DUK_ASSERT_CTX_VALID(ctx);
+ DUK_ASSERT_API_ENTRY(thr);
- tv = duk_get_tval_or_unused(ctx, idx);
+ tv = duk_get_tval_or_unused(thr, idx);
DUK_ASSERT(tv != NULL);
if (DUK_UNLIKELY(!DUK_TVAL_IS_HEAP_ALLOCATED(tv))) {
return (void *) NULL;
@@ -18753,21 +19424,21 @@ DUK_EXTERNAL void *duk_get_heapptr(duk_context *ctx, duk_idx_t idx) {
return ret;
}
-DUK_EXTERNAL void *duk_opt_heapptr(duk_context *ctx, duk_idx_t idx, void *def_value) {
- DUK_ASSERT_CTX_VALID(ctx);
+DUK_EXTERNAL void *duk_opt_heapptr(duk_hthread *thr, duk_idx_t idx, void *def_value) {
+ DUK_ASSERT_API_ENTRY(thr);
- if (duk_check_type_mask(ctx, idx, DUK_TYPE_MASK_NONE | DUK_TYPE_MASK_UNDEFINED)) {
+ if (duk_check_type_mask(thr, idx, DUK_TYPE_MASK_NONE | DUK_TYPE_MASK_UNDEFINED)) {
return def_value;
}
- return duk_require_heapptr(ctx, idx);
+ return duk_require_heapptr(thr, idx);
}
-DUK_EXTERNAL_DECL void *duk_get_heapptr_default(duk_context *ctx, duk_idx_t idx, void *def_value) {
+DUK_EXTERNAL void *duk_get_heapptr_default(duk_hthread *thr, duk_idx_t idx, void *def_value) {
void *ret;
- DUK_ASSERT_CTX_VALID(ctx);
+ DUK_ASSERT_API_ENTRY(thr);
- ret = duk_get_heapptr(ctx, idx);
+ ret = duk_get_heapptr(thr, idx);
if (ret != NULL) {
return ret;
}
@@ -18775,14 +19446,13 @@ DUK_EXTERNAL_DECL void *duk_get_heapptr_default(duk_context *ctx, duk_idx_t idx,
return def_value;
}
-DUK_EXTERNAL void *duk_require_heapptr(duk_context *ctx, duk_idx_t idx) {
- duk_hthread *thr = (duk_hthread *) ctx;
+DUK_EXTERNAL void *duk_require_heapptr(duk_hthread *thr, duk_idx_t idx) {
duk_tval *tv;
void *ret;
- DUK_ASSERT_CTX_VALID(ctx);
+ DUK_ASSERT_API_ENTRY(thr);
- tv = duk_get_tval_or_unused(ctx, idx);
+ tv = duk_get_tval_or_unused(thr, idx);
DUK_ASSERT(tv != NULL);
if (DUK_UNLIKELY(!DUK_TVAL_IS_HEAP_ALLOCATED(tv))) {
DUK_ERROR_REQUIRE_TYPE_INDEX(thr, idx, "heapobject", DUK_STR_UNEXPECTED_TYPE);
@@ -18794,22 +19464,22 @@ DUK_EXTERNAL void *duk_require_heapptr(duk_context *ctx, duk_idx_t idx) {
}
/* Internal helper for getting/requiring a duk_hobject with possible promotion. */
-DUK_LOCAL duk_hobject *duk__get_hobject_promote_mask_raw(duk_context *ctx, duk_idx_t idx, duk_uint_t type_mask) {
+DUK_LOCAL duk_hobject *duk__get_hobject_promote_mask_raw(duk_hthread *thr, duk_idx_t idx, duk_uint_t type_mask) {
duk_uint_t val_mask;
duk_hobject *res;
- DUK_ASSERT_CTX_VALID(ctx);
+ DUK_ASSERT_CTX_VALID(thr);
- res = duk_get_hobject(ctx, idx); /* common case, not promoted */
+ res = duk_get_hobject(thr, idx); /* common case, not promoted */
if (DUK_LIKELY(res != NULL)) {
DUK_ASSERT(res != NULL);
return res;
}
- val_mask = duk_get_type_mask(ctx, idx);
+ val_mask = duk_get_type_mask(thr, idx);
if (val_mask & type_mask) {
if (type_mask & DUK_TYPE_MASK_PROMOTE) {
- res = duk_to_hobject(ctx, idx);
+ res = duk_to_hobject(thr, idx);
DUK_ASSERT(res != NULL);
return res;
} else {
@@ -18818,7 +19488,7 @@ DUK_LOCAL duk_hobject *duk__get_hobject_promote_mask_raw(duk_context *ctx, duk_i
}
if (type_mask & DUK_TYPE_MASK_THROW) {
- DUK_ERROR_REQUIRE_TYPE_INDEX((duk_hthread *) ctx, idx, "object", DUK_STR_NOT_OBJECT);
+ DUK_ERROR_REQUIRE_TYPE_INDEX(thr, idx, "object", DUK_STR_NOT_OBJECT);
}
return NULL;
}
@@ -18830,48 +19500,49 @@ DUK_LOCAL duk_hobject *duk__get_hobject_promote_mask_raw(duk_context *ctx, duk_i
* Return value is NULL if value is neither an object nor a plain type allowed
* by the mask.
*/
-DUK_INTERNAL duk_hobject *duk_get_hobject_promote_mask(duk_context *ctx, duk_idx_t idx, duk_uint_t type_mask) {
- return duk__get_hobject_promote_mask_raw(ctx, idx, type_mask | DUK_TYPE_MASK_PROMOTE);
+DUK_INTERNAL duk_hobject *duk_get_hobject_promote_mask(duk_hthread *thr, duk_idx_t idx, duk_uint_t type_mask) {
+ DUK_ASSERT_API_ENTRY(thr);
+ return duk__get_hobject_promote_mask_raw(thr, idx, type_mask | DUK_TYPE_MASK_PROMOTE);
}
/* Like duk_get_hobject_promote_mask() but throw a TypeError instead of
* returning a NULL.
*/
-DUK_INTERNAL duk_hobject *duk_require_hobject_promote_mask(duk_context *ctx, duk_idx_t idx, duk_uint_t type_mask) {
- return duk__get_hobject_promote_mask_raw(ctx, idx, type_mask | DUK_TYPE_MASK_THROW | DUK_TYPE_MASK_PROMOTE);
+DUK_INTERNAL duk_hobject *duk_require_hobject_promote_mask(duk_hthread *thr, duk_idx_t idx, duk_uint_t type_mask) {
+ DUK_ASSERT_API_ENTRY(thr);
+ return duk__get_hobject_promote_mask_raw(thr, idx, type_mask | DUK_TYPE_MASK_THROW | DUK_TYPE_MASK_PROMOTE);
}
/* Require a duk_hobject * at 'idx'; if the value is not an object but matches the
* supplied 'type_mask', return a NULL instead. Otherwise throw a TypeError.
*/
-DUK_INTERNAL duk_hobject *duk_require_hobject_accept_mask(duk_context *ctx, duk_idx_t idx, duk_uint_t type_mask) {
- return duk__get_hobject_promote_mask_raw(ctx, idx, type_mask | DUK_TYPE_MASK_THROW);
+DUK_INTERNAL duk_hobject *duk_require_hobject_accept_mask(duk_hthread *thr, duk_idx_t idx, duk_uint_t type_mask) {
+ DUK_ASSERT_API_ENTRY(thr);
+ return duk__get_hobject_promote_mask_raw(thr, idx, type_mask | DUK_TYPE_MASK_THROW);
}
-DUK_INTERNAL duk_hobject *duk_get_hobject_with_class(duk_context *ctx, duk_idx_t idx, duk_small_uint_t classnum) {
+DUK_INTERNAL duk_hobject *duk_get_hobject_with_class(duk_hthread *thr, duk_idx_t idx, duk_small_uint_t classnum) {
duk_hobject *h;
- DUK_ASSERT_CTX_VALID(ctx);
+ DUK_ASSERT_API_ENTRY(thr);
DUK_ASSERT_DISABLE(classnum >= 0); /* unsigned */
DUK_ASSERT(classnum <= DUK_HOBJECT_CLASS_MAX);
- h = (duk_hobject *) duk__get_tagged_heaphdr_raw(ctx, idx, DUK_TAG_OBJECT);
+ h = (duk_hobject *) duk__get_tagged_heaphdr_raw(thr, idx, DUK_TAG_OBJECT);
if (DUK_UNLIKELY(h != NULL && DUK_HOBJECT_GET_CLASS_NUMBER(h) != classnum)) {
h = NULL;
}
return h;
}
-DUK_INTERNAL duk_hobject *duk_require_hobject_with_class(duk_context *ctx, duk_idx_t idx, duk_small_uint_t classnum) {
- duk_hthread *thr;
+DUK_INTERNAL duk_hobject *duk_require_hobject_with_class(duk_hthread *thr, duk_idx_t idx, duk_small_uint_t classnum) {
duk_hobject *h;
- DUK_ASSERT_CTX_VALID(ctx);
+ DUK_ASSERT_API_ENTRY(thr);
DUK_ASSERT_DISABLE(classnum >= 0); /* unsigned */
DUK_ASSERT(classnum <= DUK_HOBJECT_CLASS_MAX);
- thr = (duk_hthread *) ctx;
- h = (duk_hobject *) duk__get_tagged_heaphdr_raw(ctx, idx, DUK_TAG_OBJECT);
+ h = (duk_hobject *) duk__get_tagged_heaphdr_raw(thr, idx, DUK_TAG_OBJECT);
if (DUK_UNLIKELY(!(h != NULL && DUK_HOBJECT_GET_CLASS_NUMBER(h) == classnum))) {
duk_hstring *h_class;
h_class = DUK_HTHREAD_GET_STRING(thr, DUK_HOBJECT_CLASS_NUMBER_TO_STRIDX(classnum));
@@ -18882,12 +19553,12 @@ DUK_INTERNAL duk_hobject *duk_require_hobject_with_class(duk_context *ctx, duk_i
return h;
}
-DUK_EXTERNAL duk_size_t duk_get_length(duk_context *ctx, duk_idx_t idx) {
+DUK_EXTERNAL duk_size_t duk_get_length(duk_hthread *thr, duk_idx_t idx) {
duk_tval *tv;
- DUK_ASSERT_CTX_VALID(ctx);
+ DUK_ASSERT_API_ENTRY(thr);
- tv = duk_get_tval_or_unused(ctx, idx);
+ tv = duk_get_tval_or_unused(thr, idx);
DUK_ASSERT(tv != NULL);
switch (DUK_TVAL_GET_TAG(tv)) {
@@ -18897,17 +19568,20 @@ DUK_EXTERNAL duk_size_t duk_get_length(duk_context *ctx, duk_idx_t idx) {
case DUK_TAG_POINTER:
return 0;
#if defined(DUK_USE_PREFER_SIZE)
- /* All of these types (besides object) have a virtual, non-configurable
- * .length property which is within size_t range so we can just look it
- * up without specific type checks.
+ /* String and buffer have a virtual non-configurable .length property
+ * which is within size_t range so it can be looked up without specific
+ * type checks. Lightfuncs inherit from %NativeFunctionPrototype%
+ * which provides an inherited .length accessor; it could be overwritten
+ * to produce unexpected types or values, but just number convert and
+ * duk_size_t cast for now.
*/
case DUK_TAG_STRING:
case DUK_TAG_BUFFER:
case DUK_TAG_LIGHTFUNC: {
duk_size_t ret;
- duk_get_prop_stridx(ctx, idx, DUK_STRIDX_LENGTH);
- ret = (duk_size_t) duk_to_number_m1(ctx);
- duk_pop(ctx);
+ duk_get_prop_stridx(thr, idx, DUK_STRIDX_LENGTH);
+ ret = (duk_size_t) duk_to_number_m1(thr);
+ duk_pop_unsafe(thr);
return ret;
}
#else /* DUK_USE_PREFER_SIZE */
@@ -18925,15 +19599,22 @@ DUK_EXTERNAL duk_size_t duk_get_length(duk_context *ctx, duk_idx_t idx) {
return (duk_size_t) DUK_HBUFFER_GET_SIZE(h);
}
case DUK_TAG_LIGHTFUNC: {
- duk_small_uint_t lf_flags;
- lf_flags = DUK_TVAL_GET_LIGHTFUNC_FLAGS(tv);
- return (duk_size_t) DUK_LFUNC_FLAGS_GET_LENGTH(lf_flags);
+ /* We could look up the length from the lightfunc duk_tval,
+ * but since Duktape 2.2 lightfunc .length comes from
+ * %NativeFunctionPrototype% which can be overridden, so
+ * look up the property explicitly.
+ */
+ duk_size_t ret;
+ duk_get_prop_stridx(thr, idx, DUK_STRIDX_LENGTH);
+ ret = (duk_size_t) duk_to_number_m1(thr);
+ duk_pop_unsafe(thr);
+ return ret;
}
#endif /* DUK_USE_PREFER_SIZE */
case DUK_TAG_OBJECT: {
duk_hobject *h = DUK_TVAL_GET_OBJECT(tv);
DUK_ASSERT(h != NULL);
- return (duk_size_t) duk_hobject_get_length((duk_hthread *) ctx, h);
+ return (duk_size_t) duk_hobject_get_length(thr, h);
}
#if defined(DUK_USE_FASTINT)
case DUK_TAG_FASTINT:
@@ -18952,17 +19633,16 @@ DUK_EXTERNAL duk_size_t duk_get_length(duk_context *ctx, duk_idx_t idx) {
*
* Used internally when we're 100% sure that a certain index is valid and
* contains an object of a certain type. For example, if we duk_push_object()
- * we can then safely duk_known_hobject(ctx, -1). These helpers just assert
+ * we can then safely duk_known_hobject(thr, -1). These helpers just assert
* for the index and type, and if the assumptions are not valid, memory unsafe
* behavior happens.
*/
-DUK_LOCAL duk_heaphdr *duk__known_heaphdr(duk_context *ctx, duk_idx_t idx) {
- duk_hthread *thr = (duk_hthread *) ctx;
+DUK_LOCAL duk_heaphdr *duk__known_heaphdr(duk_hthread *thr, duk_idx_t idx) {
duk_tval *tv;
duk_heaphdr *h;
- DUK_ASSERT_CTX_VALID(ctx);
+ DUK_ASSERT_CTX_VALID(thr);
if (idx < 0) {
tv = thr->valstack_top + idx;
} else {
@@ -18975,37 +19655,42 @@ DUK_LOCAL duk_heaphdr *duk__known_heaphdr(duk_context *ctx, duk_idx_t idx) {
return h;
}
-DUK_INTERNAL duk_hstring *duk_known_hstring(duk_context *ctx, duk_idx_t idx) {
- DUK_ASSERT(duk_get_hstring(ctx, idx) != NULL);
- return (duk_hstring *) duk__known_heaphdr(ctx, idx);
+DUK_INTERNAL duk_hstring *duk_known_hstring(duk_hthread *thr, duk_idx_t idx) {
+ DUK_ASSERT_API_ENTRY(thr);
+ DUK_ASSERT(duk_get_hstring(thr, idx) != NULL);
+ return (duk_hstring *) duk__known_heaphdr(thr, idx);
}
-DUK_INTERNAL duk_hobject *duk_known_hobject(duk_context *ctx, duk_idx_t idx) {
- DUK_ASSERT(duk_get_hobject(ctx, idx) != NULL);
- return (duk_hobject *) duk__known_heaphdr(ctx, idx);
+DUK_INTERNAL duk_hobject *duk_known_hobject(duk_hthread *thr, duk_idx_t idx) {
+ DUK_ASSERT_API_ENTRY(thr);
+ DUK_ASSERT(duk_get_hobject(thr, idx) != NULL);
+ return (duk_hobject *) duk__known_heaphdr(thr, idx);
}
-DUK_INTERNAL duk_hbuffer *duk_known_hbuffer(duk_context *ctx, duk_idx_t idx) {
- DUK_ASSERT(duk_get_hbuffer(ctx, idx) != NULL);
- return (duk_hbuffer *) duk__known_heaphdr(ctx, idx);
+DUK_INTERNAL duk_hbuffer *duk_known_hbuffer(duk_hthread *thr, duk_idx_t idx) {
+ DUK_ASSERT_API_ENTRY(thr);
+ DUK_ASSERT(duk_get_hbuffer(thr, idx) != NULL);
+ return (duk_hbuffer *) duk__known_heaphdr(thr, idx);
}
-DUK_INTERNAL duk_hcompfunc *duk_known_hcompfunc(duk_context *ctx, duk_idx_t idx) {
- DUK_ASSERT(duk_get_hcompfunc(ctx, idx) != NULL);
- return (duk_hcompfunc *) duk__known_heaphdr(ctx, idx);
+DUK_INTERNAL duk_hcompfunc *duk_known_hcompfunc(duk_hthread *thr, duk_idx_t idx) {
+ DUK_ASSERT_API_ENTRY(thr);
+ DUK_ASSERT(duk_get_hcompfunc(thr, idx) != NULL);
+ return (duk_hcompfunc *) duk__known_heaphdr(thr, idx);
}
-DUK_INTERNAL duk_hnatfunc *duk_known_hnatfunc(duk_context *ctx, duk_idx_t idx) {
- DUK_ASSERT(duk_get_hnatfunc(ctx, idx) != NULL);
- return (duk_hnatfunc *) duk__known_heaphdr(ctx, idx);
+DUK_INTERNAL duk_hnatfunc *duk_known_hnatfunc(duk_hthread *thr, duk_idx_t idx) {
+ DUK_ASSERT_API_ENTRY(thr);
+ DUK_ASSERT(duk_get_hnatfunc(thr, idx) != NULL);
+ return (duk_hnatfunc *) duk__known_heaphdr(thr, idx);
}
-DUK_EXTERNAL void duk_set_length(duk_context *ctx, duk_idx_t idx, duk_size_t len) {
- DUK_ASSERT_CTX_VALID(ctx);
+DUK_EXTERNAL void duk_set_length(duk_hthread *thr, duk_idx_t idx, duk_size_t len) {
+ DUK_ASSERT_API_ENTRY(thr);
- idx = duk_normalize_index(ctx, idx);
- duk_push_uint(ctx, (duk_uint_t) len);
- duk_put_prop_stridx(ctx, idx, DUK_STRIDX_LENGTH);
+ idx = duk_normalize_index(thr, idx);
+ duk_push_uint(thr, (duk_uint_t) len);
+ duk_put_prop_stridx(thr, idx, DUK_STRIDX_LENGTH);
}
/*
@@ -19018,68 +19703,63 @@ DUK_EXTERNAL void duk_set_length(duk_context *ctx, duk_idx_t idx, duk_size_t len
/* E5 Section 8.12.8 */
-DUK_LOCAL duk_bool_t duk__defaultvalue_coerce_attempt(duk_context *ctx, duk_idx_t idx, duk_small_int_t func_stridx) {
- if (duk_get_prop_stridx(ctx, idx, func_stridx)) {
+DUK_LOCAL duk_bool_t duk__defaultvalue_coerce_attempt(duk_hthread *thr, duk_idx_t idx, duk_small_uint_t func_stridx) {
+ if (duk_get_prop_stridx(thr, idx, func_stridx)) {
/* [ ... func ] */
- if (duk_is_callable(ctx, -1)) {
- duk_dup(ctx, idx); /* -> [ ... func this ] */
- duk_call_method(ctx, 0); /* -> [ ... retval ] */
- if (duk_is_primitive(ctx, -1)) {
- duk_replace(ctx, idx);
+ if (duk_is_callable(thr, -1)) {
+ duk_dup(thr, idx); /* -> [ ... func this ] */
+ duk_call_method(thr, 0); /* -> [ ... retval ] */
+ if (duk_is_primitive(thr, -1)) {
+ duk_replace(thr, idx);
return 1;
}
/* [ ... retval ]; popped below */
}
}
- duk_pop(ctx); /* [ ... func/retval ] -> [ ... ] */
+ duk_pop_unsafe(thr); /* [ ... func/retval ] -> [ ... ] */
return 0;
}
-DUK_EXTERNAL void duk_to_undefined(duk_context *ctx, duk_idx_t idx) {
- duk_hthread *thr = (duk_hthread *) ctx;
+DUK_EXTERNAL void duk_to_undefined(duk_hthread *thr, duk_idx_t idx) {
duk_tval *tv;
- DUK_ASSERT_CTX_VALID(ctx);
- DUK_UNREF(thr);
+ DUK_ASSERT_API_ENTRY(thr);
- tv = duk_require_tval(ctx, idx);
+ tv = duk_require_tval(thr, idx);
DUK_ASSERT(tv != NULL);
DUK_TVAL_SET_UNDEFINED_UPDREF(thr, tv); /* side effects */
}
-DUK_EXTERNAL void duk_to_null(duk_context *ctx, duk_idx_t idx) {
- duk_hthread *thr = (duk_hthread *) ctx;
+DUK_EXTERNAL void duk_to_null(duk_hthread *thr, duk_idx_t idx) {
duk_tval *tv;
- DUK_ASSERT_CTX_VALID(ctx);
- DUK_UNREF(thr);
+ DUK_ASSERT_API_ENTRY(thr);
- tv = duk_require_tval(ctx, idx);
+ tv = duk_require_tval(thr, idx);
DUK_ASSERT(tv != NULL);
DUK_TVAL_SET_NULL_UPDREF(thr, tv); /* side effects */
}
/* E5 Section 9.1 */
-DUK_EXTERNAL void duk_to_primitive(duk_context *ctx, duk_idx_t idx, duk_int_t hint) {
- duk_hthread *thr = (duk_hthread *) ctx;
+DUK_EXTERNAL void duk_to_primitive(duk_hthread *thr, duk_idx_t idx, duk_int_t hint) {
/* inline initializer for coercers[] is not allowed by old compilers like BCC */
- duk_small_int_t coercers[2];
+ duk_small_uint_t coercers[2];
duk_small_uint_t class_number;
- DUK_ASSERT_CTX_VALID(ctx);
+ DUK_ASSERT_API_ENTRY(thr);
DUK_ASSERT(hint == DUK_HINT_NONE || hint == DUK_HINT_NUMBER || hint == DUK_HINT_STRING);
- idx = duk_require_normalize_index(ctx, idx);
+ idx = duk_require_normalize_index(thr, idx);
- if (!duk_check_type_mask(ctx, idx, DUK_TYPE_MASK_OBJECT |
+ if (!duk_check_type_mask(thr, idx, DUK_TYPE_MASK_OBJECT |
DUK_TYPE_MASK_LIGHTFUNC |
DUK_TYPE_MASK_BUFFER)) {
/* Any other values stay as is. */
- DUK_ASSERT(!duk_is_buffer(ctx, idx)); /* duk_to_string() relies on this behavior */
+ DUK_ASSERT(!duk_is_buffer(thr, idx)); /* duk_to_string() relies on this behavior */
return;
}
- class_number = duk_get_class_number(ctx, idx);
+ class_number = duk_get_class_number(thr, idx);
/* XXX: Symbol objects normally coerce via the ES2015-revised ToPrimitive()
* algorithm which consults value[@@toPrimitive] and avoids calling
@@ -19094,11 +19774,11 @@ DUK_EXTERNAL void duk_to_primitive(duk_context *ctx, duk_idx_t idx, duk_int_t hi
duk_hstring *h_str;
/* XXX: pretty awkward, index based API for internal value access? */
- h_obj = duk_known_hobject(ctx, idx);
+ h_obj = duk_known_hobject(thr, idx);
h_str = duk_hobject_get_internal_value_string(thr->heap, h_obj);
if (h_str) {
- duk_push_hstring(ctx, h_str);
- duk_replace(ctx, idx);
+ duk_push_hstring(thr, h_str);
+ duk_replace(thr, idx);
return;
}
}
@@ -19127,13 +19807,13 @@ DUK_EXTERNAL void duk_to_primitive(duk_context *ctx, duk_idx_t idx, duk_int_t hi
coercers[1] = DUK_STRIDX_VALUE_OF;
}
- if (duk__defaultvalue_coerce_attempt(ctx, idx, coercers[0])) {
- DUK_ASSERT(!duk_is_buffer(ctx, idx)); /* duk_to_string() relies on this behavior */
+ if (duk__defaultvalue_coerce_attempt(thr, idx, coercers[0])) {
+ DUK_ASSERT(!duk_is_buffer(thr, idx)); /* duk_to_string() relies on this behavior */
return;
}
- if (duk__defaultvalue_coerce_attempt(ctx, idx, coercers[1])) {
- DUK_ASSERT(!duk_is_buffer(ctx, idx)); /* duk_to_string() relies on this behavior */
+ if (duk__defaultvalue_coerce_attempt(thr, idx, coercers[1])) {
+ DUK_ASSERT(!duk_is_buffer(thr, idx)); /* duk_to_string() relies on this behavior */
return;
}
@@ -19141,16 +19821,14 @@ DUK_EXTERNAL void duk_to_primitive(duk_context *ctx, duk_idx_t idx, duk_int_t hi
}
/* E5 Section 9.2 */
-DUK_EXTERNAL duk_bool_t duk_to_boolean(duk_context *ctx, duk_idx_t idx) {
- duk_hthread *thr = (duk_hthread *) ctx;
+DUK_EXTERNAL duk_bool_t duk_to_boolean(duk_hthread *thr, duk_idx_t idx) {
duk_tval *tv;
duk_bool_t val;
- DUK_ASSERT_CTX_VALID(ctx);
- DUK_UNREF(thr);
+ DUK_ASSERT_API_ENTRY(thr);
- idx = duk_require_normalize_index(ctx, idx);
- tv = DUK_GET_TVAL_POSIDX(ctx, idx);
+ idx = duk_require_normalize_index(thr, idx);
+ tv = DUK_GET_TVAL_POSIDX(thr, idx);
DUK_ASSERT(tv != NULL);
val = duk_js_toboolean(tv);
@@ -19162,43 +19840,64 @@ DUK_EXTERNAL duk_bool_t duk_to_boolean(duk_context *ctx, duk_idx_t idx) {
return val;
}
-DUK_EXTERNAL duk_double_t duk_to_number(duk_context *ctx, duk_idx_t idx) {
- duk_hthread *thr = (duk_hthread *) ctx;
+DUK_EXTERNAL duk_double_t duk_to_number(duk_hthread *thr, duk_idx_t idx) {
duk_tval *tv;
duk_double_t d;
- DUK_ASSERT_CTX_VALID(ctx);
+ DUK_ASSERT_API_ENTRY(thr);
/* XXX: No need to normalize; the whole operation could be inlined here to
* avoid 'tv' re-lookup.
*/
- idx = duk_require_normalize_index(ctx, idx);
- tv = DUK_GET_TVAL_POSIDX(ctx, idx);
+ idx = duk_require_normalize_index(thr, idx);
+ tv = DUK_GET_TVAL_POSIDX(thr, idx);
DUK_ASSERT(tv != NULL);
d = duk_js_tonumber(thr, tv); /* XXX: fastint coercion? now result will always be a non-fastint */
/* ToNumber() may have side effects so must relookup 'tv'. */
- tv = DUK_GET_TVAL_POSIDX(ctx, idx);
+ tv = DUK_GET_TVAL_POSIDX(thr, idx);
DUK_TVAL_SET_NUMBER_UPDREF(thr, tv, d); /* side effects */
return d;
}
-DUK_INTERNAL duk_double_t duk_to_number_m1(duk_context *ctx) {
- return duk_to_number(ctx, -1);
+DUK_INTERNAL duk_double_t duk_to_number_m1(duk_hthread *thr) {
+ DUK_ASSERT_API_ENTRY(thr);
+ return duk_to_number(thr, -1);
}
-DUK_INTERNAL duk_double_t duk_to_number_m2(duk_context *ctx) {
- return duk_to_number(ctx, -2);
+DUK_INTERNAL duk_double_t duk_to_number_m2(duk_hthread *thr) {
+ DUK_ASSERT_API_ENTRY(thr);
+ return duk_to_number(thr, -2);
}
-DUK_INTERNAL duk_double_t duk_to_number_tval(duk_context *ctx, duk_tval *tv) {
+DUK_INTERNAL duk_double_t duk_to_number_tval(duk_hthread *thr, duk_tval *tv) {
+#if defined(DUK_USE_PREFER_SIZE)
duk_double_t res;
- DUK_ASSERT_CTX_VALID(ctx);
+ DUK_ASSERT_API_ENTRY(thr);
- duk_push_tval(ctx, tv);
- res = duk_to_number(ctx, -1);
- duk_pop(ctx);
+ duk_push_tval(thr, tv);
+ res = duk_to_number_m1(thr);
+ duk_pop_unsafe(thr);
return res;
+#else
+ duk_double_t res;
+ duk_tval *tv_dst;
+
+ DUK_ASSERT_API_ENTRY(thr);
+ DUK__ASSERT_SPACE();
+
+ tv_dst = thr->valstack_top++;
+ DUK_TVAL_SET_TVAL(tv_dst, tv);
+ DUK_TVAL_INCREF(thr, tv_dst); /* decref not necessary */
+ res = duk_to_number_m1(thr); /* invalidates tv_dst */
+
+ tv_dst = --thr->valstack_top;
+ DUK_ASSERT(DUK_TVAL_IS_NUMBER(tv_dst));
+ DUK_ASSERT(!DUK_TVAL_NEEDS_REFCOUNT_UPDATE(tv_dst)); /* plain number */
+ DUK_TVAL_SET_UNDEFINED(tv_dst); /* valstack init policy */
+
+ return res;
+#endif
}
/* XXX: combine all the integer conversions: they share everything
@@ -19207,14 +19906,13 @@ DUK_INTERNAL duk_double_t duk_to_number_tval(duk_context *ctx, duk_tval *tv) {
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 idx, duk__toint_coercer coerce_func) {
- duk_hthread *thr = (duk_hthread *) ctx;
+DUK_LOCAL duk_double_t duk__to_int_uint_helper(duk_hthread *thr, duk_idx_t idx, duk__toint_coercer coerce_func) {
duk_tval *tv;
duk_double_t d;
- DUK_ASSERT_CTX_VALID(ctx);
+ DUK_ASSERT_CTX_VALID(thr);
- tv = duk_require_tval(ctx, idx);
+ tv = duk_require_tval(thr, idx);
DUK_ASSERT(tv != NULL);
#if defined(DUK_USE_FASTINT)
@@ -19231,93 +19929,92 @@ DUK_LOCAL duk_double_t duk__to_int_uint_helper(duk_context *ctx, duk_idx_t idx,
/* XXX: fastint? */
/* Relookup in case coerce_func() has side effects, e.g. ends up coercing an object */
- tv = duk_require_tval(ctx, idx);
+ tv = duk_require_tval(thr, idx);
DUK_TVAL_SET_NUMBER_UPDREF(thr, tv, d); /* side effects */
return d;
}
-DUK_EXTERNAL duk_int_t duk_to_int(duk_context *ctx, duk_idx_t idx) {
+DUK_EXTERNAL duk_int_t duk_to_int(duk_hthread *thr, duk_idx_t idx) {
/* Value coercion (in stack): ToInteger(), E5 Section 9.4,
* API return value coercion: custom.
*/
- DUK_ASSERT_CTX_VALID(ctx);
- (void) duk__to_int_uint_helper(ctx, idx, duk_js_tointeger);
- return (duk_int_t) duk__api_coerce_d2i(ctx, idx, 0 /*def_value*/, 0 /*require*/);
+ DUK_ASSERT_API_ENTRY(thr);
+ (void) duk__to_int_uint_helper(thr, idx, duk_js_tointeger);
+ return (duk_int_t) duk__api_coerce_d2i(thr, idx, 0 /*def_value*/, 0 /*require*/);
}
-DUK_EXTERNAL duk_uint_t duk_to_uint(duk_context *ctx, duk_idx_t idx) {
+DUK_EXTERNAL duk_uint_t duk_to_uint(duk_hthread *thr, duk_idx_t idx) {
/* Value coercion (in stack): ToInteger(), E5 Section 9.4,
* API return value coercion: custom.
*/
- DUK_ASSERT_CTX_VALID(ctx);
- (void) duk__to_int_uint_helper(ctx, idx, duk_js_tointeger);
- return (duk_uint_t) duk__api_coerce_d2ui(ctx, idx, 0 /*def_value*/, 0 /*require*/);
+ DUK_ASSERT_API_ENTRY(thr);
+ (void) duk__to_int_uint_helper(thr, idx, duk_js_tointeger);
+ return (duk_uint_t) duk__api_coerce_d2ui(thr, idx, 0 /*def_value*/, 0 /*require*/);
}
-DUK_EXTERNAL duk_int32_t duk_to_int32(duk_context *ctx, duk_idx_t idx) {
- duk_hthread *thr = (duk_hthread *) ctx;
+DUK_EXTERNAL duk_int32_t duk_to_int32(duk_hthread *thr, duk_idx_t idx) {
duk_tval *tv;
duk_int32_t ret;
- DUK_ASSERT_CTX_VALID(ctx);
+ DUK_ASSERT_API_ENTRY(thr);
- tv = duk_require_tval(ctx, idx);
+ tv = duk_require_tval(thr, idx);
DUK_ASSERT(tv != NULL);
ret = duk_js_toint32(thr, tv);
/* Relookup in case coerce_func() has side effects, e.g. ends up coercing an object */
- tv = duk_require_tval(ctx, idx);
+ tv = duk_require_tval(thr, idx);
DUK_TVAL_SET_I32_UPDREF(thr, tv, ret); /* side effects */
return ret;
}
-DUK_EXTERNAL duk_uint32_t duk_to_uint32(duk_context *ctx, duk_idx_t idx) {
- duk_hthread *thr = (duk_hthread *) ctx;
+DUK_EXTERNAL duk_uint32_t duk_to_uint32(duk_hthread *thr, duk_idx_t idx) {
duk_tval *tv;
duk_uint32_t ret;
- DUK_ASSERT_CTX_VALID(ctx);
+ DUK_ASSERT_API_ENTRY(thr);
- tv = duk_require_tval(ctx, idx);
+ tv = duk_require_tval(thr, idx);
DUK_ASSERT(tv != NULL);
ret = duk_js_touint32(thr, tv);
/* Relookup in case coerce_func() has side effects, e.g. ends up coercing an object */
- tv = duk_require_tval(ctx, idx);
+ tv = duk_require_tval(thr, idx);
DUK_TVAL_SET_U32_UPDREF(thr, tv, ret); /* side effects */
return ret;
}
-DUK_EXTERNAL duk_uint16_t duk_to_uint16(duk_context *ctx, duk_idx_t idx) {
- duk_hthread *thr = (duk_hthread *) ctx;
+DUK_EXTERNAL duk_uint16_t duk_to_uint16(duk_hthread *thr, duk_idx_t idx) {
duk_tval *tv;
duk_uint16_t ret;
- DUK_ASSERT_CTX_VALID(ctx);
+ DUK_ASSERT_API_ENTRY(thr);
- tv = duk_require_tval(ctx, idx);
+ tv = duk_require_tval(thr, idx);
DUK_ASSERT(tv != NULL);
ret = duk_js_touint16(thr, tv);
/* Relookup in case coerce_func() has side effects, e.g. ends up coercing an object */
- tv = duk_require_tval(ctx, idx);
+ tv = duk_require_tval(thr, idx);
DUK_TVAL_SET_U32_UPDREF(thr, tv, ret); /* side effects */
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 idx) {
+DUK_INTERNAL duk_uint8_t duk_to_uint8clamped(duk_hthread *thr, duk_idx_t idx) {
duk_double_t d;
duk_double_t t;
duk_uint8_t ret;
+ DUK_ASSERT_API_ENTRY(thr);
+
/* XXX: Simplify this algorithm, should be possible to come up with
* a shorter and faster algorithm by inspecting IEEE representation
* directly.
*/
- d = duk_to_number(ctx, idx);
+ d = duk_to_number(thr, idx);
if (d <= 0.0) {
return 0;
} else if (d >= 255) {
@@ -19342,41 +20039,41 @@ DUK_INTERNAL duk_uint8_t duk_to_uint8clamped(duk_context *ctx, duk_idx_t idx) {
}
#endif /* DUK_USE_BUFFEROBJECT_SUPPORT */
-DUK_EXTERNAL const char *duk_to_lstring(duk_context *ctx, duk_idx_t idx, duk_size_t *out_len) {
- DUK_ASSERT_CTX_VALID(ctx);
+DUK_EXTERNAL const char *duk_to_lstring(duk_hthread *thr, duk_idx_t idx, duk_size_t *out_len) {
+ DUK_ASSERT_API_ENTRY(thr);
- (void) duk_to_string(ctx, idx);
- DUK_ASSERT(duk_is_string(ctx, idx));
- return duk_require_lstring(ctx, idx, out_len);
+ (void) duk_to_string(thr, idx);
+ DUK_ASSERT(duk_is_string(thr, idx));
+ return duk_require_lstring(thr, idx, out_len);
}
-DUK_LOCAL duk_ret_t duk__safe_to_string_raw(duk_context *ctx, void *udata) {
- DUK_ASSERT_CTX_VALID(ctx);
+DUK_LOCAL duk_ret_t duk__safe_to_string_raw(duk_hthread *thr, void *udata) {
+ DUK_ASSERT_CTX_VALID(thr);
DUK_UNREF(udata);
- duk_to_string(ctx, -1);
+ duk_to_string(thr, -1);
return 1;
}
-DUK_EXTERNAL const char *duk_safe_to_lstring(duk_context *ctx, duk_idx_t idx, duk_size_t *out_len) {
- DUK_ASSERT_CTX_VALID(ctx);
+DUK_EXTERNAL const char *duk_safe_to_lstring(duk_hthread *thr, duk_idx_t idx, duk_size_t *out_len) {
+ DUK_ASSERT_API_ENTRY(thr);
- idx = duk_require_normalize_index(ctx, idx);
+ idx = duk_require_normalize_index(thr, idx);
/* We intentionally ignore the duk_safe_call() return value and only
* check the output type. This way we don't also need to check that
* the returned value is indeed a string in the success case.
*/
- duk_dup(ctx, idx);
- (void) duk_safe_call(ctx, duk__safe_to_string_raw, NULL /*udata*/, 1 /*nargs*/, 1 /*nrets*/);
- if (!duk_is_string(ctx, -1)) {
+ duk_dup(thr, idx);
+ (void) duk_safe_call(thr, duk__safe_to_string_raw, NULL /*udata*/, 1 /*nargs*/, 1 /*nrets*/);
+ if (!duk_is_string(thr, -1)) {
/* Error: try coercing error to string once. */
- (void) duk_safe_call(ctx, duk__safe_to_string_raw, NULL /*udata*/, 1 /*nargs*/, 1 /*nrets*/);
- if (!duk_is_string(ctx, -1)) {
+ (void) duk_safe_call(thr, duk__safe_to_string_raw, NULL /*udata*/, 1 /*nargs*/, 1 /*nrets*/);
+ if (!duk_is_string(thr, -1)) {
/* Double error */
- duk_pop(ctx);
- duk_push_hstring_stridx(ctx, DUK_STRIDX_UC_ERROR);
+ duk_pop_unsafe(thr);
+ duk_push_hstring_stridx(thr, DUK_STRIDX_UC_ERROR);
} else {
;
}
@@ -19384,50 +20081,49 @@ DUK_EXTERNAL const char *duk_safe_to_lstring(duk_context *ctx, duk_idx_t idx, du
/* String; may be a symbol, accepted. */
;
}
- DUK_ASSERT(duk_is_string(ctx, -1));
+ DUK_ASSERT(duk_is_string(thr, -1));
- duk_replace(ctx, idx);
- DUK_ASSERT(duk_get_string(ctx, idx) != NULL);
- return duk_get_lstring(ctx, idx, out_len);
+ duk_replace(thr, idx);
+ DUK_ASSERT(duk_get_string(thr, idx) != NULL);
+ return duk_get_lstring(thr, idx, out_len);
}
-DUK_INTERNAL duk_hstring *duk_to_property_key_hstring(duk_context *ctx, duk_idx_t idx) {
+DUK_INTERNAL duk_hstring *duk_to_property_key_hstring(duk_hthread *thr, duk_idx_t idx) {
duk_hstring *h;
- DUK_ASSERT_CTX_VALID(ctx);
+ DUK_ASSERT_API_ENTRY(thr);
- duk_to_primitive(ctx, idx, DUK_HINT_STRING); /* needed for e.g. Symbol objects */
- h = duk_get_hstring(ctx, idx);
+ duk_to_primitive(thr, idx, DUK_HINT_STRING); /* needed for e.g. Symbol objects */
+ h = duk_get_hstring(thr, idx);
if (h == NULL) {
/* The "is string?" check may seem unnecessary, but as things
* are duk_to_hstring() invokes ToString() which fails for
* symbols. But since symbols are already strings for Duktape
* C API, we check for that before doing the coercion.
*/
- h = duk_to_hstring(ctx, idx);
+ h = duk_to_hstring(thr, idx);
}
DUK_ASSERT(h != NULL);
return h;
}
#if defined(DUK_USE_DEBUGGER_SUPPORT) /* only needed by debugger for now */
-DUK_INTERNAL duk_hstring *duk_safe_to_hstring(duk_context *ctx, duk_idx_t idx) {
- (void) duk_safe_to_string(ctx, idx);
- DUK_ASSERT(duk_is_string(ctx, idx));
- DUK_ASSERT(duk_get_hstring(ctx, idx) != NULL);
- return duk_known_hstring(ctx, idx);
+DUK_INTERNAL duk_hstring *duk_safe_to_hstring(duk_hthread *thr, duk_idx_t idx) {
+ DUK_ASSERT_API_ENTRY(thr);
+
+ (void) duk_safe_to_string(thr, idx);
+ DUK_ASSERT(duk_is_string(thr, idx));
+ DUK_ASSERT(duk_get_hstring(thr, idx) != NULL);
+ return duk_known_hstring(thr, idx);
}
#endif
/* Push Object.prototype.toString() output for 'tv'. */
-DUK_INTERNAL void duk_push_class_string_tval(duk_context *ctx, duk_tval *tv) {
- duk_hthread *thr;
+DUK_INTERNAL void duk_push_class_string_tval(duk_hthread *thr, duk_tval *tv) {
duk_small_uint_t stridx;
duk_hstring *h_strclass;
- DUK_ASSERT_CTX_VALID(ctx);
- thr = (duk_hthread *) ctx;
- DUK_UNREF(thr);
+ DUK_ASSERT_API_ENTRY(thr);
switch (DUK_TVAL_GET_TAG(tv)) {
case DUK_TAG_UNUSED: /* Treat like 'undefined', shouldn't happen. */
@@ -19499,21 +20195,20 @@ DUK_INTERNAL void duk_push_class_string_tval(duk_context *ctx, duk_tval *tv) {
h_strclass = DUK_HTHREAD_GET_STRING(thr, stridx);
DUK_ASSERT(h_strclass != NULL);
- duk_push_sprintf(ctx, "[object %s]", (const char *) DUK_HSTRING_GET_DATA(h_strclass));
+ duk_push_sprintf(thr, "[object %s]", (const char *) DUK_HSTRING_GET_DATA(h_strclass));
}
/* XXX: other variants like uint, u32 etc */
-DUK_INTERNAL duk_int_t duk_to_int_clamped_raw(duk_context *ctx, duk_idx_t idx, duk_int_t minval, duk_int_t maxval, duk_bool_t *out_clamped) {
- duk_hthread *thr = (duk_hthread *) ctx;
+DUK_INTERNAL duk_int_t duk_to_int_clamped_raw(duk_hthread *thr, duk_idx_t idx, duk_int_t minval, duk_int_t maxval, duk_bool_t *out_clamped) {
duk_tval *tv;
duk_tval tv_tmp;
duk_double_t d, dmin, dmax;
duk_int_t res;
duk_bool_t clamped = 0;
- DUK_ASSERT_CTX_VALID(ctx);
+ DUK_ASSERT_API_ENTRY(thr);
- tv = duk_require_tval(ctx, idx);
+ tv = duk_require_tval(thr, idx);
DUK_ASSERT(tv != NULL);
d = duk_js_tointeger(thr, tv); /* E5 Section 9.4, ToInteger() */
@@ -19535,7 +20230,7 @@ DUK_INTERNAL duk_int_t duk_to_int_clamped_raw(duk_context *ctx, duk_idx_t idx, d
/* 'd' and 'res' agree here */
/* Relookup in case duk_js_tointeger() ends up e.g. coercing an object. */
- tv = duk_get_tval(ctx, idx);
+ tv = duk_get_tval(thr, idx);
DUK_ASSERT(tv != NULL); /* not popped by side effect */
DUK_TVAL_SET_TVAL(&tv_tmp, tv);
#if defined(DUK_USE_FASTINT)
@@ -19566,40 +20261,42 @@ DUK_INTERNAL duk_int_t duk_to_int_clamped_raw(duk_context *ctx, duk_idx_t idx, d
return res;
}
-DUK_INTERNAL duk_int_t duk_to_int_clamped(duk_context *ctx, duk_idx_t idx, duk_idx_t minval, duk_idx_t maxval) {
+DUK_INTERNAL duk_int_t duk_to_int_clamped(duk_hthread *thr, duk_idx_t idx, duk_idx_t minval, duk_idx_t maxval) {
duk_bool_t dummy;
- return duk_to_int_clamped_raw(ctx, idx, minval, maxval, &dummy);
+
+ DUK_ASSERT_API_ENTRY(thr);
+
+ return duk_to_int_clamped_raw(thr, idx, minval, maxval, &dummy);
}
-DUK_INTERNAL duk_int_t duk_to_int_check_range(duk_context *ctx, duk_idx_t idx, duk_int_t minval, duk_int_t maxval) {
- return duk_to_int_clamped_raw(ctx, idx, minval, maxval, NULL); /* out_clamped==NULL -> RangeError if outside range */
+DUK_INTERNAL duk_int_t duk_to_int_check_range(duk_hthread *thr, duk_idx_t idx, duk_int_t minval, duk_int_t maxval) {
+ DUK_ASSERT_API_ENTRY(thr);
+ return duk_to_int_clamped_raw(thr, idx, minval, maxval, NULL); /* out_clamped==NULL -> RangeError if outside range */
}
-DUK_EXTERNAL const char *duk_to_string(duk_context *ctx, duk_idx_t idx) {
- duk_hthread *thr = (duk_hthread *) ctx;
+DUK_EXTERNAL const char *duk_to_string(duk_hthread *thr, duk_idx_t idx) {
duk_tval *tv;
- DUK_ASSERT_CTX_VALID(ctx);
- DUK_UNREF(thr);
+ DUK_ASSERT_API_ENTRY(thr);
- idx = duk_require_normalize_index(ctx, idx);
- tv = DUK_GET_TVAL_POSIDX(ctx, idx);
+ idx = duk_require_normalize_index(thr, idx);
+ tv = DUK_GET_TVAL_POSIDX(thr, idx);
DUK_ASSERT(tv != NULL);
switch (DUK_TVAL_GET_TAG(tv)) {
case DUK_TAG_UNDEFINED: {
- duk_push_hstring_stridx(ctx, DUK_STRIDX_LC_UNDEFINED);
+ duk_push_hstring_stridx(thr, DUK_STRIDX_LC_UNDEFINED);
break;
}
case DUK_TAG_NULL: {
- duk_push_hstring_stridx(ctx, DUK_STRIDX_LC_NULL);
+ duk_push_hstring_stridx(thr, DUK_STRIDX_LC_NULL);
break;
}
case DUK_TAG_BOOLEAN: {
if (DUK_TVAL_GET_BOOLEAN(tv)) {
- duk_push_hstring_stridx(ctx, DUK_STRIDX_TRUE);
+ duk_push_hstring_stridx(thr, DUK_STRIDX_TRUE);
} else {
- duk_push_hstring_stridx(ctx, DUK_STRIDX_FALSE);
+ duk_push_hstring_stridx(thr, DUK_STRIDX_FALSE);
}
break;
}
@@ -19614,7 +20311,7 @@ DUK_EXTERNAL const char *duk_to_string(duk_context *ctx, duk_idx_t idx) {
h = DUK_TVAL_GET_STRING(tv);
DUK_ASSERT(h != NULL);
if (DUK_UNLIKELY(DUK_HSTRING_HAS_SYMBOL(h))) {
- DUK_ERROR_TYPE((duk_hthread *) ctx, DUK_STR_CANNOT_STRING_COERCE_SYMBOL);
+ DUK_ERROR_TYPE(thr, DUK_STR_CANNOT_STRING_COERCE_SYMBOL);
} else {
goto skip_replace;
}
@@ -19630,27 +20327,27 @@ DUK_EXTERNAL const char *duk_to_string(duk_context *ctx, duk_idx_t idx) {
* Symbol objects: duk_to_primitive() results in a plain symbol
* value, and duk_to_string() then causes a TypeError.
*/
- duk_to_primitive(ctx, idx, DUK_HINT_STRING);
- DUK_ASSERT(!duk_is_buffer(ctx, idx)); /* ToPrimitive() must guarantee */
- DUK_ASSERT(!duk_is_object(ctx, idx));
- return duk_to_string(ctx, idx); /* Note: recursive call */
+ duk_to_primitive(thr, idx, DUK_HINT_STRING);
+ DUK_ASSERT(!duk_is_buffer(thr, idx)); /* ToPrimitive() must guarantee */
+ DUK_ASSERT(!duk_is_object(thr, idx));
+ return duk_to_string(thr, idx); /* Note: recursive call */
}
case DUK_TAG_POINTER: {
void *ptr = DUK_TVAL_GET_POINTER(tv);
if (ptr != NULL) {
- duk_push_sprintf(ctx, DUK_STR_FMT_PTR, (void *) ptr);
+ duk_push_sprintf(thr, DUK_STR_FMT_PTR, (void *) ptr);
} else {
/* Represent a null pointer as 'null' to be consistent with
* the JX format variant. Native '%p' format for a NULL
* pointer may be e.g. '(nil)'.
*/
- duk_push_hstring_stridx(ctx, DUK_STRIDX_LC_NULL);
+ duk_push_hstring_stridx(thr, DUK_STRIDX_LC_NULL);
}
break;
}
case DUK_TAG_LIGHTFUNC: {
/* Should match Function.prototype.toString() */
- duk_push_lightfunc_tostring(ctx, tv);
+ duk_push_lightfunc_tostring(thr, tv);
break;
}
#if defined(DUK_USE_FASTINT)
@@ -19660,8 +20357,8 @@ DUK_EXTERNAL const char *duk_to_string(duk_context *ctx, duk_idx_t idx) {
/* number */
DUK_ASSERT(!DUK_TVAL_IS_UNUSED(tv));
DUK_ASSERT(DUK_TVAL_IS_NUMBER(tv));
- duk_push_tval(ctx, tv);
- duk_numconv_stringify(ctx,
+ duk_push_tval(thr, tv);
+ duk_numconv_stringify(thr,
10 /*radix*/,
0 /*precision:shortest*/,
0 /*force_exponential*/);
@@ -19669,34 +20366,39 @@ DUK_EXTERNAL const char *duk_to_string(duk_context *ctx, duk_idx_t idx) {
}
}
- duk_replace(ctx, idx);
+ duk_replace(thr, idx);
skip_replace:
- DUK_ASSERT(duk_is_string(ctx, idx));
- return duk_require_string(ctx, idx);
+ DUK_ASSERT(duk_is_string(thr, idx));
+ return duk_require_string(thr, idx);
}
-DUK_INTERNAL duk_hstring *duk_to_hstring(duk_context *ctx, duk_idx_t idx) {
+DUK_INTERNAL duk_hstring *duk_to_hstring(duk_hthread *thr, duk_idx_t idx) {
duk_hstring *ret;
- DUK_ASSERT_CTX_VALID(ctx);
- duk_to_string(ctx, idx);
- ret = duk_get_hstring(ctx, idx);
+
+ DUK_ASSERT_API_ENTRY(thr);
+
+ duk_to_string(thr, idx);
+ ret = duk_get_hstring(thr, idx);
DUK_ASSERT(ret != NULL);
return ret;
}
-DUK_INTERNAL duk_hstring *duk_to_hstring_m1(duk_context *ctx) {
- return duk_to_hstring(ctx, -1);
+DUK_INTERNAL duk_hstring *duk_to_hstring_m1(duk_hthread *thr) {
+ DUK_ASSERT_API_ENTRY(thr);
+ return duk_to_hstring(thr, -1);
}
-DUK_INTERNAL duk_hstring *duk_to_hstring_acceptsymbol(duk_context *ctx, duk_idx_t idx) {
+DUK_INTERNAL duk_hstring *duk_to_hstring_acceptsymbol(duk_hthread *thr, duk_idx_t idx) {
duk_hstring *ret;
- DUK_ASSERT_CTX_VALID(ctx);
- ret = duk_get_hstring(ctx, idx);
+
+ DUK_ASSERT_API_ENTRY(thr);
+
+ ret = duk_get_hstring(thr, idx);
if (DUK_UNLIKELY(ret && DUK_HSTRING_HAS_SYMBOL(ret))) {
return ret;
}
- return duk_to_hstring(ctx, idx);
+ return duk_to_hstring(thr, idx);
}
/* Convert a plain buffer or any buffer object into a string, using the buffer
@@ -19706,34 +20408,34 @@ DUK_INTERNAL duk_hstring *duk_to_hstring_acceptsymbol(duk_context *ctx, duk_idx_
* string with the same bytes as in the buffer but rather (usually)
* '[object ArrayBuffer]'.
*/
-DUK_EXTERNAL const char *duk_buffer_to_string(duk_context *ctx, duk_idx_t idx) {
+DUK_EXTERNAL const char *duk_buffer_to_string(duk_hthread *thr, duk_idx_t idx) {
void *ptr_src;
duk_size_t len;
const char *res;
- idx = duk_require_normalize_index(ctx, idx);
+ DUK_ASSERT_API_ENTRY(thr);
- ptr_src = duk_require_buffer_data(ctx, idx, &len);
+ idx = duk_require_normalize_index(thr, idx);
+
+ ptr_src = duk_require_buffer_data(thr, idx, &len);
DUK_ASSERT(ptr_src != NULL || len == 0);
- res = duk_push_lstring(ctx, (const char *) ptr_src, len);
- duk_replace(ctx, idx);
+ res = duk_push_lstring(thr, (const char *) ptr_src, len);
+ duk_replace(thr, idx);
return res;
}
-DUK_EXTERNAL void *duk_to_buffer_raw(duk_context *ctx, duk_idx_t idx, duk_size_t *out_size, duk_uint_t mode) {
- duk_hthread *thr = (duk_hthread *) ctx;
+DUK_EXTERNAL void *duk_to_buffer_raw(duk_hthread *thr, duk_idx_t idx, duk_size_t *out_size, duk_uint_t mode) {
duk_hbuffer *h_buf;
const duk_uint8_t *src_data;
duk_size_t src_size;
duk_uint8_t *dst_data;
- DUK_ASSERT_CTX_VALID(ctx);
- DUK_UNREF(thr);
+ DUK_ASSERT_API_ENTRY(thr);
- idx = duk_require_normalize_index(ctx, idx);
+ idx = duk_require_normalize_index(thr, idx);
- h_buf = duk_get_hbuffer(ctx, idx);
+ h_buf = duk_get_hbuffer(thr, idx);
if (h_buf != NULL) {
/* Buffer is kept as is, with the fixed/dynamic nature of the
* buffer only changed if requested. An external buffer
@@ -19762,10 +20464,10 @@ DUK_EXTERNAL void *duk_to_buffer_raw(duk_context *ctx, duk_idx_t idx, duk_size_t
* explicitly requested). Symbols are rejected with a TypeError.
* XXX: C API could maybe allow symbol-to-buffer coercion?
*/
- src_data = (const duk_uint8_t *) duk_to_lstring(ctx, idx, &src_size);
+ src_data = (const duk_uint8_t *) duk_to_lstring(thr, idx, &src_size);
}
- dst_data = (duk_uint8_t *) duk_push_buffer(ctx, src_size, (mode == DUK_BUF_MODE_DYNAMIC) /*dynamic*/);
+ dst_data = (duk_uint8_t *) duk_push_buffer(thr, src_size, (mode == DUK_BUF_MODE_DYNAMIC) /*dynamic*/);
if (DUK_LIKELY(src_size > 0)) {
/* When src_size == 0, src_data may be NULL (if source
* buffer is dynamic), and dst_data may be NULL (if
@@ -19774,7 +20476,7 @@ DUK_EXTERNAL void *duk_to_buffer_raw(duk_context *ctx, duk_idx_t idx, duk_size_t
*/
DUK_MEMCPY((void *) dst_data, (const void *) src_data, (size_t) src_size);
}
- duk_replace(ctx, idx);
+ duk_replace(thr, idx);
skip_copy:
if (out_size) {
@@ -19783,14 +20485,14 @@ DUK_EXTERNAL void *duk_to_buffer_raw(duk_context *ctx, duk_idx_t idx, duk_size_t
return dst_data;
}
-DUK_EXTERNAL void *duk_to_pointer(duk_context *ctx, duk_idx_t idx) {
+DUK_EXTERNAL void *duk_to_pointer(duk_hthread *thr, duk_idx_t idx) {
duk_tval *tv;
void *res;
- DUK_ASSERT_CTX_VALID(ctx);
+ DUK_ASSERT_API_ENTRY(thr);
- idx = duk_require_normalize_index(ctx, idx);
- tv = DUK_GET_TVAL_POSIDX(ctx, idx);
+ idx = duk_require_normalize_index(thr, idx);
+ tv = DUK_GET_TVAL_POSIDX(thr, idx);
DUK_ASSERT(tv != NULL);
switch (DUK_TVAL_GET_TAG(tv)) {
@@ -19828,12 +20530,12 @@ DUK_EXTERNAL void *duk_to_pointer(duk_context *ctx, duk_idx_t idx) {
break;
}
- duk_push_pointer(ctx, res);
- duk_replace(ctx, idx);
+ duk_push_pointer(thr, res);
+ duk_replace(thr, idx);
return res;
}
-DUK_LOCAL void duk__push_func_from_lightfunc(duk_context *ctx, duk_c_function func, duk_small_uint_t lf_flags) {
+DUK_LOCAL void duk__push_func_from_lightfunc(duk_hthread *thr, duk_c_function func, duk_small_uint_t lf_flags) {
duk_idx_t nargs;
duk_uint_t flags = 0; /* shared flags for a subset of types */
duk_small_uint_t lf_len;
@@ -19846,44 +20548,40 @@ DUK_LOCAL void duk__push_func_from_lightfunc(duk_context *ctx, duk_c_function fu
flags = DUK_HOBJECT_FLAG_EXTENSIBLE |
DUK_HOBJECT_FLAG_CONSTRUCTABLE |
+ DUK_HOBJECT_FLAG_CALLABLE |
DUK_HOBJECT_FLAG_FASTREFS |
DUK_HOBJECT_FLAG_NATFUNC |
DUK_HOBJECT_FLAG_NEWENV |
DUK_HOBJECT_FLAG_STRICT |
DUK_HOBJECT_FLAG_NOTAIL |
- /* DUK_HOBJECT_FLAG_EXOTIC_DUKFUNC: omitted here intentionally */
DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_FUNCTION);
- (void) duk__push_c_function_raw(ctx, func, nargs, flags);
+ (void) duk__push_c_function_raw(thr, func, nargs, flags, DUK_BIDX_NATIVE_FUNCTION_PROTOTYPE);
lf_len = DUK_LFUNC_FLAGS_GET_LENGTH(lf_flags);
if ((duk_idx_t) lf_len != nargs) {
/* Explicit length is only needed if it differs from 'nargs'. */
- duk_push_int(ctx, (duk_int_t) lf_len);
- duk_xdef_prop_stridx_short(ctx, -2, DUK_STRIDX_LENGTH, DUK_PROPDESC_FLAGS_NONE);
+ duk_push_int(thr, (duk_int_t) lf_len);
+ duk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_LENGTH, DUK_PROPDESC_FLAGS_NONE);
}
#if defined(DUK_USE_FUNC_NAME_PROPERTY)
- duk_push_lightfunc_name_raw(ctx, func, lf_flags);
- duk_xdef_prop_stridx_short(ctx, -2, DUK_STRIDX_NAME, DUK_PROPDESC_FLAGS_C);
+ duk_push_lightfunc_name_raw(thr, func, lf_flags);
+ duk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_NAME, DUK_PROPDESC_FLAGS_C);
#endif
- nf = duk_known_hnatfunc(ctx, -1);
+ nf = duk_known_hnatfunc(thr, -1);
nf->magic = (duk_int16_t) DUK_LFUNC_FLAGS_GET_MAGIC(lf_flags);
-
- /* Enable DUKFUNC exotic behavior once properties are set up. */
- DUK_HOBJECT_SET_EXOTIC_DUKFUNC((duk_hobject *) nf);
}
-DUK_EXTERNAL void duk_to_object(duk_context *ctx, duk_idx_t idx) {
- duk_hthread *thr = (duk_hthread *) ctx;
+DUK_EXTERNAL void duk_to_object(duk_hthread *thr, duk_idx_t idx) {
duk_tval *tv;
duk_uint_t flags = 0; /* shared flags for a subset of types */
duk_small_int_t proto = 0;
- DUK_ASSERT_CTX_VALID(ctx);
+ DUK_ASSERT_API_ENTRY(thr);
- idx = duk_require_normalize_index(ctx, idx);
- tv = DUK_GET_TVAL_POSIDX(ctx, idx);
+ idx = duk_require_normalize_index(thr, idx);
+ tv = DUK_GET_TVAL_POSIDX(thr, idx);
DUK_ASSERT(tv != NULL);
switch (DUK_TVAL_GET_TAG(tv)) {
@@ -19962,7 +20660,7 @@ DUK_EXTERNAL void duk_to_object(duk_context *ctx, duk_idx_t idx) {
duk_c_function func;
DUK_TVAL_GET_LIGHTFUNC(tv, func, lf_flags);
- duk__push_func_from_lightfunc(ctx, func, lf_flags);
+ duk__push_func_from_lightfunc(thr, func, lf_flags);
goto replace_value;
}
#if defined(DUK_USE_FASTINT)
@@ -19978,11 +20676,11 @@ DUK_EXTERNAL void duk_to_object(duk_context *ctx, duk_idx_t idx) {
goto create_object;
}
}
- DUK_ASSERT(duk_is_object(ctx, idx));
+ DUK_ASSERT(duk_is_object(thr, idx));
return;
create_object:
- (void) duk_push_object_helper(ctx, flags, proto);
+ (void) duk_push_object_helper(thr, flags, proto);
/* Note: Boolean prototype's internal value property is not writable,
* but duk_xdef_prop_stridx() disregards the write protection. Boolean
@@ -19991,19 +20689,21 @@ DUK_EXTERNAL void duk_to_object(duk_context *ctx, duk_idx_t idx) {
* String and buffer special behaviors are already enabled which is not
* ideal, but a write to the internal value is not affected by them.
*/
- duk_dup(ctx, idx);
- duk_xdef_prop_stridx_short(ctx, -2, DUK_STRIDX_INT_VALUE, DUK_PROPDESC_FLAGS_NONE);
+ duk_dup(thr, idx);
+ duk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_INT_VALUE, DUK_PROPDESC_FLAGS_NONE);
replace_value:
- duk_replace(ctx, idx);
- DUK_ASSERT(duk_is_object(ctx, idx));
+ duk_replace(thr, idx);
+ DUK_ASSERT(duk_is_object(thr, idx));
}
-DUK_INTERNAL duk_hobject *duk_to_hobject(duk_context *ctx, duk_idx_t idx) {
+DUK_INTERNAL duk_hobject *duk_to_hobject(duk_hthread *thr, duk_idx_t idx) {
duk_hobject *ret;
- DUK_ASSERT_CTX_VALID(ctx);
- duk_to_object(ctx, idx);
- ret = duk_known_hobject(ctx, idx);
+
+ DUK_ASSERT_API_ENTRY(thr);
+
+ duk_to_object(thr, idx);
+ ret = duk_known_hobject(thr, idx);
return ret;
}
@@ -20011,20 +20711,20 @@ DUK_INTERNAL duk_hobject *duk_to_hobject(duk_context *ctx, duk_idx_t idx) {
* Type checking
*/
-DUK_LOCAL duk_bool_t duk__tag_check(duk_context *ctx, duk_idx_t idx, duk_small_uint_t tag) {
+DUK_LOCAL duk_bool_t duk__tag_check(duk_hthread *thr, duk_idx_t idx, duk_small_uint_t tag) {
duk_tval *tv;
- tv = duk_get_tval_or_unused(ctx, idx);
+ tv = duk_get_tval_or_unused(thr, idx);
DUK_ASSERT(tv != NULL);
return (DUK_TVAL_GET_TAG(tv) == tag);
}
-DUK_LOCAL duk_bool_t duk__obj_flag_any_default_false(duk_context *ctx, duk_idx_t idx, duk_uint_t flag_mask) {
+DUK_LOCAL duk_bool_t duk__obj_flag_any_default_false(duk_hthread *thr, duk_idx_t idx, duk_uint_t flag_mask) {
duk_hobject *obj;
- DUK_ASSERT_CTX_VALID(ctx);
+ DUK_ASSERT_API_ENTRY(thr);
- obj = duk_get_hobject(ctx, idx);
+ obj = duk_get_hobject(thr, idx);
if (obj) {
return (DUK_HEAPHDR_CHECK_FLAG_BITS((duk_heaphdr *) obj, flag_mask) ? 1 : 0);
}
@@ -20070,19 +20770,19 @@ DUK_INTERNAL duk_int_t duk_get_type_tval(duk_tval *tv) {
#endif /* DUK_USE_PACKED_TVAL */
}
-DUK_EXTERNAL duk_int_t duk_get_type(duk_context *ctx, duk_idx_t idx) {
+DUK_EXTERNAL duk_int_t duk_get_type(duk_hthread *thr, duk_idx_t idx) {
duk_tval *tv;
- DUK_ASSERT_CTX_VALID(ctx);
+ DUK_ASSERT_API_ENTRY(thr);
- tv = duk_get_tval_or_unused(ctx, idx);
+ tv = duk_get_tval_or_unused(thr, idx);
DUK_ASSERT(tv != NULL);
return duk_get_type_tval(tv);
}
#if defined(DUK_USE_VERBOSE_ERRORS) && defined(DUK_USE_PARANOID_ERRORS)
-DUK_LOCAL const char *duk__type_names[] = {
+DUK_LOCAL const char * const duk__type_names[] = {
"none",
"undefined",
"null",
@@ -20095,22 +20795,26 @@ DUK_LOCAL const char *duk__type_names[] = {
"lightfunc"
};
-DUK_INTERNAL const char *duk_get_type_name(duk_context *ctx, duk_idx_t idx) {
+DUK_INTERNAL const char *duk_get_type_name(duk_hthread *thr, duk_idx_t idx) {
duk_int_t type_tag;
- type_tag = duk_get_type(ctx, idx);
+ DUK_ASSERT_API_ENTRY(thr);
+
+ type_tag = duk_get_type(thr, idx);
DUK_ASSERT(type_tag >= DUK_TYPE_MIN && type_tag <= DUK_TYPE_MAX);
DUK_ASSERT(DUK_TYPE_MIN == 0 && sizeof(duk__type_names) / sizeof(const char *) == DUK_TYPE_MAX + 1);
return duk__type_names[type_tag];
}
-#endif
+#endif /* DUK_USE_VERBOSE_ERRORS && DUK_USE_PARANOID_ERRORS */
-DUK_INTERNAL duk_small_uint_t duk_get_class_number(duk_context *ctx, duk_idx_t idx) {
+DUK_INTERNAL duk_small_uint_t duk_get_class_number(duk_hthread *thr, duk_idx_t idx) {
duk_tval *tv;
duk_hobject *obj;
- tv = duk_get_tval_or_unused(ctx, idx);
+ DUK_ASSERT_API_ENTRY(thr);
+
+ tv = duk_get_tval_or_unused(thr, idx);
DUK_ASSERT(tv != NULL);
switch (DUK_TVAL_GET_TAG(tv)) {
@@ -20130,10 +20834,10 @@ DUK_INTERNAL duk_small_uint_t duk_get_class_number(duk_context *ctx, duk_idx_t i
}
}
-DUK_EXTERNAL duk_bool_t duk_check_type(duk_context *ctx, duk_idx_t idx, duk_int_t type) {
- DUK_ASSERT_CTX_VALID(ctx);
+DUK_EXTERNAL duk_bool_t duk_check_type(duk_hthread *thr, duk_idx_t idx, duk_int_t type) {
+ DUK_ASSERT_API_ENTRY(thr);
- return (duk_get_type(ctx, idx) == type) ? 1 : 0;
+ return (duk_get_type(thr, idx) == type) ? 1 : 0;
}
DUK_INTERNAL duk_uint_t duk_get_type_mask_tval(duk_tval *tv) {
@@ -20171,27 +20875,25 @@ DUK_INTERNAL duk_uint_t duk_get_type_mask_tval(duk_tval *tv) {
#else /* DUK_USE_PACKED_TVAL */
DUK_ASSERT(DUK_TVAL_IS_VALID_TAG(tv));
DUK_ASSERT(sizeof(duk__type_mask_from_tag) / sizeof(duk_uint_t) == DUK_TAG_MAX - DUK_TAG_MIN + 1);
- return (duk_int_t) duk__type_mask_from_tag[DUK_TVAL_GET_TAG(tv) - DUK_TAG_MIN];
+ return duk__type_mask_from_tag[DUK_TVAL_GET_TAG(tv) - DUK_TAG_MIN];
#endif /* DUK_USE_PACKED_TVAL */
}
-DUK_EXTERNAL duk_uint_t duk_get_type_mask(duk_context *ctx, duk_idx_t idx) {
+DUK_EXTERNAL duk_uint_t duk_get_type_mask(duk_hthread *thr, duk_idx_t idx) {
duk_tval *tv;
- DUK_ASSERT_CTX_VALID(ctx);
+ DUK_ASSERT_API_ENTRY(thr);
- tv = duk_get_tval_or_unused(ctx, idx);
+ tv = duk_get_tval_or_unused(thr, idx);
DUK_ASSERT(tv != NULL);
return duk_get_type_mask_tval(tv);
}
-DUK_EXTERNAL duk_bool_t duk_check_type_mask(duk_context *ctx, duk_idx_t idx, duk_uint_t mask) {
- duk_hthread *thr = (duk_hthread *) ctx;
+DUK_EXTERNAL duk_bool_t duk_check_type_mask(duk_hthread *thr, duk_idx_t idx, duk_uint_t mask) {
+ DUK_ASSERT_API_ENTRY(thr);
- DUK_ASSERT_CTX_VALID(ctx);
-
- if (DUK_LIKELY(duk_get_type_mask(ctx, idx) & mask)) {
+ if (DUK_LIKELY((duk_get_type_mask(thr, idx) & mask) != 0U)) {
return 1;
}
if (mask & DUK_TYPE_MASK_THROW) {
@@ -20201,25 +20903,25 @@ DUK_EXTERNAL duk_bool_t duk_check_type_mask(duk_context *ctx, duk_idx_t idx, duk
return 0;
}
-DUK_EXTERNAL duk_bool_t duk_is_undefined(duk_context *ctx, duk_idx_t idx) {
- DUK_ASSERT_CTX_VALID(ctx);
- return duk__tag_check(ctx, idx, DUK_TAG_UNDEFINED);
+DUK_EXTERNAL duk_bool_t duk_is_undefined(duk_hthread *thr, duk_idx_t idx) {
+ DUK_ASSERT_API_ENTRY(thr);
+ return duk__tag_check(thr, idx, DUK_TAG_UNDEFINED);
}
-DUK_EXTERNAL duk_bool_t duk_is_null(duk_context *ctx, duk_idx_t idx) {
- DUK_ASSERT_CTX_VALID(ctx);
- return duk__tag_check(ctx, idx, DUK_TAG_NULL);
+DUK_EXTERNAL duk_bool_t duk_is_null(duk_hthread *thr, duk_idx_t idx) {
+ DUK_ASSERT_API_ENTRY(thr);
+ return duk__tag_check(thr, idx, DUK_TAG_NULL);
}
-DUK_EXTERNAL duk_bool_t duk_is_boolean(duk_context *ctx, duk_idx_t idx) {
- DUK_ASSERT_CTX_VALID(ctx);
- return duk__tag_check(ctx, idx, DUK_TAG_BOOLEAN);
+DUK_EXTERNAL duk_bool_t duk_is_boolean(duk_hthread *thr, duk_idx_t idx) {
+ DUK_ASSERT_API_ENTRY(thr);
+ return duk__tag_check(thr, idx, DUK_TAG_BOOLEAN);
}
-DUK_EXTERNAL duk_bool_t duk_is_number(duk_context *ctx, duk_idx_t idx) {
+DUK_EXTERNAL duk_bool_t duk_is_number(duk_hthread *thr, duk_idx_t idx) {
duk_tval *tv;
- DUK_ASSERT_CTX_VALID(ctx);
+ DUK_ASSERT_API_ENTRY(thr);
/*
* Number is special because it doesn't have a specific
@@ -20228,12 +20930,12 @@ DUK_EXTERNAL duk_bool_t duk_is_number(duk_context *ctx, duk_idx_t idx) {
/* XXX: shorter version for unpacked representation? */
- tv = duk_get_tval_or_unused(ctx, idx);
+ tv = duk_get_tval_or_unused(thr, idx);
DUK_ASSERT(tv != NULL);
return DUK_TVAL_IS_NUMBER(tv);
}
-DUK_EXTERNAL duk_bool_t duk_is_nan(duk_context *ctx, duk_idx_t idx) {
+DUK_EXTERNAL duk_bool_t duk_is_nan(duk_hthread *thr, duk_idx_t idx) {
/* XXX: This will now return false for non-numbers, even though they would
* coerce to NaN (as a general rule). In particular, duk_get_number()
* returns a NaN for non-numbers, so should this function also return
@@ -20242,45 +20944,45 @@ DUK_EXTERNAL duk_bool_t duk_is_nan(duk_context *ctx, duk_idx_t idx) {
duk_tval *tv;
- DUK_ASSERT_CTX_VALID(ctx);
+ DUK_ASSERT_API_ENTRY(thr);
- tv = duk_get_tval_or_unused(ctx, idx);
+ tv = duk_get_tval_or_unused(thr, idx);
DUK_ASSERT(tv != NULL);
/* XXX: for packed duk_tval an explicit "is number" check is unnecessary */
if (!DUK_TVAL_IS_NUMBER(tv)) {
return 0;
}
- return DUK_ISNAN(DUK_TVAL_GET_NUMBER(tv));
+ return (duk_bool_t) DUK_ISNAN(DUK_TVAL_GET_NUMBER(tv));
}
-DUK_EXTERNAL duk_bool_t duk_is_string(duk_context *ctx, duk_idx_t idx) {
- DUK_ASSERT_CTX_VALID(ctx);
- return duk__tag_check(ctx, idx, DUK_TAG_STRING);
+DUK_EXTERNAL duk_bool_t duk_is_string(duk_hthread *thr, duk_idx_t idx) {
+ DUK_ASSERT_API_ENTRY(thr);
+ return duk__tag_check(thr, idx, DUK_TAG_STRING);
}
-DUK_INTERNAL duk_bool_t duk_is_string_notsymbol(duk_context *ctx, duk_idx_t idx) {
- DUK_ASSERT_CTX_VALID(ctx);
- return duk_get_hstring_notsymbol(ctx, idx) != NULL;
+DUK_INTERNAL duk_bool_t duk_is_string_notsymbol(duk_hthread *thr, duk_idx_t idx) {
+ DUK_ASSERT_API_ENTRY(thr);
+ return duk_get_hstring_notsymbol(thr, idx) != NULL;
}
-DUK_EXTERNAL duk_bool_t duk_is_object(duk_context *ctx, duk_idx_t idx) {
- DUK_ASSERT_CTX_VALID(ctx);
- return duk__tag_check(ctx, idx, DUK_TAG_OBJECT);
+DUK_EXTERNAL duk_bool_t duk_is_object(duk_hthread *thr, duk_idx_t idx) {
+ DUK_ASSERT_API_ENTRY(thr);
+ return duk__tag_check(thr, idx, DUK_TAG_OBJECT);
}
-DUK_EXTERNAL duk_bool_t duk_is_buffer(duk_context *ctx, duk_idx_t idx) {
- DUK_ASSERT_CTX_VALID(ctx);
- return duk__tag_check(ctx, idx, DUK_TAG_BUFFER);
+DUK_EXTERNAL duk_bool_t duk_is_buffer(duk_hthread *thr, duk_idx_t idx) {
+ DUK_ASSERT_API_ENTRY(thr);
+ return duk__tag_check(thr, idx, DUK_TAG_BUFFER);
}
#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)
-DUK_EXTERNAL duk_bool_t duk_is_buffer_data(duk_context *ctx, duk_idx_t idx) {
+DUK_EXTERNAL duk_bool_t duk_is_buffer_data(duk_hthread *thr, duk_idx_t idx) {
duk_tval *tv;
- DUK_ASSERT_CTX_VALID(ctx);
+ DUK_ASSERT_API_ENTRY(thr);
- tv = duk_get_tval_or_unused(ctx, idx);
+ tv = duk_get_tval_or_unused(thr, idx);
DUK_ASSERT(tv != NULL);
if (DUK_TVAL_IS_BUFFER(tv)) {
return 1;
@@ -20294,29 +20996,29 @@ DUK_EXTERNAL duk_bool_t duk_is_buffer_data(duk_context *ctx, duk_idx_t idx) {
return 0;
}
#else /* DUK_USE_BUFFEROBJECT_SUPPORT */
-DUK_EXTERNAL duk_bool_t duk_is_buffer_data(duk_context *ctx, duk_idx_t idx) {
- DUK_ASSERT_CTX_VALID(ctx);
+DUK_EXTERNAL duk_bool_t duk_is_buffer_data(duk_hthread *thr, duk_idx_t idx) {
+ DUK_ASSERT_API_ENTRY(thr);
- return duk_is_buffer(ctx, idx);
+ return duk_is_buffer(thr, idx);
}
#endif /* DUK_USE_BUFFEROBJECT_SUPPORT */
-DUK_EXTERNAL duk_bool_t duk_is_pointer(duk_context *ctx, duk_idx_t idx) {
- DUK_ASSERT_CTX_VALID(ctx);
- return duk__tag_check(ctx, idx, DUK_TAG_POINTER);
+DUK_EXTERNAL duk_bool_t duk_is_pointer(duk_hthread *thr, duk_idx_t idx) {
+ DUK_ASSERT_API_ENTRY(thr);
+ return duk__tag_check(thr, idx, DUK_TAG_POINTER);
}
-DUK_EXTERNAL duk_bool_t duk_is_lightfunc(duk_context *ctx, duk_idx_t idx) {
- DUK_ASSERT_CTX_VALID(ctx);
- return duk__tag_check(ctx, idx, DUK_TAG_LIGHTFUNC);
+DUK_EXTERNAL duk_bool_t duk_is_lightfunc(duk_hthread *thr, duk_idx_t idx) {
+ DUK_ASSERT_API_ENTRY(thr);
+ return duk__tag_check(thr, idx, DUK_TAG_LIGHTFUNC);
}
-DUK_EXTERNAL duk_bool_t duk_is_symbol(duk_context *ctx, duk_idx_t idx) {
+DUK_EXTERNAL duk_bool_t duk_is_symbol(duk_hthread *thr, duk_idx_t idx) {
duk_hstring *h;
- DUK_ASSERT_CTX_VALID(ctx);
- h = duk_get_hstring(ctx, idx);
+ DUK_ASSERT_API_ENTRY(thr);
+ h = duk_get_hstring(thr, idx);
/* Use DUK_LIKELY() here because caller may be more likely to type
* check an expected symbol than not.
*/
@@ -20326,73 +21028,110 @@ DUK_EXTERNAL duk_bool_t duk_is_symbol(duk_context *ctx, duk_idx_t idx) {
return 0;
}
-DUK_EXTERNAL duk_bool_t duk_is_array(duk_context *ctx, duk_idx_t idx) {
+DUK_EXTERNAL duk_bool_t duk_is_array(duk_hthread *thr, duk_idx_t idx) {
duk_hobject *obj;
- DUK_ASSERT_CTX_VALID(ctx);
+ DUK_ASSERT_API_ENTRY(thr);
- obj = duk_get_hobject(ctx, idx);
+ obj = duk_get_hobject(thr, idx);
if (obj) {
return (DUK_HOBJECT_GET_CLASS_NUMBER(obj) == DUK_HOBJECT_CLASS_ARRAY ? 1 : 0);
}
return 0;
}
-DUK_EXTERNAL duk_bool_t duk_is_function(duk_context *ctx, duk_idx_t idx) {
+DUK_EXTERNAL duk_bool_t duk_is_function(duk_hthread *thr, duk_idx_t idx) {
duk_tval *tv;
- DUK_ASSERT_CTX_VALID(ctx);
+ DUK_ASSERT_API_ENTRY(thr);
- tv = duk_get_tval_or_unused(ctx, idx);
+ tv = duk_get_tval_or_unused(thr, idx);
+ if (DUK_TVAL_IS_OBJECT(tv)) {
+ duk_hobject *h;
+ h = DUK_TVAL_GET_OBJECT(tv);
+ DUK_ASSERT(h != NULL);
+ return DUK_HOBJECT_HAS_CALLABLE(h) ? 1 : 0;
+ }
if (DUK_TVAL_IS_LIGHTFUNC(tv)) {
return 1;
}
- return duk__obj_flag_any_default_false(ctx,
- idx,
- DUK_HOBJECT_FLAG_COMPFUNC |
- DUK_HOBJECT_FLAG_NATFUNC |
- DUK_HOBJECT_FLAG_BOUNDFUNC);
+ return 0;
+}
+
+DUK_INTERNAL duk_bool_t duk_is_callable_tval(duk_hthread *thr, duk_tval *tv) {
+ DUK_ASSERT_API_ENTRY(thr);
+
+ DUK_UNREF(thr);
+
+ if (DUK_TVAL_IS_OBJECT(tv)) {
+ duk_hobject *h;
+ h = DUK_TVAL_GET_OBJECT(tv);
+ DUK_ASSERT(h != NULL);
+ return DUK_HOBJECT_HAS_CALLABLE(h) ? 1 : 0;
+ }
+ if (DUK_TVAL_IS_LIGHTFUNC(tv)) {
+ return 1;
+ }
+ return 0;
}
-DUK_EXTERNAL duk_bool_t duk_is_c_function(duk_context *ctx, duk_idx_t idx) {
- DUK_ASSERT_CTX_VALID(ctx);
- return duk__obj_flag_any_default_false(ctx,
+DUK_EXTERNAL duk_bool_t duk_is_constructable(duk_hthread *thr, duk_idx_t idx) {
+ duk_tval *tv;
+
+ DUK_ASSERT_API_ENTRY(thr);
+
+ tv = duk_get_tval_or_unused(thr, idx);
+ if (DUK_TVAL_IS_OBJECT(tv)) {
+ duk_hobject *h;
+ h = DUK_TVAL_GET_OBJECT(tv);
+ DUK_ASSERT(h != NULL);
+ return DUK_HOBJECT_HAS_CONSTRUCTABLE(h) ? 1 : 0;
+ }
+ if (DUK_TVAL_IS_LIGHTFUNC(tv)) {
+ return 1;
+ }
+ return 0;
+}
+
+DUK_EXTERNAL duk_bool_t duk_is_c_function(duk_hthread *thr, duk_idx_t idx) {
+ DUK_ASSERT_API_ENTRY(thr);
+ return duk__obj_flag_any_default_false(thr,
idx,
DUK_HOBJECT_FLAG_NATFUNC);
}
-DUK_EXTERNAL duk_bool_t duk_is_ecmascript_function(duk_context *ctx, duk_idx_t idx) {
- DUK_ASSERT_CTX_VALID(ctx);
- return duk__obj_flag_any_default_false(ctx,
+DUK_EXTERNAL duk_bool_t duk_is_ecmascript_function(duk_hthread *thr, duk_idx_t idx) {
+ DUK_ASSERT_API_ENTRY(thr);
+ return duk__obj_flag_any_default_false(thr,
idx,
DUK_HOBJECT_FLAG_COMPFUNC);
}
-DUK_EXTERNAL duk_bool_t duk_is_bound_function(duk_context *ctx, duk_idx_t idx) {
- DUK_ASSERT_CTX_VALID(ctx);
- return duk__obj_flag_any_default_false(ctx,
+DUK_EXTERNAL duk_bool_t duk_is_bound_function(duk_hthread *thr, duk_idx_t idx) {
+ DUK_ASSERT_API_ENTRY(thr);
+ return duk__obj_flag_any_default_false(thr,
idx,
DUK_HOBJECT_FLAG_BOUNDFUNC);
}
-DUK_EXTERNAL duk_bool_t duk_is_thread(duk_context *ctx, duk_idx_t idx) {
+DUK_EXTERNAL duk_bool_t duk_is_thread(duk_hthread *thr, duk_idx_t idx) {
duk_hobject *obj;
- DUK_ASSERT_CTX_VALID(ctx);
+ DUK_ASSERT_API_ENTRY(thr);
- obj = duk_get_hobject(ctx, idx);
+ obj = duk_get_hobject(thr, idx);
if (obj) {
return (DUK_HOBJECT_GET_CLASS_NUMBER(obj) == DUK_HOBJECT_CLASS_THREAD ? 1 : 0);
}
return 0;
}
-DUK_EXTERNAL duk_bool_t duk_is_fixed_buffer(duk_context *ctx, duk_idx_t idx) {
+DUK_EXTERNAL duk_bool_t duk_is_fixed_buffer(duk_hthread *thr, duk_idx_t idx) {
duk_tval *tv;
- DUK_ASSERT_CTX_VALID(ctx);
+ DUK_ASSERT_API_ENTRY(thr);
- tv = duk_get_tval_or_unused(ctx, idx);
+ tv = duk_get_tval_or_unused(thr, idx);
DUK_ASSERT(tv != NULL);
if (DUK_TVAL_IS_BUFFER(tv)) {
duk_hbuffer *h = DUK_TVAL_GET_BUFFER(tv);
@@ -20402,12 +21141,12 @@ DUK_EXTERNAL duk_bool_t duk_is_fixed_buffer(duk_context *ctx, duk_idx_t idx) {
return 0;
}
-DUK_EXTERNAL duk_bool_t duk_is_dynamic_buffer(duk_context *ctx, duk_idx_t idx) {
+DUK_EXTERNAL duk_bool_t duk_is_dynamic_buffer(duk_hthread *thr, duk_idx_t idx) {
duk_tval *tv;
- DUK_ASSERT_CTX_VALID(ctx);
+ DUK_ASSERT_API_ENTRY(thr);
- tv = duk_get_tval_or_unused(ctx, idx);
+ tv = duk_get_tval_or_unused(thr, idx);
DUK_ASSERT(tv != NULL);
if (DUK_TVAL_IS_BUFFER(tv)) {
duk_hbuffer *h = DUK_TVAL_GET_BUFFER(tv);
@@ -20417,12 +21156,12 @@ DUK_EXTERNAL duk_bool_t duk_is_dynamic_buffer(duk_context *ctx, duk_idx_t idx) {
return 0;
}
-DUK_EXTERNAL duk_bool_t duk_is_external_buffer(duk_context *ctx, duk_idx_t idx) {
+DUK_EXTERNAL duk_bool_t duk_is_external_buffer(duk_hthread *thr, duk_idx_t idx) {
duk_tval *tv;
- DUK_ASSERT_CTX_VALID(ctx);
+ DUK_ASSERT_API_ENTRY(thr);
- tv = duk_get_tval_or_unused(ctx, idx);
+ tv = duk_get_tval_or_unused(thr, idx);
DUK_ASSERT(tv != NULL);
if (DUK_TVAL_IS_BUFFER(tv)) {
duk_hbuffer *h = DUK_TVAL_GET_BUFFER(tv);
@@ -20432,20 +21171,22 @@ DUK_EXTERNAL duk_bool_t duk_is_external_buffer(duk_context *ctx, duk_idx_t idx)
return 0;
}
-DUK_EXTERNAL duk_errcode_t duk_get_error_code(duk_context *ctx, duk_idx_t idx) {
- duk_hthread *thr = (duk_hthread *) ctx;
+DUK_EXTERNAL duk_errcode_t duk_get_error_code(duk_hthread *thr, duk_idx_t idx) {
duk_hobject *h;
duk_uint_t sanity;
- DUK_ASSERT_CTX_VALID(ctx);
+ DUK_ASSERT_API_ENTRY(thr);
- h = duk_get_hobject(ctx, idx);
+ h = duk_get_hobject(thr, idx);
sanity = DUK_HOBJECT_PROTOTYPE_CHAIN_SANITY;
do {
if (!h) {
return DUK_ERR_NONE;
}
+
+ /* XXX: something more convenient? */
+
if (h == thr->builtins[DUK_BIDX_EVAL_ERROR_PROTOTYPE]) {
return DUK_ERR_EVAL_ERROR;
}
@@ -20478,24 +21219,21 @@ DUK_EXTERNAL duk_errcode_t duk_get_error_code(duk_context *ctx, duk_idx_t idx) {
* Pushers
*/
-DUK_INTERNAL void duk_push_tval(duk_context *ctx, duk_tval *tv) {
- duk_hthread *thr;
+DUK_INTERNAL void duk_push_tval(duk_hthread *thr, duk_tval *tv) {
duk_tval *tv_slot;
- DUK_ASSERT_CTX_VALID(ctx);
+ DUK_ASSERT_API_ENTRY(thr);
DUK_ASSERT(tv != NULL);
- thr = (duk_hthread *) ctx;
+
DUK__CHECK_SPACE();
tv_slot = thr->valstack_top++;
DUK_TVAL_SET_TVAL(tv_slot, tv);
DUK_TVAL_INCREF(thr, tv); /* no side effects */
}
-DUK_EXTERNAL void duk_push_undefined(duk_context *ctx) {
- duk_hthread *thr;
+DUK_EXTERNAL void duk_push_undefined(duk_hthread *thr) {
+ DUK_ASSERT_API_ENTRY(thr);
- DUK_ASSERT_CTX_VALID(ctx);
- thr = (duk_hthread *) ctx;
DUK__CHECK_SPACE();
/* Because value stack init policy is 'undefined above top',
@@ -20505,60 +21243,50 @@ DUK_EXTERNAL void duk_push_undefined(duk_context *ctx) {
DUK_ASSERT(DUK_TVAL_IS_UNDEFINED(thr->valstack_top - 1));
}
-DUK_EXTERNAL void duk_push_null(duk_context *ctx) {
- duk_hthread *thr;
+DUK_EXTERNAL void duk_push_null(duk_hthread *thr) {
duk_tval *tv_slot;
- DUK_ASSERT_CTX_VALID(ctx);
- thr = (duk_hthread *) ctx;
+ DUK_ASSERT_API_ENTRY(thr);
DUK__CHECK_SPACE();
tv_slot = thr->valstack_top++;
DUK_TVAL_SET_NULL(tv_slot);
}
-DUK_EXTERNAL void duk_push_boolean(duk_context *ctx, duk_bool_t val) {
- duk_hthread *thr;
+DUK_EXTERNAL void duk_push_boolean(duk_hthread *thr, duk_bool_t val) {
duk_tval *tv_slot;
duk_small_int_t b;
- DUK_ASSERT_CTX_VALID(ctx);
- thr = (duk_hthread *) ctx;
+ DUK_ASSERT_API_ENTRY(thr);
DUK__CHECK_SPACE();
b = (val ? 1 : 0); /* ensure value is 1 or 0 (not other non-zero) */
tv_slot = thr->valstack_top++;
DUK_TVAL_SET_BOOLEAN(tv_slot, b);
}
-DUK_EXTERNAL void duk_push_true(duk_context *ctx) {
- duk_hthread *thr;
+DUK_EXTERNAL void duk_push_true(duk_hthread *thr) {
duk_tval *tv_slot;
- DUK_ASSERT_CTX_VALID(ctx);
- thr = (duk_hthread *) ctx;
+ DUK_ASSERT_API_ENTRY(thr);
DUK__CHECK_SPACE();
tv_slot = thr->valstack_top++;
DUK_TVAL_SET_BOOLEAN_TRUE(tv_slot);
}
-DUK_EXTERNAL void duk_push_false(duk_context *ctx) {
- duk_hthread *thr;
+DUK_EXTERNAL void duk_push_false(duk_hthread *thr) {
duk_tval *tv_slot;
- DUK_ASSERT_CTX_VALID(ctx);
- thr = (duk_hthread *) ctx;
+ DUK_ASSERT_API_ENTRY(thr);
DUK__CHECK_SPACE();
tv_slot = thr->valstack_top++;
DUK_TVAL_SET_BOOLEAN_FALSE(tv_slot);
}
/* normalize NaN which may not match our canonical internal NaN */
-DUK_EXTERNAL void duk_push_number(duk_context *ctx, duk_double_t val) {
- duk_hthread *thr;
+DUK_EXTERNAL void duk_push_number(duk_hthread *thr, duk_double_t val) {
duk_tval *tv_slot;
duk_double_union du;
- DUK_ASSERT_CTX_VALID(ctx);
- thr = (duk_hthread *) ctx;
+ DUK_ASSERT_API_ENTRY(thr);
DUK__CHECK_SPACE();
du.d = val;
DUK_DBLUNION_NORMALIZE_NAN_CHECK(&du);
@@ -20566,13 +21294,11 @@ DUK_EXTERNAL void duk_push_number(duk_context *ctx, duk_double_t val) {
DUK_TVAL_SET_NUMBER(tv_slot, du.d);
}
-DUK_EXTERNAL void duk_push_int(duk_context *ctx, duk_int_t val) {
+DUK_EXTERNAL void duk_push_int(duk_hthread *thr, duk_int_t val) {
#if defined(DUK_USE_FASTINT)
- duk_hthread *thr;
duk_tval *tv_slot;
- DUK_ASSERT_CTX_VALID(ctx);
- thr = (duk_hthread *) ctx;
+ DUK_ASSERT_API_ENTRY(thr);
DUK__CHECK_SPACE();
tv_slot = thr->valstack_top++;
#if DUK_INT_MAX <= 0x7fffffffL
@@ -20586,12 +21312,10 @@ DUK_EXTERNAL void duk_push_int(duk_context *ctx, duk_int_t val) {
}
#endif
#else /* DUK_USE_FASTINT */
- duk_hthread *thr;
duk_tval *tv_slot;
duk_double_t d;
- DUK_ASSERT_CTX_VALID(ctx);
- thr = (duk_hthread *) ctx;
+ DUK_ASSERT_API_ENTRY(thr);
DUK__CHECK_SPACE();
d = (duk_double_t) val;
tv_slot = thr->valstack_top++;
@@ -20599,13 +21323,11 @@ DUK_EXTERNAL void duk_push_int(duk_context *ctx, duk_int_t val) {
#endif /* DUK_USE_FASTINT */
}
-DUK_EXTERNAL void duk_push_uint(duk_context *ctx, duk_uint_t val) {
+DUK_EXTERNAL void duk_push_uint(duk_hthread *thr, duk_uint_t val) {
#if defined(DUK_USE_FASTINT)
- duk_hthread *thr;
duk_tval *tv_slot;
- DUK_ASSERT_CTX_VALID(ctx);
- thr = (duk_hthread *) ctx;
+ DUK_ASSERT_API_ENTRY(thr);
DUK__CHECK_SPACE();
tv_slot = thr->valstack_top++;
#if DUK_UINT_MAX <= 0xffffffffUL
@@ -20620,12 +21342,10 @@ DUK_EXTERNAL void duk_push_uint(duk_context *ctx, duk_uint_t val) {
}
#endif
#else /* DUK_USE_FASTINT */
- duk_hthread *thr;
duk_tval *tv_slot;
duk_double_t d;
- DUK_ASSERT_CTX_VALID(ctx);
- thr = (duk_hthread *) ctx;
+ DUK_ASSERT_API_ENTRY(thr);
DUK__CHECK_SPACE();
d = (duk_double_t) val;
tv_slot = thr->valstack_top++;
@@ -20633,13 +21353,11 @@ DUK_EXTERNAL void duk_push_uint(duk_context *ctx, duk_uint_t val) {
#endif /* DUK_USE_FASTINT */
}
-DUK_EXTERNAL void duk_push_nan(duk_context *ctx) {
- duk_hthread *thr;
+DUK_EXTERNAL void duk_push_nan(duk_hthread *thr) {
duk_tval *tv_slot;
duk_double_union du;
- DUK_ASSERT_CTX_VALID(ctx);
- thr = (duk_hthread *) ctx;
+ DUK_ASSERT_API_ENTRY(thr);
DUK__CHECK_SPACE();
DUK_DBLUNION_SET_NAN(&du);
DUK_ASSERT(DUK_DBLUNION_IS_NORMALIZED(&du));
@@ -20647,12 +21365,11 @@ DUK_EXTERNAL void duk_push_nan(duk_context *ctx) {
DUK_TVAL_SET_NUMBER(tv_slot, du.d);
}
-DUK_EXTERNAL const char *duk_push_lstring(duk_context *ctx, const char *str, duk_size_t len) {
- duk_hthread *thr = (duk_hthread *) ctx;
+DUK_EXTERNAL const char *duk_push_lstring(duk_hthread *thr, const char *str, duk_size_t len) {
duk_hstring *h;
duk_tval *tv_slot;
- DUK_ASSERT_CTX_VALID(ctx);
+ DUK_ASSERT_API_ENTRY(thr);
/* check stack before interning (avoid hanging temp) */
DUK__CHECK_SPACE();
@@ -20681,52 +21398,47 @@ DUK_EXTERNAL const char *duk_push_lstring(duk_context *ctx, const char *str, duk
return (const char *) DUK_HSTRING_GET_DATA(h);
}
-DUK_EXTERNAL const char *duk_push_string(duk_context *ctx, const char *str) {
- DUK_ASSERT_CTX_VALID(ctx);
+DUK_EXTERNAL const char *duk_push_string(duk_hthread *thr, const char *str) {
+ DUK_ASSERT_API_ENTRY(thr);
if (str) {
- return duk_push_lstring(ctx, str, DUK_STRLEN(str));
+ return duk_push_lstring(thr, str, DUK_STRLEN(str));
} else {
- duk_push_null(ctx);
+ duk_push_null(thr);
return NULL;
}
}
-DUK_EXTERNAL void duk_push_pointer(duk_context *ctx, void *val) {
- duk_hthread *thr;
+DUK_EXTERNAL void duk_push_pointer(duk_hthread *thr, void *val) {
duk_tval *tv_slot;
- DUK_ASSERT_CTX_VALID(ctx);
- thr = (duk_hthread *) ctx;
+ DUK_ASSERT_API_ENTRY(thr);
DUK__CHECK_SPACE();
tv_slot = thr->valstack_top++;
DUK_TVAL_SET_POINTER(tv_slot, val);
}
-DUK_INTERNAL duk_hstring *duk_push_uint_to_hstring(duk_context *ctx, duk_uint_t i) {
+DUK_INTERNAL duk_hstring *duk_push_uint_to_hstring(duk_hthread *thr, duk_uint_t i) {
duk_hstring *h_tmp;
+ DUK_ASSERT_API_ENTRY(thr);
+
/* XXX: this could be a direct DUK_SPRINTF to a buffer followed by duk_push_string() */
- duk_push_uint(ctx, (duk_uint_t) i);
- h_tmp = duk_to_hstring_m1(ctx);
+ duk_push_uint(thr, (duk_uint_t) i);
+ h_tmp = duk_to_hstring_m1(thr);
DUK_ASSERT(h_tmp != NULL);
return h_tmp;
}
-DUK_LOCAL void duk__push_this_helper(duk_context *ctx, duk_small_uint_t check_object_coercible) {
- duk_hthread *thr;
+DUK_LOCAL void duk__push_this_helper(duk_hthread *thr, duk_small_uint_t check_object_coercible) {
duk_tval *tv_slot;
- 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();
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 (DUK_UNLIKELY(thr->callstack_curr == NULL)) {
if (check_object_coercible) {
goto type_error;
}
@@ -20752,132 +21464,119 @@ DUK_LOCAL void duk__push_this_helper(duk_context *ctx, duk_small_uint_t check_ob
DUK_ERROR_TYPE(thr, DUK_STR_NOT_OBJECT_COERCIBLE);
}
-DUK_EXTERNAL void duk_push_this(duk_context *ctx) {
- DUK_ASSERT_CTX_VALID(ctx);
+DUK_EXTERNAL void duk_push_this(duk_hthread *thr) {
+ DUK_ASSERT_API_ENTRY(thr);
- duk__push_this_helper(ctx, 0 /*check_object_coercible*/);
+ duk__push_this_helper(thr, 0 /*check_object_coercible*/);
}
-DUK_INTERNAL void duk_push_this_check_object_coercible(duk_context *ctx) {
- DUK_ASSERT_CTX_VALID(ctx);
+DUK_INTERNAL void duk_push_this_check_object_coercible(duk_hthread *thr) {
+ DUK_ASSERT_API_ENTRY(thr);
- duk__push_this_helper(ctx, 1 /*check_object_coercible*/);
+ duk__push_this_helper(thr, 1 /*check_object_coercible*/);
}
-DUK_INTERNAL duk_hobject *duk_push_this_coercible_to_object(duk_context *ctx) {
+DUK_INTERNAL duk_hobject *duk_push_this_coercible_to_object(duk_hthread *thr) {
duk_hobject *h;
- DUK_ASSERT_CTX_VALID(ctx);
+ DUK_ASSERT_API_ENTRY(thr);
- duk__push_this_helper(ctx, 1 /*check_object_coercible*/);
- h = duk_to_hobject(ctx, -1);
+ duk__push_this_helper(thr, 1 /*check_object_coercible*/);
+ h = duk_to_hobject(thr, -1);
DUK_ASSERT(h != NULL);
return h;
}
-DUK_INTERNAL duk_hstring *duk_push_this_coercible_to_string(duk_context *ctx) {
- DUK_ASSERT_CTX_VALID(ctx);
+DUK_INTERNAL duk_hstring *duk_push_this_coercible_to_string(duk_hthread *thr) {
+ DUK_ASSERT_API_ENTRY(thr);
- duk__push_this_helper(ctx, 1 /*check_object_coercible*/);
- return duk_to_hstring_m1(ctx); /* This will reject all Symbol values; accepts Symbol objects. */
+ duk__push_this_helper(thr, 1 /*check_object_coercible*/);
+ return duk_to_hstring_m1(thr); /* This will reject all Symbol values; accepts Symbol objects. */
}
-DUK_INTERNAL duk_tval *duk_get_borrowed_this_tval(duk_context *ctx) {
- duk_hthread *thr;
-
- DUK_ASSERT(ctx != NULL);
- thr = (duk_hthread *) ctx;
+DUK_INTERNAL duk_tval *duk_get_borrowed_this_tval(duk_hthread *thr) {
+ DUK_ASSERT_API_ENTRY(thr);
DUK_ASSERT(thr->callstack_top > 0); /* caller required to know */
- DUK_ASSERT(thr->callstack_curr != NULL);
+ DUK_ASSERT(thr->callstack_curr != NULL); /* caller required to know */
DUK_ASSERT(thr->valstack_bottom > thr->valstack); /* consequence of above */
DUK_ASSERT(thr->valstack_bottom - 1 >= thr->valstack); /* 'this' binding exists */
return thr->valstack_bottom - 1;
}
-DUK_EXTERNAL void duk_push_current_function(duk_context *ctx) {
- duk_hthread *thr = (duk_hthread *) ctx;
+DUK_EXTERNAL void duk_push_current_function(duk_hthread *thr) {
duk_activation *act;
- DUK_ASSERT_CTX_VALID(ctx);
- DUK_ASSERT(thr != NULL);
- DUK_ASSERT_DISABLE(thr->callstack_top >= 0);
- DUK_ASSERT(thr->callstack_top <= thr->callstack_size);
+ DUK_ASSERT_API_ENTRY(thr);
act = thr->callstack_curr;
if (act != NULL) {
- duk_push_tval(ctx, &act->tv_func);
+ duk_push_tval(thr, &act->tv_func);
} else {
- duk_push_undefined(ctx);
+ duk_push_undefined(thr);
}
}
-DUK_EXTERNAL void duk_push_current_thread(duk_context *ctx) {
- duk_hthread *thr = (duk_hthread *) ctx;
-
- DUK_ASSERT_CTX_VALID(ctx);
- DUK_ASSERT(thr != NULL);
+DUK_EXTERNAL void duk_push_current_thread(duk_hthread *thr) {
+ DUK_ASSERT_API_ENTRY(thr);
if (thr->heap->curr_thread) {
- duk_push_hobject(ctx, (duk_hobject *) thr->heap->curr_thread);
+ duk_push_hobject(thr, (duk_hobject *) thr->heap->curr_thread);
} else {
- duk_push_undefined(ctx);
+ duk_push_undefined(thr);
}
}
-DUK_EXTERNAL void duk_push_global_object(duk_context *ctx) {
- DUK_ASSERT_CTX_VALID(ctx);
+DUK_EXTERNAL void duk_push_global_object(duk_hthread *thr) {
+ DUK_ASSERT_API_ENTRY(thr);
- duk_push_hobject_bidx(ctx, DUK_BIDX_GLOBAL);
+ duk_push_hobject_bidx(thr, DUK_BIDX_GLOBAL);
}
/* XXX: size optimize */
-DUK_LOCAL void duk__push_stash(duk_context *ctx) {
- DUK_ASSERT_CTX_VALID(ctx);
- if (!duk_get_prop_stridx_short(ctx, -1, DUK_STRIDX_INT_VALUE)) {
+DUK_LOCAL void duk__push_stash(duk_hthread *thr) {
+ if (!duk_get_prop_stridx_short(thr, -1, DUK_STRIDX_INT_VALUE)) {
DUK_DDD(DUK_DDDPRINT("creating heap/global/thread stash on first use"));
- duk_pop(ctx);
- duk_push_bare_object(ctx);
- duk_dup_top(ctx);
- duk_xdef_prop_stridx_short(ctx, -3, DUK_STRIDX_INT_VALUE, DUK_PROPDESC_FLAGS_C); /* [ ... parent stash stash ] -> [ ... parent stash ] */
+ duk_pop_unsafe(thr);
+ duk_push_bare_object(thr);
+ duk_dup_top(thr);
+ duk_xdef_prop_stridx_short(thr, -3, DUK_STRIDX_INT_VALUE, DUK_PROPDESC_FLAGS_C); /* [ ... parent stash stash ] -> [ ... parent stash ] */
}
- duk_remove_m2(ctx);
+ duk_remove_m2(thr);
}
-DUK_EXTERNAL void duk_push_heap_stash(duk_context *ctx) {
- duk_hthread *thr = (duk_hthread *) ctx;
+DUK_EXTERNAL void duk_push_heap_stash(duk_hthread *thr) {
duk_heap *heap;
- DUK_ASSERT_CTX_VALID(ctx);
+ DUK_ASSERT_API_ENTRY(thr);
heap = thr->heap;
DUK_ASSERT(heap->heap_object != NULL);
- duk_push_hobject(ctx, heap->heap_object);
- duk__push_stash(ctx);
+ duk_push_hobject(thr, heap->heap_object);
+ duk__push_stash(thr);
}
-DUK_EXTERNAL void duk_push_global_stash(duk_context *ctx) {
- DUK_ASSERT_CTX_VALID(ctx);
- duk_push_global_object(ctx);
- duk__push_stash(ctx);
+DUK_EXTERNAL void duk_push_global_stash(duk_hthread *thr) {
+ DUK_ASSERT_API_ENTRY(thr);
+ duk_push_global_object(thr);
+ duk__push_stash(thr);
}
-DUK_EXTERNAL void duk_push_thread_stash(duk_context *ctx, duk_context *target_ctx) {
- duk_hthread *thr = (duk_hthread *) ctx;
- DUK_ASSERT_CTX_VALID(ctx);
- if (DUK_UNLIKELY(target_ctx == NULL)) {
+DUK_EXTERNAL void duk_push_thread_stash(duk_hthread *thr, duk_hthread *target_thr) {
+ DUK_ASSERT_API_ENTRY(thr);
+ if (DUK_UNLIKELY(target_thr == NULL)) {
DUK_ERROR_TYPE_INVALID_ARGS(thr);
return; /* not reached */
}
- duk_push_hobject(ctx, (duk_hobject *) target_ctx);
- duk__push_stash(ctx);
+ duk_push_hobject(thr, (duk_hobject *) target_thr);
+ duk__push_stash(thr);
}
/* XXX: duk_ssize_t would be useful here */
-DUK_LOCAL duk_int_t duk__try_push_vsprintf(duk_context *ctx, void *buf, duk_size_t sz, const char *fmt, va_list ap) {
+DUK_LOCAL duk_int_t duk__try_push_vsprintf(duk_hthread *thr, void *buf, duk_size_t sz, const char *fmt, va_list ap) {
duk_int_t len;
- DUK_ASSERT_CTX_VALID(ctx);
- DUK_UNREF(ctx);
+ DUK_ASSERT_CTX_VALID(thr);
+ DUK_UNREF(thr);
/* NUL terminator handling doesn't matter here */
len = DUK_VSNPRINTF((char *) buf, sz, fmt, ap);
@@ -20890,8 +21589,7 @@ DUK_LOCAL duk_int_t duk__try_push_vsprintf(duk_context *ctx, void *buf, duk_size
return -1;
}
-DUK_EXTERNAL const char *duk_push_vsprintf(duk_context *ctx, const char *fmt, va_list ap) {
- duk_hthread *thr = (duk_hthread *) ctx;
+DUK_EXTERNAL const char *duk_push_vsprintf(duk_hthread *thr, const char *fmt, va_list ap) {
duk_uint8_t stack_buf[DUK_PUSH_SPRINTF_INITIAL_SIZE];
duk_size_t sz = DUK_PUSH_SPRINTF_INITIAL_SIZE;
duk_bool_t pushed_buf = 0;
@@ -20899,13 +21597,13 @@ DUK_EXTERNAL const char *duk_push_vsprintf(duk_context *ctx, const char *fmt, va
duk_int_t len; /* XXX: duk_ssize_t */
const char *res;
- DUK_ASSERT_CTX_VALID(ctx);
+ DUK_ASSERT_API_ENTRY(thr);
/* special handling of fmt==NULL */
if (!fmt) {
duk_hstring *h_str;
- duk_push_hstring_empty(ctx);
- h_str = duk_known_hstring(ctx, -1);
+ duk_push_hstring_empty(thr);
+ h_str = duk_known_hstring(thr, -1);
return (const char *) DUK_HSTRING_GET_DATA(h_str);
}
@@ -20926,14 +21624,14 @@ DUK_EXTERNAL const char *duk_push_vsprintf(duk_context *ctx, const char *fmt, va
buf = stack_buf;
} else if (!pushed_buf) {
pushed_buf = 1;
- buf = duk_push_dynamic_buffer(ctx, sz);
+ buf = duk_push_dynamic_buffer(thr, sz);
} else {
- buf = duk_resize_buffer(ctx, -1, sz);
+ buf = duk_resize_buffer(thr, -1, sz);
}
DUK_ASSERT(buf != NULL);
DUK_VA_COPY(ap_copy, ap);
- len = duk__try_push_vsprintf(ctx, buf, sz, fmt, ap_copy);
+ len = duk__try_push_vsprintf(thr, buf, sz, fmt, ap_copy);
va_end(ap_copy);
if (len >= 0) {
break;
@@ -20949,33 +21647,32 @@ DUK_EXTERNAL const char *duk_push_vsprintf(duk_context *ctx, const char *fmt, va
/* Cannot use duk_buffer_to_string() on the buffer because it is
* usually larger than 'len'; 'buf' is also usually a stack buffer.
*/
- res = duk_push_lstring(ctx, (const char *) buf, (duk_size_t) len); /* [ buf? res ] */
+ res = duk_push_lstring(thr, (const char *) buf, (duk_size_t) len); /* [ buf? res ] */
if (pushed_buf) {
- duk_remove_m2(ctx);
+ duk_remove_m2(thr);
}
return res;
}
-DUK_EXTERNAL const char *duk_push_sprintf(duk_context *ctx, const char *fmt, ...) {
+DUK_EXTERNAL const char *duk_push_sprintf(duk_hthread *thr, const char *fmt, ...) {
va_list ap;
const char *ret;
- DUK_ASSERT_CTX_VALID(ctx);
+ DUK_ASSERT_API_ENTRY(thr);
/* allow fmt==NULL */
va_start(ap, fmt);
- ret = duk_push_vsprintf(ctx, fmt, ap);
+ ret = duk_push_vsprintf(thr, fmt, ap);
va_end(ap);
return ret;
}
-DUK_INTERNAL duk_hobject *duk_push_object_helper(duk_context *ctx, duk_uint_t hobject_flags_and_class, duk_small_int_t prototype_bidx) {
- duk_hthread *thr = (duk_hthread *) ctx;
+DUK_INTERNAL duk_hobject *duk_push_object_helper(duk_hthread *thr, duk_uint_t hobject_flags_and_class, duk_small_int_t prototype_bidx) {
duk_tval *tv_slot;
duk_hobject *h;
- DUK_ASSERT_CTX_VALID(ctx);
+ DUK_ASSERT_API_ENTRY(thr);
DUK_ASSERT(prototype_bidx == -1 ||
(prototype_bidx >= 0 && prototype_bidx < DUK_NUM_BUILTINS));
@@ -20994,7 +21691,7 @@ DUK_INTERNAL duk_hobject *duk_push_object_helper(duk_context *ctx, duk_uint_t ho
/* object is now reachable */
if (prototype_bidx >= 0) {
- DUK_HOBJECT_SET_PROTOTYPE_UPDREF(thr, h, thr->builtins[prototype_bidx]);
+ DUK_HOBJECT_SET_PROTOTYPE_INIT_INCREF(thr, h, thr->builtins[prototype_bidx]);
} else {
DUK_ASSERT(prototype_bidx == -1);
DUK_ASSERT(DUK_HOBJECT_GET_PROTOTYPE(thr->heap, h) == NULL);
@@ -21003,38 +21700,35 @@ DUK_INTERNAL duk_hobject *duk_push_object_helper(duk_context *ctx, duk_uint_t ho
return h;
}
-DUK_INTERNAL duk_hobject *duk_push_object_helper_proto(duk_context *ctx, duk_uint_t hobject_flags_and_class, duk_hobject *proto) {
- duk_hthread *thr = (duk_hthread *) ctx;
+DUK_INTERNAL duk_hobject *duk_push_object_helper_proto(duk_hthread *thr, duk_uint_t hobject_flags_and_class, duk_hobject *proto) {
duk_hobject *h;
- DUK_ASSERT_CTX_VALID(ctx);
+ DUK_ASSERT_API_ENTRY(thr);
- h = duk_push_object_helper(ctx, hobject_flags_and_class, -1);
+ h = duk_push_object_helper(thr, hobject_flags_and_class, -1);
DUK_ASSERT(h != NULL);
- DUK_ASSERT(DUK_HOBJECT_GET_PROTOTYPE(thr->heap, h) == NULL);
- DUK_HOBJECT_SET_PROTOTYPE_UPDREF(thr, h, proto);
+ DUK_HOBJECT_SET_PROTOTYPE_INIT_INCREF(thr, h, proto);
return h;
}
-DUK_EXTERNAL duk_idx_t duk_push_object(duk_context *ctx) {
- DUK_ASSERT_CTX_VALID(ctx);
+DUK_EXTERNAL duk_idx_t duk_push_object(duk_hthread *thr) {
+ DUK_ASSERT_API_ENTRY(thr);
- (void) duk_push_object_helper(ctx,
+ (void) duk_push_object_helper(thr,
DUK_HOBJECT_FLAG_EXTENSIBLE |
DUK_HOBJECT_FLAG_FASTREFS |
DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_OBJECT),
DUK_BIDX_OBJECT_PROTOTYPE);
- return duk_get_top_index_unsafe(ctx);
+ return duk_get_top_index_unsafe(thr);
}
-DUK_EXTERNAL duk_idx_t duk_push_array(duk_context *ctx) {
- duk_hthread *thr = (duk_hthread *) ctx;
+DUK_EXTERNAL duk_idx_t duk_push_array(duk_hthread *thr) {
duk_uint_t flags;
duk_harray *obj;
duk_idx_t ret;
duk_tval *tv_slot;
- DUK_ASSERT_CTX_VALID(ctx);
+ DUK_ASSERT_API_ENTRY(thr);
flags = DUK_HOBJECT_FLAG_EXTENSIBLE |
DUK_HOBJECT_FLAG_FASTREFS |
@@ -21045,8 +21739,7 @@ DUK_EXTERNAL duk_idx_t duk_push_array(duk_context *ctx) {
obj = duk_harray_alloc(thr, flags);
DUK_ASSERT(obj != NULL);
- /* XXX: since prototype is NULL, could save a check */
- DUK_HOBJECT_SET_PROTOTYPE_UPDREF(thr, (duk_hobject *) obj, thr->builtins[DUK_BIDX_ARRAY_PROTOTYPE]);
+ DUK_HOBJECT_SET_PROTOTYPE_INIT_INCREF(thr, (duk_hobject *) obj, thr->builtins[DUK_BIDX_ARRAY_PROTOTYPE]);
tv_slot = thr->valstack_top;
DUK_TVAL_SET_OBJECT(tv_slot, (duk_hobject *) obj);
@@ -21058,13 +21751,13 @@ DUK_EXTERNAL duk_idx_t duk_push_array(duk_context *ctx) {
return ret;
}
-DUK_INTERNAL duk_harray *duk_push_harray(duk_context *ctx) {
+DUK_INTERNAL duk_harray *duk_push_harray(duk_hthread *thr) {
/* XXX: API call could do this directly, cast to void in API macro. */
- duk_hthread *thr;
duk_harray *a;
- thr = (duk_hthread *) ctx;
- (void) duk_push_array(ctx);
+ DUK_ASSERT_API_ENTRY(thr);
+
+ (void) duk_push_array(thr);
DUK_ASSERT(DUK_TVAL_IS_OBJECT(thr->valstack_top - 1));
a = (duk_harray *) DUK_TVAL_GET_OBJECT(thr->valstack_top - 1);
DUK_ASSERT(a != NULL);
@@ -21074,12 +21767,14 @@ DUK_INTERNAL duk_harray *duk_push_harray(duk_context *ctx) {
/* Push a duk_harray with preallocated size (.length also set to match size).
* Caller may then populate array part of the duk_harray directly.
*/
-DUK_INTERNAL duk_harray *duk_push_harray_with_size(duk_context *ctx, duk_uint32_t size) {
+DUK_INTERNAL duk_harray *duk_push_harray_with_size(duk_hthread *thr, duk_uint32_t size) {
duk_harray *a;
- a = duk_push_harray(ctx);
+ DUK_ASSERT_API_ENTRY(thr);
+
+ a = duk_push_harray(thr);
- duk_hobject_realloc_props((duk_hthread *) ctx,
+ duk_hobject_realloc_props(thr,
(duk_hobject *) a,
0,
size,
@@ -21089,13 +21784,22 @@ DUK_INTERNAL duk_harray *duk_push_harray_with_size(duk_context *ctx, duk_uint32_
return a;
}
-DUK_EXTERNAL duk_idx_t duk_push_thread_raw(duk_context *ctx, duk_uint_t flags) {
- duk_hthread *thr = (duk_hthread *) ctx;
+DUK_INTERNAL duk_tval *duk_push_harray_with_size_outptr(duk_hthread *thr, duk_uint32_t size) {
+ duk_harray *a;
+
+ DUK_ASSERT_API_ENTRY(thr);
+
+ a = duk_push_harray_with_size(thr, size);
+ DUK_ASSERT(a != NULL);
+ return DUK_HOBJECT_A_GET_BASE(thr->heap, (duk_hobject *) a);
+}
+
+DUK_EXTERNAL duk_idx_t duk_push_thread_raw(duk_hthread *thr, duk_uint_t flags) {
duk_hthread *obj;
duk_idx_t ret;
duk_tval *tv_slot;
- DUK_ASSERT_CTX_VALID(ctx);
+ DUK_ASSERT_API_ENTRY(thr);
DUK__CHECK_SPACE();
@@ -21134,11 +21838,10 @@ DUK_EXTERNAL duk_idx_t duk_push_thread_raw(duk_context *ctx, duk_uint_t flags) {
duk_hthread_copy_builtin_objects(thr, obj);
}
- /* default prototype (Note: 'obj' must be reachable) */
- /* XXX: since prototype is NULL, could save a check */
- DUK_HOBJECT_SET_PROTOTYPE_UPDREF(thr, (duk_hobject *) obj, obj->builtins[DUK_BIDX_THREAD_PROTOTYPE]);
+ /* default prototype */
+ DUK_HOBJECT_SET_PROTOTYPE_INIT_INCREF(thr, (duk_hobject *) obj, obj->builtins[DUK_BIDX_THREAD_PROTOTYPE]);
- /* Initial stack size satisfies the stack spare constraints so there
+ /* Initial stack size satisfies the stack slack constraints so there
* is no need to require stack here.
*/
DUK_ASSERT(DUK_VALSTACK_INITIAL_SIZE >=
@@ -21147,12 +21850,11 @@ DUK_EXTERNAL duk_idx_t duk_push_thread_raw(duk_context *ctx, duk_uint_t flags) {
return ret;
}
-DUK_INTERNAL duk_hcompfunc *duk_push_hcompfunc(duk_context *ctx) {
- duk_hthread *thr = (duk_hthread *) ctx;
+DUK_INTERNAL duk_hcompfunc *duk_push_hcompfunc(duk_hthread *thr) {
duk_hcompfunc *obj;
duk_tval *tv_slot;
- DUK_ASSERT_CTX_VALID(ctx);
+ DUK_ASSERT_API_ENTRY(thr);
DUK__CHECK_SPACE();
@@ -21163,6 +21865,7 @@ DUK_INTERNAL duk_hcompfunc *duk_push_hcompfunc(duk_context *ctx) {
obj = duk_hcompfunc_alloc(thr,
DUK_HOBJECT_FLAG_EXTENSIBLE |
+ DUK_HOBJECT_FLAG_CALLABLE |
DUK_HOBJECT_FLAG_COMPFUNC |
DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_FUNCTION));
if (DUK_UNLIKELY(obj == NULL)) {
@@ -21176,19 +21879,49 @@ DUK_INTERNAL duk_hcompfunc *duk_push_hcompfunc(duk_context *ctx) {
DUK_HOBJECT_INCREF(thr, obj);
thr->valstack_top++;
- DUK_HOBJECT_SET_PROTOTYPE_UPDREF(thr, (duk_hobject *) obj, thr->builtins[DUK_BIDX_FUNCTION_PROTOTYPE]);
+ /* default prototype */
+ DUK_ASSERT(DUK_HOBJECT_GET_PROTOTYPE(thr->heap, (duk_hobject *) obj) == NULL);
+ DUK_HOBJECT_SET_PROTOTYPE_INIT_INCREF(thr, (duk_hobject *) obj, thr->builtins[DUK_BIDX_FUNCTION_PROTOTYPE]);
return obj;
}
-DUK_LOCAL duk_idx_t duk__push_c_function_raw(duk_context *ctx, duk_c_function func, duk_idx_t nargs, duk_uint_t flags) {
- duk_hthread *thr = (duk_hthread *) ctx;
+DUK_INTERNAL duk_hboundfunc *duk_push_hboundfunc(duk_hthread *thr) {
+ duk_hboundfunc *obj;
+ duk_tval *tv_slot;
+
+ DUK_ASSERT_API_ENTRY(thr);
+
+ DUK__CHECK_SPACE();
+ obj = duk_hboundfunc_alloc(thr->heap,
+ DUK_HOBJECT_FLAG_EXTENSIBLE |
+ DUK_HOBJECT_FLAG_BOUNDFUNC |
+ DUK_HOBJECT_FLAG_CONSTRUCTABLE |
+ DUK_HOBJECT_FLAG_CALLABLE |
+ DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_FUNCTION));
+ if (!obj) {
+ DUK_ERROR_ALLOC_FAILED(thr);
+ }
+
+ tv_slot = thr->valstack_top++;
+ DUK_TVAL_SET_OBJECT(tv_slot, (duk_hobject *) obj);
+ DUK_HOBJECT_INCREF(thr, obj);
+
+ /* Prototype is left as NULL because the caller always sets it (and
+ * it depends on the target function).
+ */
+ DUK_ASSERT(DUK_HOBJECT_GET_PROTOTYPE(thr->heap, (duk_hobject *) obj) == NULL);
+
+ return obj;
+}
+
+DUK_LOCAL duk_idx_t duk__push_c_function_raw(duk_hthread *thr, duk_c_function func, duk_idx_t nargs, duk_uint_t flags, duk_small_uint_t proto_bidx) {
duk_hnatfunc *obj;
duk_idx_t ret;
duk_tval *tv_slot;
duk_int16_t func_nargs;
- DUK_ASSERT_CTX_VALID(ctx);
+ DUK_ASSERT_CTX_VALID(thr);
DUK__CHECK_SPACE();
@@ -21218,9 +21951,8 @@ DUK_LOCAL duk_idx_t duk__push_c_function_raw(duk_context *ctx, duk_c_function fu
ret = (duk_idx_t) (thr->valstack_top - thr->valstack_bottom);
thr->valstack_top++;
- /* default prototype (Note: 'obj' must be reachable) */
- DUK_HOBJECT_SET_PROTOTYPE_UPDREF(thr, (duk_hobject *) obj, thr->builtins[DUK_BIDX_FUNCTION_PROTOTYPE]);
-
+ DUK_ASSERT_BIDX_VALID(proto_bidx);
+ DUK_HOBJECT_SET_PROTOTYPE_INIT_INCREF(thr, (duk_hobject *) obj, thr->builtins[proto_bidx]);
return ret;
api_error:
@@ -21228,31 +21960,35 @@ DUK_LOCAL duk_idx_t duk__push_c_function_raw(duk_context *ctx, duk_c_function fu
return 0; /* not reached */
}
-DUK_EXTERNAL duk_idx_t duk_push_c_function(duk_context *ctx, duk_c_function func, duk_int_t nargs) {
+DUK_EXTERNAL duk_idx_t duk_push_c_function(duk_hthread *thr, duk_c_function func, duk_int_t nargs) {
duk_uint_t flags;
- DUK_ASSERT_CTX_VALID(ctx);
+ DUK_ASSERT_API_ENTRY(thr);
flags = DUK_HOBJECT_FLAG_EXTENSIBLE |
DUK_HOBJECT_FLAG_CONSTRUCTABLE |
+ DUK_HOBJECT_FLAG_CALLABLE |
DUK_HOBJECT_FLAG_FASTREFS |
DUK_HOBJECT_FLAG_NATFUNC |
DUK_HOBJECT_FLAG_NEWENV |
DUK_HOBJECT_FLAG_STRICT |
DUK_HOBJECT_FLAG_NOTAIL |
- DUK_HOBJECT_FLAG_EXOTIC_DUKFUNC |
DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_FUNCTION);
- return duk__push_c_function_raw(ctx, func, nargs, flags);
+ /* Default prototype is a Duktape specific %NativeFunctionPrototype%
+ * which provides .length and .name getters.
+ */
+ return duk__push_c_function_raw(thr, func, nargs, flags, DUK_BIDX_NATIVE_FUNCTION_PROTOTYPE);
}
-DUK_INTERNAL void duk_push_c_function_noexotic(duk_context *ctx, duk_c_function func, duk_int_t nargs) {
+DUK_INTERNAL void duk_push_c_function_builtin(duk_hthread *thr, duk_c_function func, duk_int_t nargs) {
duk_uint_t flags;
- DUK_ASSERT_CTX_VALID(ctx);
+ DUK_ASSERT_API_ENTRY(thr);
flags = DUK_HOBJECT_FLAG_EXTENSIBLE |
DUK_HOBJECT_FLAG_CONSTRUCTABLE |
+ DUK_HOBJECT_FLAG_CALLABLE |
DUK_HOBJECT_FLAG_FASTREFS |
DUK_HOBJECT_FLAG_NATFUNC |
DUK_HOBJECT_FLAG_NEWENV |
@@ -21260,15 +21996,17 @@ DUK_INTERNAL void duk_push_c_function_noexotic(duk_context *ctx, duk_c_function
DUK_HOBJECT_FLAG_NOTAIL |
DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_FUNCTION);
- (void) duk__push_c_function_raw(ctx, func, nargs, flags);
+ /* Must use Function.prototype for standard built-in functions. */
+ (void) duk__push_c_function_raw(thr, func, nargs, flags, DUK_BIDX_FUNCTION_PROTOTYPE);
}
-DUK_INTERNAL void duk_push_c_function_noconstruct_noexotic(duk_context *ctx, duk_c_function func, duk_int_t nargs) {
+DUK_INTERNAL void duk_push_c_function_builtin_noconstruct(duk_hthread *thr, duk_c_function func, duk_int_t nargs) {
duk_uint_t flags;
- DUK_ASSERT_CTX_VALID(ctx);
+ DUK_ASSERT_API_ENTRY(thr);
flags = DUK_HOBJECT_FLAG_EXTENSIBLE |
+ DUK_HOBJECT_FLAG_CALLABLE |
DUK_HOBJECT_FLAG_FASTREFS |
DUK_HOBJECT_FLAG_NATFUNC |
DUK_HOBJECT_FLAG_NEWENV |
@@ -21276,15 +22014,15 @@ DUK_INTERNAL void duk_push_c_function_noconstruct_noexotic(duk_context *ctx, duk
DUK_HOBJECT_FLAG_NOTAIL |
DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_FUNCTION);
- (void) duk__push_c_function_raw(ctx, func, nargs, flags);
+ /* Must use Function.prototype for standard built-in functions. */
+ (void) duk__push_c_function_raw(thr, func, nargs, flags, DUK_BIDX_FUNCTION_PROTOTYPE);
}
-DUK_EXTERNAL duk_idx_t duk_push_c_lightfunc(duk_context *ctx, duk_c_function func, duk_idx_t nargs, duk_idx_t length, duk_int_t magic) {
- duk_hthread *thr = (duk_hthread *) ctx;
- duk_tval tv_tmp;
+DUK_EXTERNAL duk_idx_t duk_push_c_lightfunc(duk_hthread *thr, duk_c_function func, duk_idx_t nargs, duk_idx_t length, duk_int_t magic) {
duk_small_uint_t lf_flags;
+ duk_tval *tv_slot;
- DUK_ASSERT_CTX_VALID(ctx);
+ DUK_ASSERT_API_ENTRY(thr);
DUK__CHECK_SPACE();
@@ -21302,11 +22040,12 @@ DUK_EXTERNAL duk_idx_t duk_push_c_lightfunc(duk_context *ctx, duk_c_function fun
goto api_error;
}
- lf_flags = DUK_LFUNC_FLAGS_PACK(magic, length, nargs);
- DUK_TVAL_SET_LIGHTFUNC(&tv_tmp, func, lf_flags);
- duk_push_tval(ctx, &tv_tmp); /* XXX: direct valstack write */
- DUK_ASSERT(thr->valstack_top != thr->valstack_bottom);
- return ((duk_idx_t) (thr->valstack_top - thr->valstack_bottom)) - 1;
+ lf_flags = DUK_LFUNC_FLAGS_PACK((duk_small_int_t) magic, (duk_small_uint_t) length, (duk_small_uint_t) nargs);
+ tv_slot = thr->valstack_top++;
+ DUK_ASSERT(DUK_TVAL_IS_UNDEFINED(tv_slot));
+ DUK_TVAL_SET_LIGHTFUNC(tv_slot, func, lf_flags);
+ DUK_ASSERT(tv_slot >= thr->valstack_bottom);
+ return (duk_idx_t) (tv_slot - thr->valstack_bottom);
api_error:
DUK_ERROR_TYPE_INVALID_ARGS(thr);
@@ -21314,12 +22053,11 @@ DUK_EXTERNAL duk_idx_t duk_push_c_lightfunc(duk_context *ctx, duk_c_function fun
}
#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)
-DUK_INTERNAL duk_hbufobj *duk_push_bufobj_raw(duk_context *ctx, duk_uint_t hobject_flags_and_class, duk_small_int_t prototype_bidx) {
- duk_hthread *thr = (duk_hthread *) ctx;
+DUK_INTERNAL duk_hbufobj *duk_push_bufobj_raw(duk_hthread *thr, duk_uint_t hobject_flags_and_class, duk_small_int_t prototype_bidx) {
duk_hbufobj *obj;
duk_tval *tv_slot;
- DUK_ASSERT(ctx != NULL);
+ DUK_ASSERT_API_ENTRY(thr);
DUK_ASSERT(prototype_bidx >= 0);
DUK__CHECK_SPACE();
@@ -21327,7 +22065,7 @@ DUK_INTERNAL duk_hbufobj *duk_push_bufobj_raw(duk_context *ctx, duk_uint_t hobje
obj = duk_hbufobj_alloc(thr, hobject_flags_and_class);
DUK_ASSERT(obj != NULL);
- DUK_HOBJECT_SET_PROTOTYPE_UPDREF(thr, (duk_hobject *) obj, thr->builtins[prototype_bidx]);
+ DUK_HOBJECT_SET_PROTOTYPE_INIT_INCREF(thr, (duk_hobject *) obj, thr->builtins[prototype_bidx]);
DUK_ASSERT_HBUFOBJ_VALID(obj);
tv_slot = thr->valstack_top;
@@ -21364,23 +22102,20 @@ static const duk_uint32_t duk__bufobj_flags_lookup[] = {
#endif /* DUK_USE_BUFFEROBJECT_SUPPORT */
#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)
-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_EXTERNAL void duk_push_buffer_object(duk_hthread *thr, duk_idx_t idx_buffer, duk_size_t byte_offset, duk_size_t byte_length, duk_uint_t flags) {
duk_hbufobj *h_bufobj;
duk_hbuffer *h_val;
+ duk_hobject *h_arraybuf;
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);
+ DUK_ASSERT_API_ENTRY(thr);
/* The underlying types for offset/length in duk_hbufobj is
- * duk_uint_t; make sure argument values fit and that
- * offset + length does not wrap.
+ * duk_uint_t; make sure argument values fit.
*/
uint_offset = (duk_uint_t) byte_offset;
uint_length = (duk_uint_t) byte_length;
@@ -21389,11 +22124,6 @@ DUK_EXTERNAL void duk_push_buffer_object(duk_context *ctx, duk_idx_t idx_buffer,
goto range_error;
}
}
- uint_added = uint_offset + uint_length;
- if (DUK_UNLIKELY(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;
@@ -21404,18 +22134,56 @@ DUK_EXTERNAL void duk_push_buffer_object(duk_context *ctx, duk_idx_t idx_buffer,
classnum = tmp >> 24;
protobidx = (tmp >> 16) & 0xff;
- h_val = duk_require_hbuffer(ctx, idx_buffer);
+ h_arraybuf = duk_get_hobject(thr, idx_buffer);
+ if (h_arraybuf != NULL && /* argument is an object */
+ flags != DUK_BUFOBJ_ARRAYBUFFER && /* creating a view */
+ DUK_HOBJECT_GET_CLASS_NUMBER(h_arraybuf) == DUK_HOBJECT_CLASS_ARRAYBUFFER /* argument is ArrayBuffer */) {
+ duk_uint_t tmp_offset;
+
+ DUK_ASSERT_HBUFOBJ_VALID((duk_hbufobj *) h_arraybuf);
+ h_val = ((duk_hbufobj *) h_arraybuf)->buf;
+ if (DUK_UNLIKELY(h_val == NULL)) {
+ goto arg_error;
+ }
+
+ tmp_offset = uint_offset + ((duk_hbufobj *) h_arraybuf)->offset;
+ if (DUK_UNLIKELY(tmp_offset < uint_offset)) {
+ goto range_error;
+ }
+ uint_offset = tmp_offset;
+
+ /* Note intentional difference to new TypedArray(): we allow
+ * caller to create an uncovered typed array (which is memory
+ * safe); new TypedArray() rejects it.
+ */
+ } else {
+ /* Handle unexpected object arguments here too, for nice error
+ * messages.
+ */
+ h_arraybuf = NULL;
+ h_val = duk_require_hbuffer(thr, idx_buffer);
+ }
+
+ /* Wrap check for offset+length. */
+ uint_added = uint_offset + uint_length;
+ if (DUK_UNLIKELY(uint_added < uint_offset)) {
+ goto range_error;
+ }
+ DUK_ASSERT(uint_added >= uint_offset && uint_added >= uint_length);
+
DUK_ASSERT(h_val != NULL);
- h_bufobj = duk_push_bufobj_raw(ctx,
+ h_bufobj = duk_push_bufobj_raw(thr,
DUK_HOBJECT_FLAG_EXTENSIBLE |
DUK_HOBJECT_FLAG_BUFOBJ |
DUK_HOBJECT_CLASS_AS_FLAGS(classnum),
- protobidx);
+ (duk_small_int_t) protobidx);
DUK_ASSERT(h_bufobj != NULL);
h_bufobj->buf = h_val;
DUK_HBUFFER_INCREF(thr, h_val);
+ h_bufobj->buf_prop = h_arraybuf;
+ DUK_HOBJECT_INCREF_ALLOWNULL(thr, h_arraybuf);
h_bufobj->offset = uint_offset;
h_bufobj->length = uint_length;
h_bufobj->shift = (tmp >> 4) & 0x0f;
@@ -21427,7 +22195,7 @@ DUK_EXTERNAL void duk_push_buffer_object(duk_context *ctx, duk_idx_t idx_buffer,
* provided as .buffer property of the view. The ArrayBuffer is
* referenced via duk_hbufobj->buf_prop and an inherited .buffer
* accessor returns it. The ArrayBuffer is created lazily on first
- * access so we don't need to do anything more here.
+ * access if necessary so we don't need to do anything more here.
*/
return;
@@ -21440,36 +22208,39 @@ DUK_EXTERNAL void duk_push_buffer_object(duk_context *ctx, duk_idx_t idx_buffer,
return; /* not reached */
}
#else /* DUK_USE_BUFFEROBJECT_SUPPORT */
-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_EXTERNAL void duk_push_buffer_object(duk_hthread *thr, duk_idx_t idx_buffer, duk_size_t byte_offset, duk_size_t byte_length, duk_uint_t flags) {
+ DUK_ASSERT_API_ENTRY(thr);
DUK_UNREF(idx_buffer);
DUK_UNREF(byte_offset);
DUK_UNREF(byte_length);
DUK_UNREF(flags);
- DUK_ERROR_UNSUPPORTED((duk_hthread *) ctx);
+ DUK_ERROR_UNSUPPORTED(thr);
}
#endif /* DUK_USE_BUFFEROBJECT_SUPPORT */
-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_EXTERNAL duk_idx_t duk_push_error_object_va_raw(duk_hthread *thr, duk_errcode_t err_code, const char *filename, duk_int_t line, const char *fmt, va_list ap) {
duk_hobject *proto;
#if defined(DUK_USE_AUGMENT_ERROR_CREATE)
- duk_bool_t noblame_fileline;
+ duk_small_uint_t augment_flags;
#endif
- DUK_ASSERT_CTX_VALID(ctx);
+ DUK_ASSERT_API_ENTRY(thr);
DUK_ASSERT(thr != NULL);
DUK_UNREF(filename);
DUK_UNREF(line);
/* Error code also packs a tracedata related flag. */
#if defined(DUK_USE_AUGMENT_ERROR_CREATE)
- noblame_fileline = err_code & DUK_ERRCODE_FLAG_NOBLAME_FILELINE;
+ augment_flags = 0;
+ if (err_code & DUK_ERRCODE_FLAG_NOBLAME_FILELINE) {
+ augment_flags = DUK_AUGMENT_FLAG_NOBLAME_FILELINE;
+ }
#endif
err_code = err_code & (~DUK_ERRCODE_FLAG_NOBLAME_FILELINE);
/* error gets its 'name' from the prototype */
proto = duk_error_prototype_from_code(thr, err_code);
- (void) duk_push_object_helper_proto(ctx,
+ (void) duk_push_object_helper_proto(thr,
DUK_HOBJECT_FLAG_EXTENSIBLE |
DUK_HOBJECT_FLAG_FASTREFS |
DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_ERROR),
@@ -21477,8 +22248,8 @@ DUK_EXTERNAL duk_idx_t duk_push_error_object_va_raw(duk_context *ctx, duk_errcod
/* ... and its 'message' from an instance property */
if (fmt) {
- duk_push_vsprintf(ctx, fmt, ap);
- duk_xdef_prop_stridx_short(ctx, -2, DUK_STRIDX_MESSAGE, DUK_PROPDESC_FLAGS_WC);
+ duk_push_vsprintf(thr, fmt, ap);
+ duk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_MESSAGE, DUK_PROPDESC_FLAGS_WC);
} else {
/* If no explicit message given, put error code into message field
* (as a number). This is not fully in keeping with the Ecmascript
@@ -21486,8 +22257,8 @@ DUK_EXTERNAL duk_idx_t duk_push_error_object_va_raw(duk_context *ctx, duk_errcod
* constructors use ToString() on their argument). However, it's
* probably more useful than having a separate 'code' property.
*/
- duk_push_int(ctx, err_code);
- duk_xdef_prop_stridx_short(ctx, -2, DUK_STRIDX_MESSAGE, DUK_PROPDESC_FLAGS_WC);
+ duk_push_int(thr, err_code);
+ duk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_MESSAGE, DUK_PROPDESC_FLAGS_WC);
}
/* XXX: .code = err_code disabled, not sure if useful */
@@ -21495,49 +22266,48 @@ DUK_EXTERNAL duk_idx_t duk_push_error_object_va_raw(duk_context *ctx, duk_errcod
/* Creation time error augmentation */
#if defined(DUK_USE_AUGMENT_ERROR_CREATE)
/* filename may be NULL in which case file/line is not recorded */
- duk_err_augment_error_create(thr, thr, filename, line, noblame_fileline); /* may throw an error */
+ duk_err_augment_error_create(thr, thr, filename, line, augment_flags); /* may throw an error */
#endif
- return duk_get_top_index_unsafe(ctx);
+ return duk_get_top_index_unsafe(thr);
}
-DUK_EXTERNAL duk_idx_t duk_push_error_object_raw(duk_context *ctx, duk_errcode_t err_code, const char *filename, duk_int_t line, const char *fmt, ...) {
+DUK_EXTERNAL duk_idx_t duk_push_error_object_raw(duk_hthread *thr, duk_errcode_t err_code, const char *filename, duk_int_t line, const char *fmt, ...) {
va_list ap;
duk_idx_t ret;
- DUK_ASSERT_CTX_VALID(ctx);
+ DUK_ASSERT_API_ENTRY(thr);
va_start(ap, fmt);
- ret = duk_push_error_object_va_raw(ctx, err_code, filename, line, fmt, ap);
+ ret = duk_push_error_object_va_raw(thr, err_code, filename, line, fmt, ap);
va_end(ap);
return ret;
}
#if !defined(DUK_USE_VARIADIC_MACROS)
-DUK_EXTERNAL duk_idx_t duk_push_error_object_stash(duk_context *ctx, duk_errcode_t err_code, const char *fmt, ...) {
+DUK_EXTERNAL duk_idx_t duk_push_error_object_stash(duk_hthread *thr, duk_errcode_t err_code, const char *fmt, ...) {
const char *filename = duk_api_global_filename;
duk_int_t line = duk_api_global_line;
va_list ap;
duk_idx_t ret;
- DUK_ASSERT_CTX_VALID(ctx);
+ DUK_ASSERT_API_ENTRY(thr);
duk_api_global_filename = NULL;
duk_api_global_line = 0;
va_start(ap, fmt);
- ret = duk_push_error_object_va_raw(ctx, err_code, filename, line, fmt, ap);
+ ret = duk_push_error_object_va_raw(thr, err_code, filename, line, fmt, ap);
va_end(ap);
return ret;
}
#endif /* DUK_USE_VARIADIC_MACROS */
-DUK_EXTERNAL void *duk_push_buffer_raw(duk_context *ctx, duk_size_t size, duk_small_uint_t flags) {
- duk_hthread *thr = (duk_hthread *) ctx;
+DUK_EXTERNAL void *duk_push_buffer_raw(duk_hthread *thr, duk_size_t size, duk_small_uint_t flags) {
duk_tval *tv_slot;
duk_hbuffer *h;
void *buf_data;
- DUK_ASSERT_CTX_VALID(ctx);
+ DUK_ASSERT_API_ENTRY(thr);
DUK__CHECK_SPACE();
@@ -21559,13 +22329,17 @@ DUK_EXTERNAL void *duk_push_buffer_raw(duk_context *ctx, duk_size_t size, duk_sm
return (void *) buf_data;
}
-DUK_INTERNAL void *duk_push_fixed_buffer_nozero(duk_context *ctx, duk_size_t len) {
- return duk_push_buffer_raw(ctx, len, DUK_BUF_FLAG_NOZERO);
+DUK_INTERNAL void *duk_push_fixed_buffer_nozero(duk_hthread *thr, duk_size_t len) {
+ DUK_ASSERT_API_ENTRY(thr);
+ return duk_push_buffer_raw(thr, len, DUK_BUF_FLAG_NOZERO);
}
-DUK_INTERNAL void *duk_push_fixed_buffer_zero(duk_context *ctx, duk_size_t len) {
+DUK_INTERNAL void *duk_push_fixed_buffer_zero(duk_hthread *thr, duk_size_t len) {
void *ptr;
- ptr = duk_push_buffer_raw(ctx, len, 0);
+
+ DUK_ASSERT_API_ENTRY(thr);
+
+ ptr = duk_push_buffer_raw(thr, len, 0);
#if !defined(DUK_USE_ZERO_BUFFER_DATA)
/* ES2015 requires zeroing even when DUK_USE_ZERO_BUFFER_DATA
* is not set.
@@ -21575,14 +22349,113 @@ DUK_INTERNAL void *duk_push_fixed_buffer_zero(duk_context *ctx, duk_size_t len)
return ptr;
}
+#if defined(DUK_USE_ES6_PROXY)
+DUK_EXTERNAL duk_idx_t duk_push_proxy(duk_hthread *thr, duk_uint_t proxy_flags) {
+ duk_hobject *h_target;
+ duk_hobject *h_handler;
+ duk_hproxy *h_proxy;
+ duk_tval *tv_slot;
+ duk_uint_t flags;
+
+ DUK_ASSERT_API_ENTRY(thr);
+ DUK_UNREF(proxy_flags);
+
+ /* DUK__CHECK_SPACE() unnecessary because the Proxy is written to
+ * value stack in-place.
+ */
+#if 0
+ DUK__CHECK_SPACE();
+#endif
+
+ /* Reject a proxy object as the target because it would need
+ * special handling in property lookups. (ES2015 has no such
+ * restriction.)
+ */
+ h_target = duk_require_hobject_promote_mask(thr, -2, DUK_TYPE_MASK_LIGHTFUNC | DUK_TYPE_MASK_BUFFER);
+ DUK_ASSERT(h_target != NULL);
+ if (DUK_HOBJECT_IS_PROXY(h_target)) {
+ goto fail_args;
+ }
+
+ /* Reject a proxy object as the handler because it would cause
+ * potentially unbounded recursion. (ES2015 has no such
+ * restriction.)
+ *
+ * There's little practical reason to use a lightfunc or a plain
+ * buffer as the handler table: one could only provide traps via
+ * their prototype objects (Function.prototype and ArrayBuffer.prototype).
+ * Even so, as lightfuncs and plain buffers mimic their object
+ * counterparts, they're promoted and accepted here.
+ */
+ h_handler = duk_require_hobject_promote_mask(thr, -1, DUK_TYPE_MASK_LIGHTFUNC | DUK_TYPE_MASK_BUFFER);
+ DUK_ASSERT(h_handler != NULL);
+ if (DUK_HOBJECT_IS_PROXY(h_handler)) {
+ goto fail_args;
+ }
+
+ /* XXX: Proxy object currently has no prototype, so ToPrimitive()
+ * coercion fails which is a bit confusing.
+ */
+
+ /* CALLABLE and CONSTRUCTABLE flags are copied from the (initial)
+ * target, see ES2015 Sections 9.5.15 and 9.5.13.
+ */
+ flags = DUK_HEAPHDR_GET_FLAGS((duk_heaphdr *) h_target) &
+ (DUK_HOBJECT_FLAG_CALLABLE | DUK_HOBJECT_FLAG_CONSTRUCTABLE);
+ flags |= DUK_HOBJECT_FLAG_EXTENSIBLE |
+ DUK_HOBJECT_FLAG_EXOTIC_PROXYOBJ;
+ if (flags & DUK_HOBJECT_FLAG_CALLABLE) {
+ flags |= DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_FUNCTION) |
+ DUK_HOBJECT_FLAG_SPECIAL_CALL;
+ } else {
+ flags |= DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_OBJECT);
+ }
+
+ h_proxy = duk_hproxy_alloc(thr, flags);
+ DUK_ASSERT(h_proxy != NULL);
+ DUK_ASSERT(DUK_HOBJECT_GET_PROTOTYPE(thr->heap, (duk_hobject *) h_proxy) == NULL);
+
+ /* Initialize Proxy target and handler references; avoid INCREF
+ * by stealing the value stack refcounts via direct value stack
+ * manipulation. INCREF is needed for the Proxy itself however.
+ */
+ DUK_ASSERT(h_target != NULL);
+ h_proxy->target = h_target;
+ DUK_ASSERT(h_handler != NULL);
+ h_proxy->handler = h_handler;
+ DUK_ASSERT_HPROXY_VALID(h_proxy);
+
+ DUK_ASSERT(duk_get_hobject(thr, -2) == h_target);
+ DUK_ASSERT(duk_get_hobject(thr, -1) == h_handler);
+ tv_slot = thr->valstack_top - 2;
+ DUK_ASSERT(tv_slot >= thr->valstack_bottom);
+ DUK_TVAL_SET_OBJECT(tv_slot, (duk_hobject *) h_proxy);
+ DUK_HOBJECT_INCREF(thr, (duk_hobject *) h_proxy);
+ tv_slot++;
+ DUK_TVAL_SET_UNDEFINED(tv_slot); /* [ ... target handler ] -> [ ... proxy undefined ] */
+ thr->valstack_top = tv_slot; /* -> [ ... proxy ] */
+
+ DUK_DD(DUK_DDPRINT("created Proxy: %!iT", duk_get_tval(thr, -1)));
+
+ return (duk_idx_t) (thr->valstack_top - thr->valstack_bottom - 1);
+
+ fail_args:
+ DUK_ERROR_TYPE_INVALID_ARGS(thr);
+}
+#else /* DUK_USE_ES6_PROXY */
+DUK_EXTERNAL duk_idx_t duk_push_proxy(duk_hthread *thr, duk_uint_t proxy_flags) {
+ DUK_ASSERT_API_ENTRY(thr);
+ DUK_UNREF(proxy_flags);
+ DUK_ERROR_UNSUPPORTED(thr);
+}
+#endif /* DUK_USE_ES6_PROXY */
+
#if defined(DUK_USE_ASSERTIONS)
-DUK_LOCAL void duk__validate_push_heapptr(duk_context *ctx, void *ptr) {
+DUK_LOCAL void duk__validate_push_heapptr(duk_hthread *thr, void *ptr) {
duk_heaphdr *h;
duk_heaphdr *curr;
- duk_hthread *thr;
duk_bool_t found = 0;
- thr = (duk_hthread *) ctx;
h = (duk_heaphdr *) ptr;
if (h == NULL) {
/* Allowed. */
@@ -21675,12 +22548,11 @@ DUK_LOCAL void duk__validate_push_heapptr(duk_context *ctx, void *ptr) {
}
#endif /* DUK_USE_ASSERTIONS */
-DUK_EXTERNAL duk_idx_t duk_push_heapptr(duk_context *ctx, void *ptr) {
- duk_hthread *thr = (duk_hthread *) ctx;
+DUK_EXTERNAL duk_idx_t duk_push_heapptr(duk_hthread *thr, void *ptr) {
duk_idx_t ret;
duk_tval *tv;
- DUK_ASSERT_CTX_VALID(ctx);
+ DUK_ASSERT_API_ENTRY(thr);
/* Reviving an object using a heap pointer is a dangerous API
* operation: if the application doesn't guarantee that the
@@ -21690,7 +22562,7 @@ DUK_EXTERNAL duk_idx_t duk_push_heapptr(duk_context *ctx, void *ptr) {
*/
#if defined(DUK_USE_ASSERTIONS)
- duk__validate_push_heapptr(ctx, ptr);
+ duk__validate_push_heapptr(thr, ptr);
#endif
DUK__CHECK_SPACE();
@@ -21768,83 +22640,79 @@ DUK_EXTERNAL duk_idx_t duk_push_heapptr(duk_context *ctx, void *ptr) {
}
/* Push object with no prototype, i.e. a "bare" object. */
-DUK_EXTERNAL duk_idx_t duk_push_bare_object(duk_context *ctx) {
- (void) duk_push_object_helper(ctx,
+DUK_EXTERNAL duk_idx_t duk_push_bare_object(duk_hthread *thr) {
+ DUK_ASSERT_API_ENTRY(thr);
+
+ (void) duk_push_object_helper(thr,
DUK_HOBJECT_FLAG_EXTENSIBLE |
DUK_HOBJECT_FLAG_FASTREFS |
DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_OBJECT),
-1); /* no prototype */
- return duk_get_top_index_unsafe(ctx);
+ return duk_get_top_index_unsafe(thr);
}
-DUK_INTERNAL void duk_push_hstring(duk_context *ctx, duk_hstring *h) {
+DUK_INTERNAL void duk_push_hstring(duk_hthread *thr, duk_hstring *h) {
duk_tval tv;
- DUK_ASSERT_CTX_VALID(ctx);
+
+ DUK_ASSERT_API_ENTRY(thr);
DUK_ASSERT(h != NULL);
+
DUK_TVAL_SET_STRING(&tv, h);
- duk_push_tval(ctx, &tv);
+ duk_push_tval(thr, &tv);
}
-DUK_INTERNAL void duk_push_hstring_stridx(duk_context *ctx, duk_small_uint_t stridx) {
- duk_hthread *thr = (duk_hthread *) ctx;
- DUK_UNREF(thr);
+DUK_INTERNAL void duk_push_hstring_stridx(duk_hthread *thr, duk_small_uint_t stridx) {
+ DUK_ASSERT_API_ENTRY(thr);
DUK_ASSERT_STRIDX_VALID(stridx);
- duk_push_hstring(ctx, DUK_HTHREAD_GET_STRING(thr, stridx));
+ duk_push_hstring(thr, DUK_HTHREAD_GET_STRING(thr, stridx));
}
-DUK_INTERNAL void duk_push_hstring_empty(duk_context *ctx) {
- duk_hthread *thr = (duk_hthread *) ctx;
- DUK_UNREF(thr);
- duk_push_hstring(ctx, DUK_HTHREAD_GET_STRING(thr, DUK_STRIDX_EMPTY_STRING));
+DUK_INTERNAL void duk_push_hstring_empty(duk_hthread *thr) {
+ DUK_ASSERT_API_ENTRY(thr);
+ duk_push_hstring(thr, DUK_HTHREAD_GET_STRING(thr, DUK_STRIDX_EMPTY_STRING));
}
-DUK_INTERNAL void duk_push_hobject(duk_context *ctx, duk_hobject *h) {
+DUK_INTERNAL void duk_push_hobject(duk_hthread *thr, duk_hobject *h) {
duk_tval tv;
- DUK_ASSERT_CTX_VALID(ctx);
+
+ DUK_ASSERT_API_ENTRY(thr);
DUK_ASSERT(h != NULL);
+
DUK_TVAL_SET_OBJECT(&tv, h);
- duk_push_tval(ctx, &tv);
+ duk_push_tval(thr, &tv);
}
-DUK_INTERNAL void duk_push_hbuffer(duk_context *ctx, duk_hbuffer *h) {
+DUK_INTERNAL void duk_push_hbuffer(duk_hthread *thr, duk_hbuffer *h) {
duk_tval tv;
- DUK_ASSERT_CTX_VALID(ctx);
+
+ DUK_ASSERT_API_ENTRY(thr);
DUK_ASSERT(h != NULL);
+
DUK_TVAL_SET_BUFFER(&tv, h);
- duk_push_tval(ctx, &tv);
+ duk_push_tval(thr, &tv);
}
-DUK_INTERNAL void duk_push_hobject_bidx(duk_context *ctx, duk_small_int_t builtin_idx) {
- duk_hthread *thr = (duk_hthread *) ctx;
- DUK_ASSERT_CTX_VALID(ctx);
- DUK_ASSERT(thr != NULL);
+DUK_INTERNAL void duk_push_hobject_bidx(duk_hthread *thr, duk_small_int_t builtin_idx) {
+ DUK_ASSERT_API_ENTRY(thr);
DUK_ASSERT(builtin_idx >= 0 && builtin_idx < DUK_NUM_BUILTINS);
DUK_ASSERT(thr->builtins[builtin_idx] != NULL);
- duk_push_hobject(ctx, thr->builtins[builtin_idx]);
+
+ duk_push_hobject(thr, thr->builtins[builtin_idx]);
}
/*
* Poppers
*/
-DUK_EXTERNAL void duk_pop_n(duk_context *ctx, duk_idx_t count) {
- duk_hthread *thr = (duk_hthread *) ctx;
+DUK_LOCAL DUK_ALWAYS_INLINE void duk__pop_n_unsafe_raw(duk_hthread *thr, duk_idx_t count) {
duk_tval *tv;
#if defined(DUK_USE_REFERENCE_COUNTING)
duk_tval *tv_end;
#endif
- DUK_ASSERT_CTX_VALID(ctx);
- DUK_ASSERT(thr->valstack_top >= thr->valstack_bottom);
-
- if (DUK_UNLIKELY(count < 0)) {
- DUK_ERROR_RANGE_INVALID_COUNT(thr);
- return;
- }
-
- if (DUK_UNLIKELY((duk_size_t) (thr->valstack_top - thr->valstack_bottom) < (duk_size_t) count)) {
- DUK_ERROR_RANGE_INVALID_COUNT(thr);
- }
+ DUK_ASSERT_CTX_VALID(thr);
+ DUK_ASSERT(count >= 0);
+ DUK_ASSERT((duk_size_t) (thr->valstack_top - thr->valstack_bottom) >= (duk_size_t) count);
#if defined(DUK_USE_REFERENCE_COUNTING)
tv = thr->valstack_top;
@@ -21870,49 +22738,37 @@ DUK_EXTERNAL void duk_pop_n(duk_context *ctx, duk_idx_t count) {
DUK_ASSERT(thr->valstack_top >= thr->valstack_bottom);
}
-DUK_INTERNAL void duk_pop_n_unsafe(duk_context *ctx, duk_idx_t count) {
- duk_hthread *thr = (duk_hthread *) ctx;
- duk_tval *tv;
-#if defined(DUK_USE_REFERENCE_COUNTING)
- duk_tval *tv_end;
-#endif
-
- DUK_ASSERT_CTX_VALID(ctx);
- DUK_ASSERT(count >= 0);
+DUK_EXTERNAL void duk_pop_n(duk_hthread *thr, duk_idx_t count) {
+ DUK_ASSERT_API_ENTRY(thr);
DUK_ASSERT(thr->valstack_top >= thr->valstack_bottom);
- DUK_ASSERT((duk_size_t) (thr->valstack_top - thr->valstack_bottom) >= (duk_size_t) count);
-#if defined(DUK_USE_REFERENCE_COUNTING)
- tv = thr->valstack_top;
- tv_end = tv - count;
- while (tv != tv_end) {
- tv--;
- DUK_ASSERT(tv >= thr->valstack_bottom);
- DUK_TVAL_SET_UNDEFINED_UPDREF_NORZ(thr, tv);
- }
- thr->valstack_top = tv;
- DUK_REFZERO_CHECK_FAST(thr);
-#else
- tv = thr->valstack_top;
- while (count > 0) {
- count--;
- tv--;
- DUK_ASSERT(tv >= thr->valstack_bottom);
- DUK_TVAL_SET_UNDEFINED(tv);
+ if (DUK_UNLIKELY((duk_uidx_t) (thr->valstack_top - thr->valstack_bottom) < (duk_uidx_t) count)) {
+ DUK_ERROR_RANGE_INVALID_COUNT(thr);
+ return;
}
- thr->valstack_top = tv;
-#endif
+ DUK_ASSERT(count >= 0);
- DUK_ASSERT(thr->valstack_top >= thr->valstack_bottom);
+ duk__pop_n_unsafe_raw(thr, count);
}
-/* Pop N elements without DECREF (in effect "stealing" the refcounts). */
+#if defined(DUK_USE_PREFER_SIZE)
+DUK_INTERNAL void duk_pop_n_unsafe(duk_hthread *thr, duk_idx_t count) {
+ DUK_ASSERT_API_ENTRY(thr);
+ duk_pop_n(thr, count);
+}
+#else /* DUK_USE_PREFER_SIZE */
+DUK_INTERNAL void duk_pop_n_unsafe(duk_hthread *thr, duk_idx_t count) {
+ DUK_ASSERT_API_ENTRY(thr);
+ duk__pop_n_unsafe_raw(thr, count);
+}
+#endif /* DUK_USE_PREFER_SIZE */
+
+/* Pop N elements without DECREF (in effect "stealing" any actual refcounts). */
#if defined(DUK_USE_REFERENCE_COUNTING)
-DUK_INTERNAL void duk_pop_n_nodecref_unsafe(duk_context *ctx, duk_idx_t count) {
- duk_hthread *thr = (duk_hthread *) ctx;
+DUK_INTERNAL void duk_pop_n_nodecref_unsafe(duk_hthread *thr, duk_idx_t count) {
duk_tval *tv;
- DUK_ASSERT_CTX_VALID(ctx);
+ DUK_ASSERT_API_ENTRY(thr);
DUK_ASSERT(count >= 0);
DUK_ASSERT(thr->valstack_top >= thr->valstack_bottom);
DUK_ASSERT((duk_size_t) (thr->valstack_top - thr->valstack_bottom) >= (duk_size_t) count);
@@ -21929,8 +22785,9 @@ DUK_INTERNAL void duk_pop_n_nodecref_unsafe(duk_context *ctx, duk_idx_t count) {
DUK_ASSERT(thr->valstack_top >= thr->valstack_bottom);
}
#else /* DUK_USE_REFERENCE_COUNTING */
-DUK_INTERNAL void duk_pop_n_nodecref_unsafe(duk_context *ctx, duk_idx_t count) {
- duk_pop_n_unsafe(ctx, count);
+DUK_INTERNAL void duk_pop_n_nodecref_unsafe(duk_hthread *thr, duk_idx_t count) {
+ DUK_ASSERT_API_ENTRY(thr);
+ duk_pop_n_unsafe(thr, count);
}
#endif /* DUK_USE_REFERENCE_COUNTING */
@@ -21938,51 +22795,116 @@ DUK_INTERNAL void duk_pop_n_nodecref_unsafe(duk_context *ctx, duk_idx_t count) {
* 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);
+DUK_EXTERNAL void duk_pop(duk_hthread *thr) {
+ DUK_ASSERT_API_ENTRY(thr);
+ duk_pop_n(thr, 1);
}
-#else
-DUK_EXTERNAL void duk_pop(duk_context *ctx) {
- duk_hthread *thr = (duk_hthread *) ctx;
+DUK_INTERNAL void duk_pop_unsafe(duk_hthread *thr) {
+ DUK_ASSERT_API_ENTRY(thr);
+ duk_pop_n_unsafe(thr, 1);
+}
+DUK_INTERNAL void duk_pop_nodecref_unsafe(duk_hthread *thr) {
+ DUK_ASSERT_API_ENTRY(thr);
+ duk_pop_n_nodecref_unsafe(thr, 1);
+}
+#else /* DUK_USE_PREFER_SIZE */
+DUK_LOCAL DUK_ALWAYS_INLINE void duk__pop_unsafe_raw(duk_hthread *thr) {
duk_tval *tv;
- DUK_ASSERT_CTX_VALID(ctx);
+ DUK_ASSERT_CTX_VALID(thr);
+ DUK_ASSERT(thr->valstack_top != thr->valstack_bottom);
DUK_ASSERT(thr->valstack_top >= thr->valstack_bottom);
- if (DUK_UNLIKELY(thr->valstack_top == thr->valstack_bottom)) {
- DUK_ERROR_RANGE_INVALID_COUNT(thr);
- }
+ DUK_ASSERT((duk_size_t) (thr->valstack_top - thr->valstack_bottom) >= (duk_size_t) 1);
- tv = --thr->valstack_top; /* tv points to element just below prev top */
+ tv = --thr->valstack_top;
DUK_ASSERT(tv >= thr->valstack_bottom);
#if defined(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);
+}
+DUK_EXTERNAL void duk_pop(duk_hthread *thr) {
+ DUK_ASSERT_API_ENTRY(thr);
+
+ DUK_ASSERT(thr->valstack_top >= thr->valstack_bottom);
+ if (DUK_UNLIKELY(thr->valstack_top == thr->valstack_bottom)) {
+ DUK_ERROR_RANGE_INVALID_COUNT(thr);
+ }
+
+ duk__pop_unsafe_raw(thr);
+}
+DUK_INTERNAL void duk_pop_unsafe(duk_hthread *thr) {
+ DUK_ASSERT_API_ENTRY(thr);
+ duk__pop_unsafe_raw(thr);
+}
+DUK_INTERNAL void duk_pop_nodecref_unsafe(duk_hthread *thr) {
+ duk_tval *tv;
+
+ DUK_ASSERT_API_ENTRY(thr);
+ DUK_ASSERT(thr->valstack_top != thr->valstack_bottom);
+ DUK_ASSERT(thr->valstack_top >= thr->valstack_bottom);
+ DUK_ASSERT((duk_size_t) (thr->valstack_top - thr->valstack_bottom) >= (duk_size_t) 1);
+
+ tv = --thr->valstack_top;
+ DUK_ASSERT(tv >= thr->valstack_bottom);
+ DUK_TVAL_SET_UNDEFINED(tv);
+
DUK_ASSERT(thr->valstack_top >= thr->valstack_bottom);
}
#endif /* !DUK_USE_PREFER_SIZE */
-/* Unsafe internal variant which assumes there are enough values on the value
- * stack so that a top check can be skipped safely.
- */
#if defined(DUK_USE_PREFER_SIZE)
-DUK_INTERNAL void duk_pop_unsafe(duk_context *ctx) {
- DUK_ASSERT_CTX_VALID(ctx);
- duk_pop_n_unsafe(ctx, 1);
+DUK_INTERNAL void duk_pop_undefined(duk_hthread *thr) {
+ DUK_ASSERT_API_ENTRY(thr);
+ duk_pop_nodecref_unsafe(thr);
+}
+#else /* DUK_USE_PREFER_SIZE */
+DUK_INTERNAL void duk_pop_undefined(duk_hthread *thr) {
+ DUK_ASSERT_API_ENTRY(thr);
+ DUK_ASSERT(thr->valstack_top != thr->valstack_bottom);
+ DUK_ASSERT(thr->valstack_top >= thr->valstack_bottom);
+ DUK_ASSERT((duk_size_t) (thr->valstack_top - thr->valstack_bottom) >= (duk_size_t) 1);
+
+ DUK_ASSERT(DUK_TVAL_IS_UNDEFINED(thr->valstack_top - 1));
+ thr->valstack_top--;
+
+ DUK_ASSERT(thr->valstack_top >= thr->valstack_bottom);
+}
+#endif /* !DUK_USE_PREFER_SIZE */
+
+#if defined(DUK_USE_PREFER_SIZE)
+DUK_EXTERNAL void duk_pop_2(duk_hthread *thr) {
+ DUK_ASSERT_API_ENTRY(thr);
+ duk_pop_n(thr, 2);
+}
+DUK_INTERNAL void duk_pop_2_unsafe(duk_hthread *thr) {
+ DUK_ASSERT_API_ENTRY(thr);
+ duk_pop_n_unsafe(thr, 2);
+}
+DUK_INTERNAL void duk_pop_2_nodecref_unsafe(duk_hthread *thr) {
+ DUK_ASSERT_API_ENTRY(thr);
+ duk_pop_n_nodecref_unsafe(thr, 2);
}
#else
-DUK_INTERNAL void duk_pop_unsafe(duk_context *ctx) {
- duk_hthread *thr = (duk_hthread *) ctx;
+DUK_LOCAL DUK_ALWAYS_INLINE void duk__pop_2_unsafe_raw(duk_hthread *thr) {
duk_tval *tv;
- DUK_ASSERT_CTX_VALID(ctx);
+ DUK_ASSERT_CTX_VALID(thr);
DUK_ASSERT(thr->valstack_top != thr->valstack_bottom);
DUK_ASSERT(thr->valstack_top >= thr->valstack_bottom);
- DUK_ASSERT((duk_size_t) (thr->valstack_top - thr->valstack_bottom) >= (duk_size_t) 1);
+ DUK_ASSERT((duk_size_t) (thr->valstack_top - thr->valstack_bottom) >= (duk_size_t) 2);
- tv = --thr->valstack_top; /* tv points to element just below prev top */
+ tv = --thr->valstack_top;
+ DUK_ASSERT(tv >= thr->valstack_bottom);
+#if defined(DUK_USE_REFERENCE_COUNTING)
+ DUK_TVAL_SET_UNDEFINED_UPDREF(thr, tv); /* side effects */
+#else
+ DUK_TVAL_SET_UNDEFINED(tv);
+#endif
+ tv = --thr->valstack_top;
DUK_ASSERT(tv >= thr->valstack_bottom);
#if defined(DUK_USE_REFERENCE_COUNTING)
DUK_TVAL_SET_UNDEFINED_UPDREF(thr, tv); /* side effects */
@@ -21992,16 +22914,47 @@ DUK_INTERNAL void duk_pop_unsafe(duk_context *ctx) {
DUK_ASSERT(thr->valstack_top >= thr->valstack_bottom);
}
+DUK_EXTERNAL void duk_pop_2(duk_hthread *thr) {
+ DUK_ASSERT_API_ENTRY(thr);
+
+ DUK_ASSERT(thr->valstack_top >= thr->valstack_bottom);
+ if (DUK_UNLIKELY(thr->valstack_top - 2 < thr->valstack_bottom)) {
+ DUK_ERROR_RANGE_INVALID_COUNT(thr);
+ }
+
+ duk__pop_2_unsafe_raw(thr);
+}
+DUK_INTERNAL void duk_pop_2_unsafe(duk_hthread *thr) {
+ DUK_ASSERT_API_ENTRY(thr);
+ duk__pop_2_unsafe_raw(thr);
+}
+DUK_INTERNAL void duk_pop_2_nodecref_unsafe(duk_hthread *thr) {
+ DUK_ASSERT_API_ENTRY(thr);
+ DUK_ASSERT(thr->valstack_top != thr->valstack_bottom);
+ DUK_ASSERT(thr->valstack_top >= thr->valstack_bottom);
+ DUK_ASSERT((duk_size_t) (thr->valstack_top - thr->valstack_bottom) >= (duk_size_t) 2);
+
+ DUK_ASSERT(DUK_TVAL_IS_UNDEFINED(thr->valstack_top - 1));
+ DUK_ASSERT(DUK_TVAL_IS_UNDEFINED(thr->valstack_top - 2));
+ thr->valstack_top -= 2;
+
+ 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);
- duk_pop_n(ctx, 2);
+DUK_EXTERNAL void duk_pop_3(duk_hthread *thr) {
+ DUK_ASSERT_API_ENTRY(thr);
+ duk_pop_n(thr, 3);
}
-DUK_EXTERNAL void duk_pop_3(duk_context *ctx) {
- DUK_ASSERT_CTX_VALID(ctx);
- duk_pop_n(ctx, 3);
+DUK_INTERNAL void duk_pop_3_unsafe(duk_hthread *thr) {
+ DUK_ASSERT_API_ENTRY(thr);
+ duk_pop_n_unsafe(thr, 3);
+}
+
+DUK_INTERNAL void duk_pop_3_nodecref_unsafe(duk_hthread *thr) {
+ DUK_ASSERT_API_ENTRY(thr);
+ duk_pop_n_nodecref_unsafe(thr, 3);
}
/*
@@ -22009,43 +22962,40 @@ DUK_EXTERNAL void duk_pop_3(duk_context *ctx) {
*/
/* XXX: pack index range? array index offset? */
-DUK_INTERNAL void duk_pack(duk_context *ctx, duk_idx_t count) {
- duk_hthread *thr;
- duk_harray *a;
+DUK_INTERNAL void duk_pack(duk_hthread *thr, duk_idx_t count) {
duk_tval *tv_src;
duk_tval *tv_dst;
duk_tval *tv_curr;
duk_tval *tv_limit;
duk_idx_t top;
- DUK_ASSERT_CTX_VALID(ctx);
- thr = (duk_hthread *) ctx;
+ DUK_ASSERT_API_ENTRY(thr);
+ DUK_ASSERT(thr->valstack_top >= thr->valstack_bottom);
top = (duk_idx_t) (thr->valstack_top - thr->valstack_bottom);
- if (DUK_UNLIKELY(count < 0 || count > top)) {
+ DUK_ASSERT(top >= 0);
+ if (DUK_UNLIKELY((duk_uidx_t) count > (duk_uidx_t) top)) {
+ /* Also handles negative count. */
DUK_ERROR_RANGE_INVALID_COUNT(thr);
return;
}
+ DUK_ASSERT(count >= 0);
/* Wrapping is controlled by the check above: value stack top can be
- * at most thr->valstack_max which is low enough so that multiplying
- * with sizeof(duk_tval) won't wrap.
+ * at most DUK_USE_VALSTACK_LIMIT which is low enough so that
+ * multiplying with sizeof(duk_tval) won't wrap.
*/
- DUK_ASSERT(count >= 0 && count <= (duk_idx_t) thr->valstack_max);
+ DUK_ASSERT(count >= 0 && count <= (duk_idx_t) DUK_USE_VALSTACK_LIMIT);
DUK_ASSERT((duk_size_t) count <= DUK_SIZE_MAX / sizeof(duk_tval)); /* no wrapping */
- a = duk_push_harray_with_size(ctx, (duk_uint32_t) count); /* XXX: uninitialized would be OK */
- DUK_ASSERT(a != NULL);
- DUK_ASSERT(DUK_HOBJECT_GET_ASIZE((duk_hobject *) a) == (duk_uint32_t) count);
- DUK_ASSERT(count == 0 || DUK_HOBJECT_A_GET_BASE(thr->heap, (duk_hobject *) a) != NULL);
- DUK_ASSERT((duk_idx_t) a->length == count);
+ tv_dst = duk_push_harray_with_size_outptr(thr, (duk_uint32_t) count); /* XXX: uninitialized would be OK */
+ DUK_ASSERT(count == 0 || tv_dst != NULL);
/* Copy value stack values directly to the array part without
* any refcount updates: net refcount changes are zero.
*/
tv_src = thr->valstack_top - count - 1;
- tv_dst = DUK_HOBJECT_A_GET_BASE(thr->heap, (duk_hobject *) a);
DUK_MEMCPY((void *) tv_dst, (const void *) tv_src, (size_t) count * sizeof(duk_tval));
/* Overwrite result array to final value stack location and wipe
@@ -22067,26 +23017,118 @@ DUK_INTERNAL void duk_pack(duk_context *ctx, duk_idx_t count) {
thr->valstack_top = tv_dst + 1;
}
-#if 0
-/* XXX: unpack to position? */
-DUK_INTERNAL void duk_unpack(duk_context *ctx) {
- /* - dense with length <= a_part
- * - dense with length > a_part
- * - sparse
- * - array-like but not actually an array?
- * - how to deal with 'unused' values (gaps); inherit or ignore?
- */
+DUK_INTERNAL duk_idx_t duk_unpack_array_like(duk_hthread *thr, duk_idx_t idx) {
+ duk_tval *tv;
+
+ DUK_ASSERT_API_ENTRY(thr);
+
+ tv = duk_require_tval(thr, idx);
+ if (DUK_LIKELY(DUK_TVAL_IS_OBJECT(tv))) {
+ duk_hobject *h;
+ duk_uint32_t len;
+ duk_uint32_t i;
+
+ h = DUK_TVAL_GET_OBJECT(tv);
+ DUK_ASSERT(h != NULL);
+ DUK_UNREF(h);
+
+#if defined(DUK_USE_ARRAY_FASTPATH) /* close enough */
+ if (DUK_LIKELY(DUK_HOBJECT_IS_ARRAY(h) &&
+ ((duk_harray *) h)->length <= DUK_HOBJECT_GET_ASIZE(h))) {
+ duk_harray *h_arr;
+ duk_tval *tv_src;
+ duk_tval *tv_dst;
+
+ h_arr = (duk_harray *) h;
+ len = h_arr->length;
+ if (DUK_UNLIKELY(len >= 0x80000000UL)) {
+ goto fail_over_2g;
+ }
+ duk_require_stack(thr, (duk_idx_t) len);
+
+ /* The potential allocation in duk_require_stack() may
+ * run a finalizer which modifies the argArray so that
+ * e.g. becomes sparse. So, we need to recheck that the
+ * array didn't change size and that there's still a
+ * valid backing array part.
+ *
+ * XXX: alternatively, could prevent finalizers for the
+ * duration.
+ */
+ if (DUK_UNLIKELY(len != h_arr->length ||
+ h_arr->length > DUK_HOBJECT_GET_ASIZE((duk_hobject *) h_arr))) {
+ goto skip_fast;
+ }
+
+ /* Main fast path: arguments array is almost always
+ * an actual array (though it might also be an arguments
+ * object).
+ */
+
+ DUK_DDD(DUK_DDDPRINT("fast path for %ld elements", (long) h_arr->length));
+ tv_src = DUK_HOBJECT_A_GET_BASE(thr->heap, h);
+ tv_dst = thr->valstack_top;
+ while (len-- > 0) {
+ DUK_ASSERT(tv_dst < thr->valstack_end);
+ if (DUK_UNLIKELY(DUK_TVAL_IS_UNUSED(tv_src))) {
+ /* Gaps are very unlikely. Skip over them,
+ * without an ancestor lookup (technically
+ * not compliant).
+ */
+ DUK_ASSERT(DUK_TVAL_IS_UNDEFINED(tv_dst)); /* valstack policy */
+ } else {
+ DUK_TVAL_SET_TVAL(tv_dst, tv_src);
+ DUK_TVAL_INCREF(thr, tv_dst);
+ }
+ tv_src++;
+ tv_dst++;
+ }
+ DUK_ASSERT(tv_dst <= thr->valstack_end);
+ thr->valstack_top = tv_dst;
+ return (duk_idx_t) h_arr->length;
+ }
+ skip_fast:
+#endif /* DUK_USE_ARRAY_FASTPATH */
+
+ /* Slow path: actual lookups. The initial 'length' lookup
+ * decides the output length, regardless of side effects that
+ * may resize or change the argArray while we read the
+ * indices.
+ */
+ idx = duk_normalize_index(thr, idx);
+ duk_get_prop_stridx(thr, idx, DUK_STRIDX_LENGTH);
+ len = duk_to_uint32(thr, -1); /* ToUint32() coercion required */
+ if (DUK_UNLIKELY(len >= 0x80000000UL)) {
+ goto fail_over_2g;
+ }
+ duk_pop_unsafe(thr);
+ DUK_DDD(DUK_DDDPRINT("slow path for %ld elements", (long) len));
+
+ duk_require_stack(thr, (duk_idx_t) len);
+ for (i = 0; i < len; i++) {
+ duk_get_prop_index(thr, idx, (duk_uarridx_t) i);
+ }
+ return (duk_idx_t) len;
+ } else if (DUK_TVAL_IS_UNDEFINED(tv) || DUK_TVAL_IS_NULL(tv)) {
+ return 0;
+ }
+
+ DUK_ERROR_TYPE_INVALID_ARGS(thr);
+ return 0;
+
+ fail_over_2g:
+ DUK_ERROR_RANGE_INVALID_LENGTH(thr);
+ return 0;
}
-#endif
/*
* Error throwing
*/
-DUK_EXTERNAL void duk_throw_raw(duk_context *ctx) {
- duk_hthread *thr = (duk_hthread *) ctx;
+DUK_EXTERNAL void duk_throw_raw(duk_hthread *thr) {
duk_tval *tv_val;
+ DUK_ASSERT_API_ENTRY(thr);
DUK_ASSERT(thr->valstack_bottom >= thr->valstack);
DUK_ASSERT(thr->valstack_top >= thr->valstack_bottom);
DUK_ASSERT(thr->valstack_end >= thr->valstack_top);
@@ -22107,12 +23149,12 @@ DUK_EXTERNAL void duk_throw_raw(duk_context *ctx) {
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_DDD(DUK_DDDPRINT("THROW ERROR (API): %!dT (before throw augment)", (duk_tval *) duk_get_tval(thr, -1)));
duk_err_augment_error_throw(thr);
#endif
- DUK_DDD(DUK_DDDPRINT("THROW ERROR (API): %!dT (after throw augment)", (duk_tval *) duk_get_tval(ctx, -1)));
+ DUK_DDD(DUK_DDDPRINT("THROW ERROR (API): %!dT (after throw augment)", (duk_tval *) duk_get_tval(thr, -1)));
- tv_val = DUK_GET_TVAL_NEGIDX(ctx, -1);
+ tv_val = DUK_GET_TVAL_NEGIDX(thr, -1);
duk_err_setup_ljstate1(thr, DUK_LJ_TYPE_THROW, tv_val);
#if defined(DUK_USE_DEBUGGER_SUPPORT)
duk_err_check_debugger_integration(thr);
@@ -22127,10 +23169,8 @@ DUK_EXTERNAL void duk_throw_raw(duk_context *ctx) {
DUK_UNREACHABLE();
}
-DUK_EXTERNAL void duk_fatal_raw(duk_context *ctx, const char *err_msg) {
- duk_hthread *thr = (duk_hthread *) ctx;
-
- DUK_ASSERT_CTX_VALID(ctx);
+DUK_EXTERNAL void duk_fatal_raw(duk_hthread *thr, const char *err_msg) {
+ DUK_ASSERT_API_ENTRY(thr);
DUK_ASSERT(thr != NULL);
DUK_ASSERT(thr->heap != NULL);
DUK_ASSERT(thr->heap->fatal_func != NULL);
@@ -22153,72 +23193,80 @@ DUK_EXTERNAL void duk_fatal_raw(duk_context *ctx, const char *err_msg) {
}
}
-DUK_EXTERNAL void duk_error_va_raw(duk_context *ctx, duk_errcode_t err_code, const char *filename, duk_int_t line, const char *fmt, va_list ap) {
- DUK_ASSERT_CTX_VALID(ctx);
+DUK_EXTERNAL void duk_error_va_raw(duk_hthread *thr, duk_errcode_t err_code, const char *filename, duk_int_t line, const char *fmt, va_list ap) {
+ DUK_ASSERT_API_ENTRY(thr);
- duk_push_error_object_va_raw(ctx, err_code, filename, line, fmt, ap);
- (void) duk_throw(ctx);
+ duk_push_error_object_va_raw(thr, err_code, filename, line, fmt, ap);
+ (void) duk_throw(thr);
}
-DUK_EXTERNAL void duk_error_raw(duk_context *ctx, duk_errcode_t err_code, const char *filename, duk_int_t line, const char *fmt, ...) {
+DUK_EXTERNAL void duk_error_raw(duk_hthread *thr, duk_errcode_t err_code, const char *filename, duk_int_t line, const char *fmt, ...) {
va_list ap;
- DUK_ASSERT_CTX_VALID(ctx);
+ DUK_ASSERT_API_ENTRY(thr);
va_start(ap, fmt);
- duk_push_error_object_va_raw(ctx, err_code, filename, line, fmt, ap);
+ duk_push_error_object_va_raw(thr, err_code, filename, line, fmt, ap);
va_end(ap);
- (void) duk_throw(ctx);
+ (void) duk_throw(thr);
}
#if !defined(DUK_USE_VARIADIC_MACROS)
-DUK_NORETURN(DUK_LOCAL_DECL void duk__throw_error_from_stash(duk_context *ctx, duk_errcode_t err_code, const char *fmt, va_list ap));
+DUK_NORETURN(DUK_LOCAL_DECL void duk__throw_error_from_stash(duk_hthread *thr, duk_errcode_t err_code, const char *fmt, va_list ap));
-DUK_LOCAL void duk__throw_error_from_stash(duk_context *ctx, duk_errcode_t err_code, const char *fmt, va_list ap) {
+DUK_LOCAL void duk__throw_error_from_stash(duk_hthread *thr, duk_errcode_t err_code, const char *fmt, va_list ap) {
const char *filename;
duk_int_t line;
- DUK_ASSERT_CTX_VALID(ctx);
+ DUK_ASSERT_CTX_VALID(thr);
filename = duk_api_global_filename;
line = duk_api_global_line;
duk_api_global_filename = NULL;
duk_api_global_line = 0;
- duk_push_error_object_va_raw(ctx, err_code, filename, line, fmt, ap);
- (void) duk_throw(ctx);
+ duk_push_error_object_va_raw(thr, err_code, filename, line, fmt, ap);
+ (void) duk_throw(thr);
}
#define DUK__ERROR_STASH_SHARED(code) do { \
va_list ap; \
va_start(ap, fmt); \
- duk__throw_error_from_stash(ctx, (code), fmt, ap); \
+ duk__throw_error_from_stash(thr, (code), fmt, ap); \
va_end(ap); \
/* Never reached; if return 0 here, gcc/clang will complain. */ \
} while (0)
-DUK_EXTERNAL duk_ret_t duk_error_stash(duk_context *ctx, duk_errcode_t err_code, const char *fmt, ...) {
+DUK_EXTERNAL duk_ret_t duk_error_stash(duk_hthread *thr, duk_errcode_t err_code, const char *fmt, ...) {
+ DUK_ASSERT_API_ENTRY(thr);
DUK__ERROR_STASH_SHARED(err_code);
}
-DUK_EXTERNAL duk_ret_t duk_generic_error_stash(duk_context *ctx, const char *fmt, ...) {
+DUK_EXTERNAL duk_ret_t duk_generic_error_stash(duk_hthread *thr, const char *fmt, ...) {
+ DUK_ASSERT_API_ENTRY(thr);
DUK__ERROR_STASH_SHARED(DUK_ERR_ERROR);
}
-DUK_EXTERNAL duk_ret_t duk_eval_error_stash(duk_context *ctx, const char *fmt, ...) {
+DUK_EXTERNAL duk_ret_t duk_eval_error_stash(duk_hthread *thr, const char *fmt, ...) {
+ DUK_ASSERT_API_ENTRY(thr);
DUK__ERROR_STASH_SHARED(DUK_ERR_EVAL_ERROR);
}
-DUK_EXTERNAL duk_ret_t duk_range_error_stash(duk_context *ctx, const char *fmt, ...) {
+DUK_EXTERNAL duk_ret_t duk_range_error_stash(duk_hthread *thr, const char *fmt, ...) {
+ DUK_ASSERT_API_ENTRY(thr);
DUK__ERROR_STASH_SHARED(DUK_ERR_RANGE_ERROR);
}
-DUK_EXTERNAL duk_ret_t duk_reference_error_stash(duk_context *ctx, const char *fmt, ...) {
+DUK_EXTERNAL duk_ret_t duk_reference_error_stash(duk_hthread *thr, const char *fmt, ...) {
+ DUK_ASSERT_API_ENTRY(thr);
DUK__ERROR_STASH_SHARED(DUK_ERR_REFERENCE_ERROR);
}
-DUK_EXTERNAL duk_ret_t duk_syntax_error_stash(duk_context *ctx, const char *fmt, ...) {
+DUK_EXTERNAL duk_ret_t duk_syntax_error_stash(duk_hthread *thr, const char *fmt, ...) {
+ DUK_ASSERT_API_ENTRY(thr);
DUK__ERROR_STASH_SHARED(DUK_ERR_SYNTAX_ERROR);
}
-DUK_EXTERNAL duk_ret_t duk_type_error_stash(duk_context *ctx, const char *fmt, ...) {
+DUK_EXTERNAL duk_ret_t duk_type_error_stash(duk_hthread *thr, const char *fmt, ...) {
+ DUK_ASSERT_API_ENTRY(thr);
DUK__ERROR_STASH_SHARED(DUK_ERR_TYPE_ERROR);
}
-DUK_EXTERNAL duk_ret_t duk_uri_error_stash(duk_context *ctx, const char *fmt, ...) {
+DUK_EXTERNAL duk_ret_t duk_uri_error_stash(duk_hthread *thr, const char *fmt, ...) {
+ DUK_ASSERT_API_ENTRY(thr);
DUK__ERROR_STASH_SHARED(DUK_ERR_URI_ERROR);
}
#endif /* DUK_USE_VARIADIC_MACROS */
@@ -22227,14 +23275,13 @@ DUK_EXTERNAL duk_ret_t duk_uri_error_stash(duk_context *ctx, const char *fmt, ..
* Comparison
*/
-DUK_EXTERNAL duk_bool_t duk_equals(duk_context *ctx, duk_idx_t idx1, duk_idx_t idx2) {
- duk_hthread *thr = (duk_hthread *) ctx;
+DUK_EXTERNAL duk_bool_t duk_equals(duk_hthread *thr, duk_idx_t idx1, duk_idx_t idx2) {
duk_tval *tv1, *tv2;
- DUK_ASSERT_CTX_VALID(ctx);
+ DUK_ASSERT_API_ENTRY(thr);
- tv1 = duk_get_tval(ctx, idx1);
- tv2 = duk_get_tval(ctx, idx2);
+ tv1 = duk_get_tval(thr, idx1);
+ tv2 = duk_get_tval(thr, idx2);
if ((tv1 == NULL) || (tv2 == NULL)) {
return 0;
}
@@ -22245,13 +23292,13 @@ DUK_EXTERNAL duk_bool_t duk_equals(duk_context *ctx, duk_idx_t idx1, duk_idx_t i
return duk_js_equals(thr, tv1, tv2);
}
-DUK_EXTERNAL duk_bool_t duk_strict_equals(duk_context *ctx, duk_idx_t idx1, duk_idx_t idx2) {
+DUK_EXTERNAL duk_bool_t duk_strict_equals(duk_hthread *thr, duk_idx_t idx1, duk_idx_t idx2) {
duk_tval *tv1, *tv2;
- DUK_ASSERT_CTX_VALID(ctx);
+ DUK_ASSERT_API_ENTRY(thr);
- tv1 = duk_get_tval(ctx, idx1);
- tv2 = duk_get_tval(ctx, idx2);
+ tv1 = duk_get_tval(thr, idx1);
+ tv2 = duk_get_tval(thr, idx2);
if ((tv1 == NULL) || (tv2 == NULL)) {
return 0;
}
@@ -22260,13 +23307,13 @@ DUK_EXTERNAL duk_bool_t duk_strict_equals(duk_context *ctx, duk_idx_t idx1, duk_
return duk_js_strict_equals(tv1, tv2);
}
-DUK_EXTERNAL duk_bool_t duk_samevalue(duk_context *ctx, duk_idx_t idx1, duk_idx_t idx2) {
+DUK_EXTERNAL duk_bool_t duk_samevalue(duk_hthread *thr, duk_idx_t idx1, duk_idx_t idx2) {
duk_tval *tv1, *tv2;
- DUK_ASSERT_CTX_VALID(ctx);
+ DUK_ASSERT_API_ENTRY(thr);
- tv1 = duk_get_tval(ctx, idx1);
- tv2 = duk_get_tval(ctx, idx2);
+ tv1 = duk_get_tval(thr, idx1);
+ tv2 = duk_get_tval(thr, idx2);
if ((tv1 == NULL) || (tv2 == NULL)) {
return 0;
}
@@ -22279,10 +23326,10 @@ DUK_EXTERNAL duk_bool_t duk_samevalue(duk_context *ctx, duk_idx_t idx1, duk_idx_
* instanceof
*/
-DUK_EXTERNAL duk_bool_t duk_instanceof(duk_context *ctx, duk_idx_t idx1, duk_idx_t idx2) {
+DUK_EXTERNAL duk_bool_t duk_instanceof(duk_hthread *thr, duk_idx_t idx1, duk_idx_t idx2) {
duk_tval *tv1, *tv2;
- DUK_ASSERT_CTX_VALID(ctx);
+ DUK_ASSERT_API_ENTRY(thr);
/* Index validation is strict, which differs from duk_equals().
* The strict behavior mimics how instanceof itself works, e.g.
@@ -22290,19 +23337,19 @@ DUK_EXTERNAL duk_bool_t duk_instanceof(duk_context *ctx, duk_idx_t idx1, duk_idx
* be somewhat inconsistent if rval would be allowed to be
* non-existent without a TypeError.
*/
- tv1 = duk_require_tval(ctx, idx1);
+ tv1 = duk_require_tval(thr, idx1);
DUK_ASSERT(tv1 != NULL);
- tv2 = duk_require_tval(ctx, idx2);
+ tv2 = duk_require_tval(thr, idx2);
DUK_ASSERT(tv2 != NULL);
- return duk_js_instanceof((duk_hthread *) ctx, tv1, tv2);
+ return duk_js_instanceof(thr, tv1, tv2);
}
/*
* Lightfunc
*/
-DUK_INTERNAL void duk_push_lightfunc_name_raw(duk_context *ctx, duk_c_function func, duk_small_uint_t lf_flags) {
+DUK_INTERNAL void duk_push_lightfunc_name_raw(duk_hthread *thr, duk_c_function func, duk_small_uint_t lf_flags) {
/* Lightfunc name, includes Duktape/C native function pointer, which
* can often be used to locate the function from a symbol table.
* The name also includes the 16-bit duk_tval flags field because it
@@ -22315,32 +23362,37 @@ DUK_INTERNAL void duk_push_lightfunc_name_raw(duk_context *ctx, duk_c_function f
* is accessed).
*/
- duk_push_sprintf(ctx, "light_");
- duk_push_string_funcptr(ctx, (duk_uint8_t *) &func, sizeof(func));
- duk_push_sprintf(ctx, "_%04x", (unsigned int) lf_flags);
- duk_concat(ctx, 3);
+ DUK_ASSERT_API_ENTRY(thr);
+
+ duk_push_sprintf(thr, "light_");
+ duk_push_string_funcptr(thr, (duk_uint8_t *) &func, sizeof(func));
+ duk_push_sprintf(thr, "_%04x", (unsigned int) lf_flags);
+ duk_concat(thr, 3);
}
-DUK_INTERNAL void duk_push_lightfunc_name(duk_context *ctx, duk_tval *tv) {
+DUK_INTERNAL void duk_push_lightfunc_name(duk_hthread *thr, duk_tval *tv) {
duk_c_function func;
duk_small_uint_t lf_flags;
+ DUK_ASSERT_API_ENTRY(thr);
DUK_ASSERT(DUK_TVAL_IS_LIGHTFUNC(tv));
+
DUK_TVAL_GET_LIGHTFUNC(tv, func, lf_flags);
- duk_push_lightfunc_name_raw(ctx, func, lf_flags);
+ duk_push_lightfunc_name_raw(thr, func, lf_flags);
}
-DUK_INTERNAL void duk_push_lightfunc_tostring(duk_context *ctx, duk_tval *tv) {
+DUK_INTERNAL void duk_push_lightfunc_tostring(duk_hthread *thr, duk_tval *tv) {
duk_c_function func;
duk_small_uint_t lf_flags;
+ DUK_ASSERT_API_ENTRY(thr);
DUK_ASSERT(DUK_TVAL_IS_LIGHTFUNC(tv));
- DUK_TVAL_GET_LIGHTFUNC(tv, func, lf_flags); /* read before 'tv' potentially invalidated */
- duk_push_string(ctx, "function ");
- duk_push_lightfunc_name_raw(ctx, func, lf_flags);
- duk_push_string(ctx, "() { [lightfunc code] }");
- duk_concat(ctx, 3);
+ DUK_TVAL_GET_LIGHTFUNC(tv, func, lf_flags); /* read before 'tv' potentially invalidated */
+ duk_push_string(thr, "function ");
+ duk_push_lightfunc_name_raw(thr, func, lf_flags);
+ duk_push_string(thr, "() { [lightfunc code] }");
+ duk_concat(thr, 3);
}
/*
@@ -22350,12 +23402,13 @@ DUK_INTERNAL void duk_push_lightfunc_tostring(duk_context *ctx, duk_tval *tv) {
* bytes from memory.
*/
-DUK_INTERNAL void duk_push_string_funcptr(duk_context *ctx, duk_uint8_t *ptr, duk_size_t sz) {
+DUK_INTERNAL void duk_push_string_funcptr(duk_hthread *thr, duk_uint8_t *ptr, duk_size_t sz) {
duk_uint8_t buf[32 * 2];
duk_uint8_t *p, *q;
duk_small_uint_t i;
duk_small_uint_t t;
+ DUK_ASSERT_API_ENTRY(thr);
DUK_ASSERT(sz <= 32); /* sanity limit for function pointer size */
p = buf;
@@ -22374,7 +23427,7 @@ DUK_INTERNAL void duk_push_string_funcptr(duk_context *ctx, duk_uint8_t *ptr, du
*p++ = duk_lc_digits[t & 0x0f];
}
- duk_push_lstring(ctx, (const char *) buf, sz * 2);
+ duk_push_lstring(thr, (const char *) buf, sz * 2);
}
/*
@@ -22384,25 +23437,27 @@ DUK_INTERNAL void duk_push_string_funcptr(duk_context *ctx, duk_uint8_t *ptr, du
* and is not intended to be fast (but small and safe).
*/
-#define DUK__READABLE_STRING_MAXCHARS 32
+/* String limits for summary strings. */
+#define DUK__READABLE_SUMMARY_MAXCHARS 96 /* maximum supported by helper */
+#define DUK__READABLE_STRING_MAXCHARS 32 /* for strings/symbols */
+#define DUK__READABLE_ERRMSG_MAXCHARS 96 /* for error messages */
/* String sanitizer which escapes ASCII control characters and a few other
* ASCII characters, passes Unicode as is, and replaces invalid UTF-8 with
* question marks. No errors are thrown for any input string, except in out
* of memory situations.
*/
-DUK_LOCAL void duk__push_hstring_readable_unicode(duk_context *ctx, duk_hstring *h_input) {
- duk_hthread *thr;
+DUK_LOCAL void duk__push_hstring_readable_unicode(duk_hthread *thr, duk_hstring *h_input, duk_small_uint_t maxchars) {
const duk_uint8_t *p, *p_start, *p_end;
- duk_uint8_t buf[DUK_UNICODE_MAX_XUTF8_LENGTH * DUK__READABLE_STRING_MAXCHARS +
+ duk_uint8_t buf[DUK_UNICODE_MAX_XUTF8_LENGTH * DUK__READABLE_SUMMARY_MAXCHARS +
2 /*quotes*/ + 3 /*periods*/];
duk_uint8_t *q;
duk_ucodepoint_t cp;
duk_small_uint_t nchars;
- DUK_ASSERT_CTX_VALID(ctx);
+ DUK_ASSERT_CTX_VALID(thr);
DUK_ASSERT(h_input != NULL);
- thr = (duk_hthread *) ctx;
+ DUK_ASSERT(maxchars <= DUK__READABLE_SUMMARY_MAXCHARS);
p_start = (const duk_uint8_t *) DUK_HSTRING_GET_DATA(h_input);
p_end = p_start + DUK_HSTRING_GET_BYTELEN(h_input);
@@ -22415,7 +23470,7 @@ DUK_LOCAL void duk__push_hstring_readable_unicode(duk_context *ctx, duk_hstring
if (p >= p_end) {
break;
}
- if (nchars == DUK__READABLE_STRING_MAXCHARS) {
+ if (nchars == maxchars) {
*q++ = (duk_uint8_t) DUK_ASC_PERIOD;
*q++ = (duk_uint8_t) DUK_ASC_PERIOD;
*q++ = (duk_uint8_t) DUK_ASC_PERIOD;
@@ -22440,24 +23495,32 @@ DUK_LOCAL void duk__push_hstring_readable_unicode(duk_context *ctx, duk_hstring
}
*q++ = (duk_uint8_t) DUK_ASC_SINGLEQUOTE;
- duk_push_lstring(ctx, (const char *) buf, (duk_size_t) (q - buf));
+ duk_push_lstring(thr, (const char *) buf, (duk_size_t) (q - buf));
}
-DUK_LOCAL const char *duk__push_string_tval_readable(duk_context *ctx, duk_tval *tv, duk_bool_t error_aware) {
- duk_hthread *thr;
-
- DUK_ASSERT_CTX_VALID(ctx);
- thr = (duk_hthread *) ctx;
- DUK_UNREF(thr);
+DUK_LOCAL const char *duk__push_string_tval_readable(duk_hthread *thr, duk_tval *tv, duk_bool_t error_aware) {
+ DUK_ASSERT_CTX_VALID(thr);
/* 'tv' may be NULL */
if (tv == NULL) {
- duk_push_string(ctx, "none");
+ duk_push_string(thr, "none");
} else {
switch (DUK_TVAL_GET_TAG(tv)) {
case DUK_TAG_STRING: {
- /* XXX: symbol support (maybe in summary rework branch) */
- duk__push_hstring_readable_unicode(ctx, DUK_TVAL_GET_STRING(tv));
+ duk_hstring *h = DUK_TVAL_GET_STRING(tv);
+ if (DUK_HSTRING_HAS_SYMBOL(h)) {
+ /* XXX: string summary produces question marks
+ * so this is not very ideal.
+ */
+ duk_push_string(thr, "[Symbol ");
+ duk_push_string(thr, duk__get_symbol_type_string(h));
+ duk_push_string(thr, " ");
+ duk__push_hstring_readable_unicode(thr, h, DUK__READABLE_STRING_MAXCHARS);
+ duk_push_string(thr, "]");
+ duk_concat(thr, 5);
+ break;
+ }
+ duk__push_hstring_readable_unicode(thr, h, DUK__READABLE_STRING_MAXCHARS);
break;
}
case DUK_TAG_OBJECT: {
@@ -22475,16 +23538,15 @@ DUK_LOCAL const char *duk__push_string_tval_readable(duk_context *ctx, duk_tval
*/
duk_tval *tv_msg;
tv_msg = duk_hobject_find_existing_entry_tval_ptr(thr->heap, h, DUK_HTHREAD_STRING_MESSAGE(thr));
- if (tv_msg) {
- /* It's important this summarization is
- * not error aware to avoid unlimited
- * recursion when the .message property
- * is e.g. another error.
+ if (tv_msg != NULL && DUK_TVAL_IS_STRING(tv_msg)) {
+ /* It's critical to avoid recursion so
+ * only summarize a string .message.
*/
- return duk_push_string_tval_readable(ctx, tv_msg);
+ duk__push_hstring_readable_unicode(thr, DUK_TVAL_GET_STRING(tv_msg), DUK__READABLE_ERRMSG_MAXCHARS);
+ break;
}
}
- duk_push_class_string_tval(ctx, tv);
+ duk_push_class_string_tval(thr, tv);
break;
}
case DUK_TAG_BUFFER: {
@@ -22495,49 +23557,51 @@ DUK_LOCAL const char *duk__push_string_tval_readable(duk_context *ctx, duk_tval
/* XXX: Hex encoded, length limited buffer summary here? */
duk_hbuffer *h = DUK_TVAL_GET_BUFFER(tv);
DUK_ASSERT(h != NULL);
- duk_push_sprintf(ctx, "[buffer:%ld]", (long) DUK_HBUFFER_GET_SIZE(h));
+ duk_push_sprintf(thr, "[buffer:%ld]", (long) DUK_HBUFFER_GET_SIZE(h));
break;
}
case DUK_TAG_POINTER: {
/* Surround with parentheses like in JX, ensures NULL pointer
* is distinguishable from null value ("(null)" vs "null").
*/
- duk_push_tval(ctx, tv);
- duk_push_sprintf(ctx, "(%s)", duk_to_string(ctx, -1));
- duk_remove_m2(ctx);
+ duk_push_tval(thr, tv);
+ duk_push_sprintf(thr, "(%s)", duk_to_string(thr, -1));
+ duk_remove_m2(thr);
break;
}
default: {
- duk_push_tval(ctx, tv);
+ duk_push_tval(thr, tv);
break;
}
}
}
- return duk_to_string(ctx, -1);
+ return duk_to_string(thr, -1);
}
-DUK_INTERNAL const char *duk_push_string_tval_readable(duk_context *ctx, duk_tval *tv) {
- DUK_ASSERT_CTX_VALID(ctx);
- return duk__push_string_tval_readable(ctx, tv, 0 /*error_aware*/);
+DUK_INTERNAL const char *duk_push_string_tval_readable(duk_hthread *thr, duk_tval *tv) {
+ DUK_ASSERT_API_ENTRY(thr);
+ return duk__push_string_tval_readable(thr, tv, 0 /*error_aware*/);
}
-DUK_INTERNAL const char *duk_push_string_readable(duk_context *ctx, duk_idx_t idx) {
- DUK_ASSERT_CTX_VALID(ctx);
- return duk_push_string_tval_readable(ctx, duk_get_tval(ctx, idx));
+DUK_INTERNAL const char *duk_push_string_readable(duk_hthread *thr, duk_idx_t idx) {
+ DUK_ASSERT_API_ENTRY(thr);
+ return duk_push_string_tval_readable(thr, duk_get_tval(thr, idx));
}
-DUK_INTERNAL const char *duk_push_string_tval_readable_error(duk_context *ctx, duk_tval *tv) {
- DUK_ASSERT_CTX_VALID(ctx);
- return duk__push_string_tval_readable(ctx, tv, 1 /*error_aware*/);
+DUK_INTERNAL const char *duk_push_string_tval_readable_error(duk_hthread *thr, duk_tval *tv) {
+ DUK_ASSERT_API_ENTRY(thr);
+ return duk__push_string_tval_readable(thr, tv, 1 /*error_aware*/);
}
-DUK_INTERNAL void duk_push_symbol_descriptive_string(duk_context *ctx, duk_hstring *h) {
+DUK_INTERNAL void duk_push_symbol_descriptive_string(duk_hthread *thr, duk_hstring *h) {
const duk_uint8_t *p;
const duk_uint8_t *p_end;
const duk_uint8_t *q;
+ DUK_ASSERT_API_ENTRY(thr);
+
/* .toString() */
- duk_push_string(ctx, "Symbol(");
+ duk_push_string(thr, "Symbol(");
p = (const duk_uint8_t *) DUK_HSTRING_GET_DATA(h);
p_end = p + DUK_HSTRING_GET_BYTELEN(h);
DUK_ASSERT(p[0] == 0xff || (p[0] & 0xc0) == 0x80);
@@ -22552,24 +23616,67 @@ DUK_INTERNAL void duk_push_symbol_descriptive_string(duk_context *ctx, duk_hstri
break;
}
}
- duk_push_lstring(ctx, (const char *) p, (duk_size_t) (q - p));
- duk_push_string(ctx, ")");
- duk_concat(ctx, 3);
+ duk_push_lstring(thr, (const char *) p, (duk_size_t) (q - p));
+ duk_push_string(thr, ")");
+ duk_concat(thr, 3);
+}
+
+/*
+ * Functions
+ */
+
+#if 0 /* not used yet */
+DUK_INTERNAL void duk_push_hnatfunc_name(duk_hthread *thr, duk_hnatfunc *h) {
+ duk_c_function func;
+
+ DUK_ASSERT_API_ENTRY(thr);
+ DUK_ASSERT(h != NULL);
+ DUK_ASSERT(DUK_HOBJECT_IS_NATFUNC((duk_hobject *) h));
+
+ duk_push_sprintf(thr, "native_");
+ func = h->func;
+ duk_push_string_funcptr(thr, (duk_uint8_t *) &func, sizeof(func));
+ duk_push_sprintf(thr, "_%04x_%04x",
+ (unsigned int) (duk_uint16_t) h->nargs,
+ (unsigned int) (duk_uint16_t) h->magic);
+ duk_concat(thr, 3);
+}
+#endif
+
+/*
+ * duk_tval slice copy
+ */
+
+DUK_INTERNAL void duk_copy_tvals_incref(duk_hthread *thr, duk_tval *tv_dst, duk_tval *tv_src, duk_size_t count) {
+ duk_tval *tv;
+
+ DUK_ASSERT_API_ENTRY(thr);
+ DUK_UNREF(thr);
+ DUK_ASSERT(count * sizeof(duk_tval) >= count); /* no wrap */
+ DUK_MEMCPY((void *) tv_dst, (const void *) tv_src, count * sizeof(duk_tval));
+
+ tv = tv_dst;
+ while (count-- > 0) {
+ DUK_TVAL_INCREF(thr, tv);
+ tv++;
+ }
}
/* automatic undefs */
+#undef DUK__ASSERT_SPACE
#undef DUK__CHECK_SPACE
#undef DUK__ERROR_STASH_SHARED
#undef DUK__PACK_ARGS
+#undef DUK__READABLE_ERRMSG_MAXCHARS
#undef DUK__READABLE_STRING_MAXCHARS
+#undef DUK__READABLE_SUMMARY_MAXCHARS
/*
* String manipulation
*/
/* #include duk_internal.h -> already included */
-DUK_LOCAL void duk__concat_and_join_helper(duk_context *ctx, duk_idx_t count_in, duk_bool_t is_join) {
- duk_hthread *thr = (duk_hthread *) ctx;
+DUK_LOCAL void duk__concat_and_join_helper(duk_hthread *thr, duk_idx_t count_in, duk_bool_t is_join) {
duk_uint_t count;
duk_uint_t i;
duk_size_t idx;
@@ -22577,7 +23684,7 @@ DUK_LOCAL void duk__concat_and_join_helper(duk_context *ctx, duk_idx_t count_in,
duk_hstring *h;
duk_uint8_t *buf;
- DUK_ASSERT_CTX_VALID(ctx);
+ DUK_ASSERT_CTX_VALID(thr);
if (DUK_UNLIKELY(count_in <= 0)) {
if (count_in < 0) {
@@ -22585,14 +23692,14 @@ DUK_LOCAL void duk__concat_and_join_helper(duk_context *ctx, duk_idx_t count_in,
return;
}
DUK_ASSERT(count_in == 0);
- duk_push_hstring_empty(ctx);
+ duk_push_hstring_empty(thr);
return;
}
count = (duk_uint_t) count_in;
if (is_join) {
duk_size_t t1, t2, limit;
- h = duk_to_hstring(ctx, -((duk_idx_t) count) - 1);
+ h = duk_to_hstring(thr, -((duk_idx_t) count) - 1);
DUK_ASSERT(h != NULL);
/* A bit tricky overflow test, see doc/code-issues.rst. */
@@ -22610,7 +23717,7 @@ DUK_LOCAL void duk__concat_and_join_helper(duk_context *ctx, duk_idx_t count_in,
for (i = count; i >= 1; i--) {
duk_size_t new_len;
- h = duk_to_hstring(ctx, -((duk_idx_t) i));
+ h = duk_to_hstring(thr, -((duk_idx_t) i));
new_len = len + (duk_size_t) DUK_HSTRING_GET_BYTELEN(h);
/* Impose a string maximum length, need to handle overflow
@@ -22629,7 +23736,7 @@ DUK_LOCAL void duk__concat_and_join_helper(duk_context *ctx, duk_idx_t count_in,
/* Use stack allocated buffer to ensure reachability in errors
* (e.g. intern error).
*/
- buf = (duk_uint8_t *) duk_push_fixed_buffer_nozero(ctx, len);
+ buf = (duk_uint8_t *) duk_push_fixed_buffer_nozero(thr, len);
DUK_ASSERT(buf != NULL);
/* [ ... (sep) str1 str2 ... strN buf ] */
@@ -22637,11 +23744,11 @@ DUK_LOCAL void duk__concat_and_join_helper(duk_context *ctx, duk_idx_t count_in,
idx = 0;
for (i = count; i >= 1; i--) {
if (is_join && i != count) {
- h = duk_require_hstring(ctx, -((duk_idx_t) count) - 2); /* extra -1 for buffer */
+ h = duk_require_hstring(thr, -((duk_idx_t) count) - 2); /* extra -1 for buffer */
DUK_MEMCPY(buf + idx, DUK_HSTRING_GET_DATA(h), DUK_HSTRING_GET_BYTELEN(h));
idx += DUK_HSTRING_GET_BYTELEN(h);
}
- h = duk_require_hstring(ctx, -((duk_idx_t) i) - 1); /* extra -1 for buffer */
+ h = duk_require_hstring(thr, -((duk_idx_t) i) - 1); /* extra -1 for buffer */
DUK_MEMCPY(buf + idx, DUK_HSTRING_GET_DATA(h), DUK_HSTRING_GET_BYTELEN(h));
idx += DUK_HSTRING_GET_BYTELEN(h);
}
@@ -22653,16 +23760,16 @@ DUK_LOCAL void duk__concat_and_join_helper(duk_context *ctx, duk_idx_t count_in,
/* Get rid of the strings early to minimize memory use before intern. */
if (is_join) {
- duk_replace(ctx, -((duk_idx_t) count) - 2); /* overwrite sep */
- duk_pop_n(ctx, count);
+ duk_replace(thr, -((duk_idx_t) count) - 2); /* overwrite sep */
+ duk_pop_n(thr, (duk_idx_t) count);
} else {
- duk_replace(ctx, -((duk_idx_t) count) - 1); /* overwrite str1 */
- duk_pop_n(ctx, count-1);
+ duk_replace(thr, -((duk_idx_t) count) - 1); /* overwrite str1 */
+ duk_pop_n(thr, (duk_idx_t) (count - 1));
}
/* [ ... buf ] */
- (void) duk_buffer_to_string(ctx, -1); /* Safe if inputs are safe. */
+ (void) duk_buffer_to_string(thr, -1); /* Safe if inputs are safe. */
/* [ ... res ] */
return;
@@ -22671,31 +23778,74 @@ DUK_LOCAL void duk__concat_and_join_helper(duk_context *ctx, duk_idx_t count_in,
DUK_ERROR_RANGE(thr, DUK_STR_RESULT_TOO_LONG);
}
-DUK_EXTERNAL void duk_concat(duk_context *ctx, duk_idx_t count) {
- DUK_ASSERT_CTX_VALID(ctx);
+DUK_EXTERNAL void duk_concat(duk_hthread *thr, duk_idx_t count) {
+ DUK_ASSERT_API_ENTRY(thr);
+
+ duk__concat_and_join_helper(thr, count, 0 /*is_join*/);
+}
+
+#if defined(DUK_USE_PREFER_SIZE)
+DUK_INTERNAL void duk_concat_2(duk_hthread *thr) {
+ DUK_ASSERT_API_ENTRY(thr);
+ duk_concat(thr, 2);
+}
+#else /* DUK_USE_PREFER_SIZE */
+DUK_INTERNAL void duk_concat_2(duk_hthread *thr) {
+ duk_hstring *h1;
+ duk_hstring *h2;
+ duk_uint8_t *buf;
+ duk_size_t len1;
+ duk_size_t len2;
+ duk_size_t len;
+
+ DUK_ASSERT_API_ENTRY(thr);
+ DUK_ASSERT(duk_get_top(thr) >= 2); /* Trusted caller. */
+
+ h1 = duk_to_hstring(thr, -2);
+ h2 = duk_to_hstring(thr, -1);
+ len1 = (duk_size_t) DUK_HSTRING_GET_BYTELEN(h1);
+ len2 = (duk_size_t) DUK_HSTRING_GET_BYTELEN(h2);
+ len = len1 + len2;
+ if (DUK_UNLIKELY(len < len1 || /* wrapped */
+ len > (duk_size_t) DUK_HSTRING_MAX_BYTELEN)) {
+ goto error_overflow;
+ }
+ buf = (duk_uint8_t *) duk_push_fixed_buffer_nozero(thr, len);
+ DUK_ASSERT(buf != NULL);
+
+ DUK_MEMCPY((void *) buf, (const void *) DUK_HSTRING_GET_DATA(h1), (size_t) len1);
+ DUK_MEMCPY((void *) (buf + len1), (const void *) DUK_HSTRING_GET_DATA(h2), (size_t) len2);
+ (void) duk_buffer_to_string(thr, -1); /* Safe if inputs are safe. */
+
+ /* [ ... str1 str2 buf ] */
+
+ duk_replace(thr, -3);
+ duk_pop_unsafe(thr);
+ return;
- duk__concat_and_join_helper(ctx, count, 0 /*is_join*/);
+ error_overflow:
+ DUK_ERROR_RANGE(thr, DUK_STR_RESULT_TOO_LONG);
}
+#endif /* DUK_USE_PREFER_SIZE */
-DUK_EXTERNAL void duk_join(duk_context *ctx, duk_idx_t count) {
- DUK_ASSERT_CTX_VALID(ctx);
+DUK_EXTERNAL void duk_join(duk_hthread *thr, duk_idx_t count) {
+ DUK_ASSERT_API_ENTRY(thr);
- duk__concat_and_join_helper(ctx, count, 1 /*is_join*/);
+ duk__concat_and_join_helper(thr, count, 1 /*is_join*/);
}
/* XXX: could map/decode be unified with duk_unicode_support.c code?
* Case conversion needs also the character surroundings though.
*/
-DUK_EXTERNAL void duk_decode_string(duk_context *ctx, duk_idx_t idx, duk_decode_char_function callback, void *udata) {
- duk_hthread *thr = (duk_hthread *) ctx;
+DUK_EXTERNAL void duk_decode_string(duk_hthread *thr, duk_idx_t idx, duk_decode_char_function callback, void *udata) {
duk_hstring *h_input;
const duk_uint8_t *p, *p_start, *p_end;
duk_codepoint_t cp;
- DUK_ASSERT_CTX_VALID(ctx);
+ DUK_ASSERT_API_ENTRY(thr);
- h_input = duk_require_hstring(ctx, idx); /* Accept symbols. */
+ h_input = duk_require_hstring(thr, idx); /* Accept symbols. */
DUK_ASSERT(h_input != NULL);
p_start = (const duk_uint8_t *) DUK_HSTRING_GET_DATA(h_input);
@@ -22711,19 +23861,18 @@ DUK_EXTERNAL void duk_decode_string(duk_context *ctx, duk_idx_t idx, duk_decode_
}
}
-DUK_EXTERNAL void duk_map_string(duk_context *ctx, duk_idx_t idx, duk_map_char_function callback, void *udata) {
- duk_hthread *thr = (duk_hthread *) ctx;
+DUK_EXTERNAL void duk_map_string(duk_hthread *thr, duk_idx_t idx, duk_map_char_function callback, void *udata) {
duk_hstring *h_input;
duk_bufwriter_ctx bw_alloc;
duk_bufwriter_ctx *bw;
const duk_uint8_t *p, *p_start, *p_end;
duk_codepoint_t cp;
- DUK_ASSERT_CTX_VALID(ctx);
+ DUK_ASSERT_API_ENTRY(thr);
- idx = duk_normalize_index(ctx, idx);
+ idx = duk_normalize_index(thr, idx);
- h_input = duk_require_hstring(ctx, idx); /* Accept symbols. */
+ h_input = duk_require_hstring(thr, idx); /* Accept symbols. */
DUK_ASSERT(h_input != NULL);
bw = &bw_alloc;
@@ -22748,22 +23897,21 @@ DUK_EXTERNAL void duk_map_string(duk_context *ctx, duk_idx_t idx, duk_map_char_f
}
DUK_BW_COMPACT(thr, bw);
- (void) duk_buffer_to_string(ctx, -1); /* Safe, extended UTF-8 encoded. */
- duk_replace(ctx, idx);
+ (void) duk_buffer_to_string(thr, -1); /* Safe, extended UTF-8 encoded. */
+ duk_replace(thr, idx);
}
-DUK_EXTERNAL void duk_substring(duk_context *ctx, duk_idx_t idx, duk_size_t start_offset, duk_size_t end_offset) {
- duk_hthread *thr = (duk_hthread *) ctx;
+DUK_EXTERNAL void duk_substring(duk_hthread *thr, duk_idx_t idx, duk_size_t start_offset, duk_size_t end_offset) {
duk_hstring *h;
duk_hstring *res;
duk_size_t start_byte_offset;
duk_size_t end_byte_offset;
duk_size_t charlen;
- DUK_ASSERT_CTX_VALID(ctx);
+ DUK_ASSERT_API_ENTRY(thr);
- idx = duk_require_normalize_index(ctx, idx); /* Accept symbols. */
- h = duk_require_hstring(ctx, idx);
+ idx = duk_require_normalize_index(thr, idx); /* Accept symbols. */
+ h = duk_require_hstring(thr, idx);
DUK_ASSERT(h != NULL);
charlen = DUK_HSTRING_GET_CHARLEN(h);
@@ -22794,24 +23942,23 @@ DUK_EXTERNAL void duk_substring(duk_context *ctx, duk_idx_t idx, duk_size_t star
DUK_HSTRING_GET_DATA(h) + start_byte_offset,
(duk_uint32_t) (end_byte_offset - start_byte_offset));
- duk_push_hstring(ctx, res);
- duk_replace(ctx, idx);
+ duk_push_hstring(thr, res);
+ duk_replace(thr, idx);
}
/* XXX: this is quite clunky. Add Unicode helpers to scan backwards and
* forwards with a callback to process codepoints?
*/
-DUK_EXTERNAL void duk_trim(duk_context *ctx, duk_idx_t idx) {
- duk_hthread *thr = (duk_hthread *) ctx;
+DUK_EXTERNAL void duk_trim(duk_hthread *thr, duk_idx_t idx) {
duk_hstring *h;
const duk_uint8_t *p, *p_start, *p_end, *p_tmp1, *p_tmp2; /* pointers for scanning */
const duk_uint8_t *q_start, *q_end; /* start (incl) and end (excl) of trimmed part */
duk_codepoint_t cp;
- DUK_ASSERT_CTX_VALID(ctx);
+ DUK_ASSERT_API_ENTRY(thr);
- idx = duk_require_normalize_index(ctx, idx); /* Accept symbols. */
- h = duk_require_hstring(ctx, idx);
+ idx = duk_require_normalize_index(thr, idx); /* Accept symbols. */
+ h = duk_require_hstring(thr, idx);
DUK_ASSERT(h != NULL);
p_start = DUK_HSTRING_GET_DATA(h);
@@ -22873,22 +24020,21 @@ DUK_EXTERNAL void duk_trim(duk_context *ctx, duk_idx_t idx) {
return;
}
- duk_push_lstring(ctx, (const char *) q_start, (duk_size_t) (q_end - q_start));
- duk_replace(ctx, idx);
+ duk_push_lstring(thr, (const char *) q_start, (duk_size_t) (q_end - q_start));
+ duk_replace(thr, idx);
}
-DUK_EXTERNAL duk_codepoint_t duk_char_code_at(duk_context *ctx, duk_idx_t idx, duk_size_t char_offset) {
- duk_hthread *thr = (duk_hthread *) ctx;
+DUK_EXTERNAL duk_codepoint_t duk_char_code_at(duk_hthread *thr, duk_idx_t idx, duk_size_t char_offset) {
duk_hstring *h;
duk_ucodepoint_t cp;
- DUK_ASSERT_CTX_VALID(ctx);
+ DUK_ASSERT_API_ENTRY(thr);
/* XXX: Share code with String.prototype.charCodeAt? Main difference
* is handling of clamped offsets.
*/
- h = duk_require_hstring(ctx, idx); /* Accept symbols. */
+ h = duk_require_hstring(thr, idx); /* Accept symbols. */
DUK_ASSERT(h != NULL);
DUK_ASSERT_DISABLE(char_offset >= 0); /* Always true, arg is unsigned. */
@@ -22906,18 +24052,56 @@ DUK_EXTERNAL duk_codepoint_t duk_char_code_at(duk_context *ctx, duk_idx_t idx, d
/* #include duk_internal.h -> already included */
-DUK_EXTERNAL duk_double_t duk_get_now(duk_context *ctx) {
- return ((duk_double_t) DUK_USE_DATE_GET_NOW((ctx)));
+DUK_INTERNAL duk_double_t duk_time_get_ecmascript_time(duk_hthread *thr) {
+ /* Ecmascript time, with millisecond fractions. Exposed via
+ * duk_get_now() for example.
+ */
+ DUK_UNREF(thr);
+ return (duk_double_t) DUK_USE_DATE_GET_NOW(thr);
}
-DUK_EXTERNAL void duk_time_to_components(duk_context *ctx, duk_double_t timeval, duk_time_components *comp) {
+DUK_INTERNAL duk_double_t duk_time_get_ecmascript_time_nofrac(duk_hthread *thr) {
+ /* Ecmascript time without millisecond fractions. Exposed via
+ * the Date built-in which doesn't allow fractions.
+ */
+ DUK_UNREF(thr);
+ return (duk_double_t) DUK_FLOOR(DUK_USE_DATE_GET_NOW(thr));
+}
+
+DUK_INTERNAL duk_double_t duk_time_get_monotonic_time(duk_hthread *thr) {
+ DUK_UNREF(thr);
+#if defined(DUK_USE_GET_MONOTONIC_TIME)
+ return (duk_double_t) DUK_USE_GET_MONOTONIC_TIME(thr);
+#else
+ return (duk_double_t) DUK_USE_DATE_GET_NOW(thr);
+#endif
+}
+
+DUK_EXTERNAL duk_double_t duk_get_now(duk_hthread *thr) {
+ DUK_ASSERT_API_ENTRY(thr);
+ DUK_UNREF(thr);
+
+ /* This API intentionally allows millisecond fractions. */
+ return duk_time_get_ecmascript_time(thr);
+}
+
+#if 0 /* XXX: worth exposing? */
+DUK_EXTERNAL duk_double_t duk_get_monotonic_time(duk_hthread *thr) {
+ DUK_ASSERT_API_ENTRY(thr);
+ DUK_UNREF(thr);
+
+ return duk_time_get_monotonic_time(thr);
+}
+#endif
+
+DUK_EXTERNAL void duk_time_to_components(duk_hthread *thr, duk_double_t timeval, duk_time_components *comp) {
duk_int_t parts[DUK_DATE_IDX_NUM_PARTS];
duk_double_t dparts[DUK_DATE_IDX_NUM_PARTS];
duk_uint_t flags;
- DUK_ASSERT(ctx != NULL);
+ DUK_ASSERT_API_ENTRY(thr);
DUK_ASSERT(comp != NULL); /* XXX: or check? */
- DUK_UNREF(ctx);
+ DUK_UNREF(thr);
/* Convert as one-based, but change month to zero-based to match the
* Ecmascript Date built-in behavior 1:1.
@@ -22926,6 +24110,8 @@ DUK_EXTERNAL void duk_time_to_components(duk_context *ctx, duk_double_t timeval,
duk_bi_date_timeval_to_parts(timeval, parts, dparts, flags);
+ /* XXX: sub-millisecond accuracy for the API */
+
DUK_ASSERT(dparts[DUK_DATE_IDX_MONTH] >= 1.0 && dparts[DUK_DATE_IDX_MONTH] <= 12.0);
comp->year = dparts[DUK_DATE_IDX_YEAR];
comp->month = dparts[DUK_DATE_IDX_MONTH] - 1.0;
@@ -22937,14 +24123,14 @@ DUK_EXTERNAL void duk_time_to_components(duk_context *ctx, duk_double_t timeval,
comp->weekday = dparts[DUK_DATE_IDX_WEEKDAY];
}
-DUK_EXTERNAL duk_double_t duk_components_to_time(duk_context *ctx, duk_time_components *comp) {
+DUK_EXTERNAL duk_double_t duk_components_to_time(duk_hthread *thr, duk_time_components *comp) {
duk_double_t d;
duk_double_t dparts[DUK_DATE_IDX_NUM_PARTS];
duk_uint_t flags;
- DUK_ASSERT(ctx != NULL);
+ DUK_ASSERT_API_ENTRY(thr);
DUK_ASSERT(comp != NULL); /* XXX: or check? */
- DUK_UNREF(ctx);
+ DUK_UNREF(thr);
/* Match Date constructor behavior (with UTC time). Month is given
* as zero-based. Day-of-month is given as one-based so normalize
@@ -23028,27 +24214,27 @@ DUK_EXTERNAL duk_double_t duk_components_to_time(duk_context *ctx, duk_time_comp
* Note that length is left on stack (it could be popped, but that's not
* usually necessary because call handling will clean it up automatically).
*/
-DUK_LOCAL duk_uint32_t duk__push_this_obj_len_u32(duk_context *ctx) {
+DUK_LOCAL duk_uint32_t duk__push_this_obj_len_u32(duk_hthread *thr) {
duk_uint32_t len;
/* XXX: push more directly? */
- (void) duk_push_this_coercible_to_object(ctx);
- DUK_ASSERT_HOBJECT_VALID(duk_get_hobject(ctx, -1));
- duk_get_prop_stridx_short(ctx, -1, DUK_STRIDX_LENGTH);
- len = duk_to_uint32(ctx, -1);
+ (void) duk_push_this_coercible_to_object(thr);
+ DUK_ASSERT_HOBJECT_VALID(duk_get_hobject(thr, -1));
+ duk_get_prop_stridx_short(thr, -1, DUK_STRIDX_LENGTH);
+ len = duk_to_uint32(thr, -1);
/* -> [ ... ToObject(this) ToUint32(length) ] */
return len;
}
-DUK_LOCAL duk_uint32_t duk__push_this_obj_len_u32_limited(duk_context *ctx) {
+DUK_LOCAL duk_uint32_t duk__push_this_obj_len_u32_limited(duk_hthread *thr) {
/* Range limited to [0, 0x7fffffff] range, i.e. range that can be
* represented with duk_int32_t. Use this when the method doesn't
* handle the full 32-bit unsigned range correctly.
*/
- duk_uint32_t ret = duk__push_this_obj_len_u32(ctx);
+ duk_uint32_t ret = duk__push_this_obj_len_u32(thr);
if (DUK_UNLIKELY(ret >= 0x80000000UL)) {
- DUK_ERROR_RANGE_INVALID_LENGTH((duk_hthread *) ctx);
+ DUK_ERROR_RANGE_INVALID_LENGTH(thr);
}
return ret;
}
@@ -23060,13 +24246,11 @@ DUK_LOCAL duk_uint32_t duk__push_this_obj_len_u32_limited(duk_context *ctx) {
* significant fraction to improve performance. Return a non-NULL duk_harray
* pointer when all fast path criteria are met, NULL otherwise.
*/
-DUK_LOCAL duk_harray *duk__arraypart_fastpath_this(duk_context *ctx) {
- duk_hthread *thr;
+DUK_LOCAL duk_harray *duk__arraypart_fastpath_this(duk_hthread *thr) {
duk_tval *tv;
duk_hobject *h;
duk_uint_t flags_mask, flags_bits, flags_value;
- thr = (duk_hthread *) ctx;
DUK_ASSERT(thr->valstack_bottom > thr->valstack); /* because call in progress */
tv = DUK_GET_THIS_TVAL_PTR(thr);
@@ -23115,34 +24299,34 @@ DUK_LOCAL duk_harray *duk__arraypart_fastpath_this(duk_context *ctx) {
* Constructor
*/
-DUK_INTERNAL duk_ret_t duk_bi_array_constructor(duk_context *ctx) {
+DUK_INTERNAL duk_ret_t duk_bi_array_constructor(duk_hthread *thr) {
duk_idx_t nargs;
duk_harray *a;
duk_double_t d;
duk_uint32_t len;
duk_uint32_t len_prealloc;
- nargs = duk_get_top(ctx);
+ nargs = duk_get_top(thr);
- if (nargs == 1 && duk_is_number(ctx, 0)) {
+ if (nargs == 1 && duk_is_number(thr, 0)) {
/* XXX: expensive check (also shared elsewhere - so add a shared internal API call?) */
- d = duk_get_number(ctx, 0);
- len = duk_to_uint32(ctx, 0);
+ d = duk_get_number(thr, 0);
+ len = duk_to_uint32(thr, 0);
if (((duk_double_t) len) != d) {
- DUK_DCERROR_RANGE_INVALID_LENGTH((duk_hthread *) ctx);
+ DUK_DCERROR_RANGE_INVALID_LENGTH(thr);
}
/* For small lengths create a dense preallocated array.
* For large arrays preallocate an initial part.
*/
len_prealloc = len < 64 ? len : 64;
- a = duk_push_harray_with_size(ctx, len_prealloc);
+ a = duk_push_harray_with_size(thr, len_prealloc);
DUK_ASSERT(a != NULL);
a->length = len;
return 1;
}
- duk_pack(ctx, nargs);
+ duk_pack(thr, nargs);
return 1;
}
@@ -23150,11 +24334,11 @@ DUK_INTERNAL duk_ret_t duk_bi_array_constructor(duk_context *ctx) {
* isArray()
*/
-DUK_INTERNAL duk_ret_t duk_bi_array_constructor_is_array(duk_context *ctx) {
+DUK_INTERNAL duk_ret_t duk_bi_array_constructor_is_array(duk_hthread *thr) {
duk_hobject *h;
- h = duk_get_hobject_with_class(ctx, 0, DUK_HOBJECT_CLASS_ARRAY);
- duk_push_boolean(ctx, (h != NULL));
+ h = duk_get_hobject_with_class(thr, 0, DUK_HOBJECT_CLASS_ARRAY);
+ duk_push_boolean(thr, (h != NULL));
return 1;
}
@@ -23162,12 +24346,12 @@ DUK_INTERNAL duk_ret_t duk_bi_array_constructor_is_array(duk_context *ctx) {
* toString()
*/
-DUK_INTERNAL duk_ret_t duk_bi_array_prototype_to_string(duk_context *ctx) {
- (void) duk_push_this_coercible_to_object(ctx);
- duk_get_prop_stridx_short(ctx, -1, DUK_STRIDX_JOIN);
+DUK_INTERNAL duk_ret_t duk_bi_array_prototype_to_string(duk_hthread *thr) {
+ (void) duk_push_this_coercible_to_object(thr);
+ duk_get_prop_stridx_short(thr, -1, DUK_STRIDX_JOIN);
/* [ ... this func ] */
- if (!duk_is_callable(ctx, -1)) {
+ if (!duk_is_callable(thr, -1)) {
/* Fall back to the initial (original) Object.toString(). We don't
* currently have pointers to the built-in functions, only the top
* level global objects (like "Array") so this is now done in a bit
@@ -23179,20 +24363,20 @@ DUK_INTERNAL duk_ret_t duk_bi_array_prototype_to_string(duk_context *ctx) {
* but should have no visible side effects.
*/
DUK_DDD(DUK_DDDPRINT("this.join is not callable, fall back to (original) Object.toString"));
- duk_set_top(ctx, 0);
- return duk_bi_object_prototype_to_string(ctx); /* has access to 'this' binding */
+ duk_set_top(thr, 0);
+ return duk_bi_object_prototype_to_string(thr); /* has access to 'this' binding */
}
/* [ ... this func ] */
- duk_insert(ctx, -2);
+ duk_insert(thr, -2);
/* [ ... func this ] */
DUK_DDD(DUK_DDDPRINT("calling: func=%!iT, this=%!iT",
- (duk_tval *) duk_get_tval(ctx, -2),
- (duk_tval *) duk_get_tval(ctx, -1)));
- duk_call_method(ctx, 0);
+ (duk_tval *) duk_get_tval(thr, -2),
+ (duk_tval *) duk_get_tval(thr, -1)));
+ duk_call_method(thr, 0);
return 1;
}
@@ -23201,7 +24385,7 @@ DUK_INTERNAL duk_ret_t duk_bi_array_prototype_to_string(duk_context *ctx) {
* concat()
*/
-DUK_INTERNAL duk_ret_t duk_bi_array_prototype_concat(duk_context *ctx) {
+DUK_INTERNAL duk_ret_t duk_bi_array_prototype_concat(duk_hthread *thr) {
duk_idx_t i, n;
duk_uarridx_t idx, idx_last;
duk_uarridx_t j, len;
@@ -23212,10 +24396,10 @@ DUK_INTERNAL duk_ret_t duk_bi_array_prototype_concat(duk_context *ctx) {
* (as the element is dup()'d anyway).
*/
- (void) duk_push_this_coercible_to_object(ctx);
- duk_insert(ctx, 0);
- n = duk_get_top(ctx);
- duk_push_array(ctx); /* -> [ ToObject(this) item1 ... itemN arr ] */
+ (void) duk_push_this_coercible_to_object(thr);
+ duk_insert(thr, 0);
+ n = duk_get_top(thr);
+ duk_push_array(thr); /* -> [ ToObject(this) item1 ... itemN arr ] */
/* NOTE: The Array special behaviors are NOT invoked by duk_xdef_prop_index()
* (which differs from the official algorithm). If no error is thrown, this
@@ -23227,14 +24411,14 @@ DUK_INTERNAL duk_ret_t duk_bi_array_prototype_concat(duk_context *ctx) {
idx = 0;
idx_last = 0;
for (i = 0; i < n; i++) {
- DUK_ASSERT_TOP(ctx, n + 1);
+ DUK_ASSERT_TOP(thr, n + 1);
/* [ ToObject(this) item1 ... itemN arr ] */
- duk_dup(ctx, i);
- h = duk_get_hobject_with_class(ctx, -1, DUK_HOBJECT_CLASS_ARRAY);
+ duk_dup(thr, i);
+ h = duk_get_hobject_with_class(thr, -1, DUK_HOBJECT_CLASS_ARRAY);
if (!h) {
- duk_xdef_prop_index_wec(ctx, -2, idx++);
+ duk_xdef_prop_index_wec(thr, -2, idx++);
idx_last = idx;
continue;
}
@@ -23244,15 +24428,15 @@ DUK_INTERNAL duk_ret_t duk_bi_array_prototype_concat(duk_context *ctx) {
/* XXX: an array can have length higher than 32 bits; this is not handled
* correctly now.
*/
- len = (duk_uarridx_t) duk_get_length(ctx, -1);
+ len = (duk_uarridx_t) duk_get_length(thr, -1);
for (j = 0; j < len; j++) {
- if (duk_get_prop_index(ctx, -1, j)) {
+ if (duk_get_prop_index(thr, -1, j)) {
/* [ ToObject(this) item1 ... itemN arr item(i) item(i)[j] ] */
- duk_xdef_prop_index_wec(ctx, -3, idx++);
+ duk_xdef_prop_index_wec(thr, -3, idx++);
idx_last = idx;
} else {
idx++;
- duk_pop(ctx);
+ duk_pop_undefined(thr);
#if defined(DUK_USE_NONSTD_ARRAY_CONCAT_TRAILER)
/* According to E5.1 Section 15.4.4.4 nonexistent trailing
* elements do not affect 'length' of the result. Test262
@@ -23266,17 +24450,17 @@ DUK_INTERNAL duk_ret_t duk_bi_array_prototype_concat(duk_context *ctx) {
#endif
}
}
- duk_pop(ctx);
+ duk_pop_unsafe(thr);
}
/* The E5.1 Section 15.4.4.4 algorithm doesn't set the length explicitly
* in the end, but because we're operating with an internal value which
* is known to be an array, this should be equivalent.
*/
- duk_push_uarridx(ctx, idx_last);
- duk_xdef_prop_stridx_short(ctx, -2, DUK_STRIDX_LENGTH, DUK_PROPDESC_FLAGS_W);
+ duk_push_uarridx(thr, idx_last);
+ duk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_LENGTH, DUK_PROPDESC_FLAGS_W);
- DUK_ASSERT_TOP(ctx, n + 1);
+ DUK_ASSERT_TOP(thr, n + 1);
return 1;
}
@@ -23293,39 +24477,39 @@ DUK_INTERNAL duk_ret_t duk_bi_array_prototype_concat(duk_context *ctx) {
* There is no fancy handling; the prefix gets re-joined multiple times.
*/
-DUK_INTERNAL duk_ret_t duk_bi_array_prototype_join_shared(duk_context *ctx) {
+DUK_INTERNAL duk_ret_t duk_bi_array_prototype_join_shared(duk_hthread *thr) {
duk_uint32_t len, count;
duk_uint32_t idx;
- duk_small_int_t to_locale_string = duk_get_current_magic(ctx);
+ duk_small_int_t to_locale_string = duk_get_current_magic(thr);
duk_idx_t valstack_required;
/* For join(), nargs is 1. For toLocaleString(), nargs is 0 and
* setting the top essentially pushes an undefined to the stack,
* thus defaulting to a comma separator.
*/
- duk_set_top(ctx, 1);
- if (duk_is_undefined(ctx, 0)) {
- duk_pop(ctx);
- duk_push_hstring_stridx(ctx, DUK_STRIDX_COMMA);
+ duk_set_top(thr, 1);
+ if (duk_is_undefined(thr, 0)) {
+ duk_pop_undefined(thr);
+ duk_push_hstring_stridx(thr, DUK_STRIDX_COMMA);
} else {
- duk_to_string(ctx, 0);
+ duk_to_string(thr, 0);
}
- len = duk__push_this_obj_len_u32(ctx);
+ len = duk__push_this_obj_len_u32(thr);
/* [ sep ToObject(this) len ] */
DUK_DDD(DUK_DDDPRINT("sep=%!T, this=%!T, len=%lu",
- (duk_tval *) duk_get_tval(ctx, 0),
- (duk_tval *) duk_get_tval(ctx, 1),
+ (duk_tval *) duk_get_tval(thr, 0),
+ (duk_tval *) duk_get_tval(thr, 1),
(unsigned long) len));
/* The extra (+4) is tight. */
- valstack_required = (len >= DUK__ARRAY_MID_JOIN_LIMIT ?
- DUK__ARRAY_MID_JOIN_LIMIT : len) + 4;
- duk_require_stack(ctx, valstack_required);
+ valstack_required = (duk_idx_t) ((len >= DUK__ARRAY_MID_JOIN_LIMIT ?
+ DUK__ARRAY_MID_JOIN_LIMIT : len) + 4);
+ duk_require_stack(thr, valstack_required);
- duk_dup_0(ctx);
+ duk_dup_0(thr);
/* [ sep ToObject(this) len sep ] */
@@ -23338,9 +24522,9 @@ DUK_INTERNAL duk_ret_t duk_bi_array_prototype_join_shared(duk_context *ctx) {
/* [ sep ToObject(this) len sep str0 ... str(count-1) ] */
DUK_DDD(DUK_DDDPRINT("mid/final join, count=%ld, idx=%ld, len=%ld",
(long) count, (long) idx, (long) len));
- duk_join(ctx, (duk_idx_t) count); /* -> [ sep ToObject(this) len str ] */
- duk_dup_0(ctx); /* -> [ sep ToObject(this) len str sep ] */
- duk_insert(ctx, -2); /* -> [ sep ToObject(this) len sep str ] */
+ duk_join(thr, (duk_idx_t) count); /* -> [ sep ToObject(this) len str ] */
+ duk_dup_0(thr); /* -> [ sep ToObject(this) len str sep ] */
+ duk_insert(thr, -2); /* -> [ sep ToObject(this) len sep str ] */
count = 1;
}
if (idx >= len) {
@@ -23348,18 +24532,18 @@ DUK_INTERNAL duk_ret_t duk_bi_array_prototype_join_shared(duk_context *ctx) {
break;
}
- duk_get_prop_index(ctx, 1, (duk_uarridx_t) idx);
- if (duk_is_null_or_undefined(ctx, -1)) {
- duk_pop(ctx);
- duk_push_hstring_empty(ctx);
+ duk_get_prop_index(thr, 1, (duk_uarridx_t) idx);
+ if (duk_is_null_or_undefined(thr, -1)) {
+ duk_pop_nodecref_unsafe(thr);
+ duk_push_hstring_empty(thr);
} else {
if (to_locale_string) {
- duk_to_object(ctx, -1);
- duk_get_prop_stridx_short(ctx, -1, DUK_STRIDX_TO_LOCALE_STRING);
- duk_insert(ctx, -2); /* -> [ ... toLocaleString ToObject(val) ] */
- duk_call_method(ctx, 0);
+ duk_to_object(thr, -1);
+ duk_get_prop_stridx_short(thr, -1, DUK_STRIDX_TO_LOCALE_STRING);
+ duk_insert(thr, -2); /* -> [ ... toLocaleString ToObject(val) ] */
+ duk_call_method(thr, 0);
}
- duk_to_string(ctx, -1);
+ duk_to_string(thr, -1);
}
count++;
@@ -23376,14 +24560,11 @@ DUK_INTERNAL duk_ret_t duk_bi_array_prototype_join_shared(duk_context *ctx) {
*/
#if defined(DUK_USE_ARRAY_FASTPATH)
-DUK_LOCAL duk_ret_t duk__array_pop_fastpath(duk_context *ctx, duk_harray *h_arr) {
- duk_hthread *thr;
+DUK_LOCAL duk_ret_t duk__array_pop_fastpath(duk_hthread *thr, duk_harray *h_arr) {
duk_tval *tv_arraypart;
duk_tval *tv_val;
duk_uint32_t len;
- thr = (duk_hthread *) ctx;
-
tv_arraypart = DUK_HOBJECT_A_GET_BASE(thr->heap, (duk_hobject *) h_arr);
len = h_arr->length;
if (len <= 0) {
@@ -23419,59 +24600,58 @@ DUK_LOCAL duk_ret_t duk__array_pop_fastpath(duk_context *ctx, duk_harray *h_arr)
}
#endif /* DUK_USE_ARRAY_FASTPATH */
-DUK_INTERNAL duk_ret_t duk_bi_array_prototype_pop(duk_context *ctx) {
+DUK_INTERNAL duk_ret_t duk_bi_array_prototype_pop(duk_hthread *thr) {
duk_uint32_t len;
duk_uint32_t idx;
#if defined(DUK_USE_ARRAY_FASTPATH)
duk_harray *h_arr;
#endif
- DUK_ASSERT_TOP(ctx, 0);
+ DUK_ASSERT_TOP(thr, 0);
#if defined(DUK_USE_ARRAY_FASTPATH)
- h_arr = duk__arraypart_fastpath_this(ctx);
+ h_arr = duk__arraypart_fastpath_this(thr);
if (h_arr) {
- return duk__array_pop_fastpath(ctx, h_arr);
+ return duk__array_pop_fastpath(thr, h_arr);
}
#endif
/* XXX: Merge fastpath check into a related call (push this, coerce length, etc)? */
- len = duk__push_this_obj_len_u32(ctx);
+ len = duk__push_this_obj_len_u32(thr);
if (len == 0) {
- duk_push_int(ctx, 0);
- duk_put_prop_stridx_short(ctx, 0, DUK_STRIDX_LENGTH);
+ duk_push_int(thr, 0);
+ duk_put_prop_stridx_short(thr, 0, DUK_STRIDX_LENGTH);
return 0;
}
idx = len - 1;
- duk_get_prop_index(ctx, 0, (duk_uarridx_t) idx);
- duk_del_prop_index(ctx, 0, (duk_uarridx_t) idx);
- duk_push_u32(ctx, idx);
- duk_put_prop_stridx_short(ctx, 0, DUK_STRIDX_LENGTH);
+ duk_get_prop_index(thr, 0, (duk_uarridx_t) idx);
+ duk_del_prop_index(thr, 0, (duk_uarridx_t) idx);
+ duk_push_u32(thr, idx);
+ duk_put_prop_stridx_short(thr, 0, DUK_STRIDX_LENGTH);
return 1;
}
#if defined(DUK_USE_ARRAY_FASTPATH)
-DUK_LOCAL duk_ret_t duk__array_push_fastpath(duk_context *ctx, duk_harray *h_arr) {
- duk_hthread *thr;
+DUK_LOCAL duk_ret_t duk__array_push_fastpath(duk_hthread *thr, duk_harray *h_arr) {
duk_tval *tv_arraypart;
duk_tval *tv_src;
duk_tval *tv_dst;
duk_uint32_t len;
duk_idx_t i, n;
- thr = (duk_hthread *) ctx;
-
len = h_arr->length;
tv_arraypart = DUK_HOBJECT_A_GET_BASE(thr->heap, (duk_hobject *) h_arr);
n = (duk_idx_t) (thr->valstack_top - thr->valstack_bottom);
- if (DUK_UNLIKELY(len + n < len)) {
+ DUK_ASSERT(n >= 0);
+ DUK_ASSERT((duk_uint32_t) n <= DUK_UINT32_MAX);
+ if (DUK_UNLIKELY(len + (duk_uint32_t) n < len)) {
DUK_D(DUK_DPRINT("Array.prototype.push() would go beyond 32-bit length, throw"));
DUK_DCERROR_RANGE_INVALID_LENGTH(thr); /* != 0 return value returned as is by caller */
}
- if (len + n > DUK_HOBJECT_GET_ASIZE((duk_hobject *) h_arr)) {
+ if (len + (duk_uint32_t) n > DUK_HOBJECT_GET_ASIZE((duk_hobject *) h_arr)) {
/* Array part would need to be extended. Rely on slow path
* for now.
*
@@ -23492,16 +24672,16 @@ DUK_LOCAL duk_ret_t duk__array_push_fastpath(duk_context *ctx, duk_harray *h_arr
tv_dst++;
}
thr->valstack_top = thr->valstack_bottom;
- len += n;
+ len += (duk_uint32_t) n;
h_arr->length = len;
DUK_ASSERT((duk_uint_t) len == len);
- duk_push_uint(ctx, (duk_uint_t) len);
+ duk_push_uint(thr, (duk_uint_t) len);
return 1;
}
#endif /* DUK_USE_ARRAY_FASTPATH */
-DUK_INTERNAL duk_ret_t duk_bi_array_prototype_push(duk_context *ctx) {
+DUK_INTERNAL duk_ret_t duk_bi_array_prototype_push(duk_hthread *thr) {
/* Note: 'this' is not necessarily an Array object. The push()
* algorithm is supposed to work for other kinds of objects too,
* so the algorithm has e.g. an explicit update for the 'length'
@@ -23515,10 +24695,10 @@ DUK_INTERNAL duk_ret_t duk_bi_array_prototype_push(duk_context *ctx) {
#endif
#if defined(DUK_USE_ARRAY_FASTPATH)
- h_arr = duk__arraypart_fastpath_this(ctx);
+ h_arr = duk__arraypart_fastpath_this(thr);
if (h_arr) {
duk_ret_t rc;
- rc = duk__array_push_fastpath(ctx, h_arr);
+ rc = duk__array_push_fastpath(thr, h_arr);
if (rc != 0) {
return rc;
}
@@ -23526,8 +24706,8 @@ DUK_INTERNAL duk_ret_t duk_bi_array_prototype_push(duk_context *ctx) {
}
#endif
- n = duk_get_top(ctx);
- len = duk__push_this_obj_len_u32(ctx);
+ n = duk_get_top(thr);
+ len = duk__push_this_obj_len_u32(thr);
/* [ arg1 ... argN obj length ] */
@@ -23543,18 +24723,18 @@ DUK_INTERNAL duk_ret_t duk_bi_array_prototype_push(duk_context *ctx) {
if (len + (duk_uint32_t) n < len) {
DUK_D(DUK_DPRINT("Array.prototype.push() would go beyond 32-bit length, throw"));
- DUK_DCERROR_RANGE_INVALID_LENGTH((duk_hthread *) ctx);
+ DUK_DCERROR_RANGE_INVALID_LENGTH(thr);
}
for (i = 0; i < n; i++) {
- duk_dup(ctx, i);
- duk_put_prop_index(ctx, -3, len + i);
+ duk_dup(thr, i);
+ duk_put_prop_index(thr, -3, (duk_uarridx_t) (len + (duk_uint32_t) i));
}
- len += n;
+ len += (duk_uint32_t) n;
- duk_push_u32(ctx, len);
- duk_dup_top(ctx);
- duk_put_prop_stridx_short(ctx, -4, DUK_STRIDX_LENGTH);
+ duk_push_u32(thr, len);
+ duk_dup_top(thr);
+ duk_put_prop_stridx_short(thr, -4, DUK_STRIDX_LENGTH);
/* [ arg1 ... argN obj length new_length ] */
return 1;
@@ -23570,7 +24750,7 @@ DUK_INTERNAL duk_ret_t duk_bi_array_prototype_push(duk_context *ctx) {
* may use a negative offset.
*/
-DUK_LOCAL duk_small_int_t duk__array_sort_compare(duk_context *ctx, duk_int_t idx1, duk_int_t idx2) {
+DUK_LOCAL duk_small_int_t duk__array_sort_compare(duk_hthread *thr, duk_int_t idx1, duk_int_t idx2) {
duk_bool_t have1, have2;
duk_bool_t undef1, undef2;
duk_small_int_t ret;
@@ -23599,12 +24779,12 @@ DUK_LOCAL duk_small_int_t duk__array_sort_compare(duk_context *ctx, duk_int_t id
return 0;
}
- have1 = duk_get_prop_index(ctx, idx_obj, (duk_uarridx_t) idx1);
- have2 = duk_get_prop_index(ctx, idx_obj, (duk_uarridx_t) idx2);
+ have1 = duk_get_prop_index(thr, idx_obj, (duk_uarridx_t) idx1);
+ have2 = duk_get_prop_index(thr, idx_obj, (duk_uarridx_t) idx2);
DUK_DDD(DUK_DDDPRINT("duk__array_sort_compare: idx1=%ld, idx2=%ld, have1=%ld, have2=%ld, val1=%!T, val2=%!T",
(long) idx1, (long) idx2, (long) have1, (long) have2,
- (duk_tval *) duk_get_tval(ctx, -2), (duk_tval *) duk_get_tval(ctx, -1)));
+ (duk_tval *) duk_get_tval(thr, -2), (duk_tval *) duk_get_tval(thr, -1)));
if (have1) {
if (have2) {
@@ -23623,8 +24803,8 @@ DUK_LOCAL duk_small_int_t duk__array_sort_compare(duk_context *ctx, duk_int_t id
}
}
- undef1 = duk_is_undefined(ctx, -2);
- undef2 = duk_is_undefined(ctx, -1);
+ undef1 = duk_is_undefined(thr, -2);
+ undef2 = duk_is_undefined(thr, -1);
if (undef1) {
if (undef2) {
ret = 0;
@@ -23642,20 +24822,20 @@ DUK_LOCAL duk_small_int_t duk__array_sort_compare(duk_context *ctx, duk_int_t id
}
}
- if (!duk_is_undefined(ctx, idx_fn)) {
+ if (!duk_is_undefined(thr, idx_fn)) {
duk_double_t d;
/* No need to check callable; duk_call() will do that. */
- duk_dup(ctx, idx_fn); /* -> [ ... x y fn ] */
- duk_insert(ctx, -3); /* -> [ ... fn x y ] */
- duk_call(ctx, 2); /* -> [ ... res ] */
+ duk_dup(thr, idx_fn); /* -> [ ... x y fn ] */
+ duk_insert(thr, -3); /* -> [ ... fn x y ] */
+ duk_call(thr, 2); /* -> [ ... res ] */
/* ES5 is a bit vague about what to do if the return value is
* not a number. ES2015 provides a concrete description:
* http://www.ecma-international.org/ecma-262/6.0/#sec-sortcompare.
*/
- d = duk_to_number_m1(ctx);
+ d = duk_to_number_m1(thr);
if (d < 0.0) {
ret = -1;
} else if (d > 0.0) {
@@ -23667,7 +24847,7 @@ DUK_LOCAL duk_small_int_t duk__array_sort_compare(duk_context *ctx, duk_int_t id
ret = 0;
}
- duk_pop(ctx);
+ duk_pop_nodecref_unsafe(thr);
DUK_DDD(DUK_DDDPRINT("-> result %ld (from comparefn, after coercion)", (long) ret));
return ret;
}
@@ -23675,8 +24855,8 @@ DUK_LOCAL duk_small_int_t duk__array_sort_compare(duk_context *ctx, duk_int_t id
/* string compare is the default (a bit oddly) */
/* XXX: any special handling for plain array; causes repeated coercion now? */
- h1 = duk_to_hstring(ctx, -2);
- h2 = duk_to_hstring_m1(ctx);
+ h1 = duk_to_hstring(thr, -2);
+ h2 = duk_to_hstring_m1(thr);
DUK_ASSERT(h1 != NULL);
DUK_ASSERT(h2 != NULL);
@@ -23684,12 +24864,12 @@ DUK_LOCAL duk_small_int_t duk__array_sort_compare(duk_context *ctx, duk_int_t id
goto pop_ret;
pop_ret:
- duk_pop_2(ctx);
+ duk_pop_2_unsafe(thr);
DUK_DDD(DUK_DDDPRINT("-> result %ld", (long) ret));
return ret;
}
-DUK_LOCAL void duk__array_sort_swap(duk_context *ctx, duk_int_t l, duk_int_t r) {
+DUK_LOCAL void duk__array_sort_swap(duk_hthread *thr, duk_int_t l, duk_int_t r) {
duk_bool_t have_l, have_r;
duk_idx_t idx_obj = 1; /* fixed offset in valstack */
@@ -23698,32 +24878,32 @@ DUK_LOCAL void duk__array_sort_swap(duk_context *ctx, duk_int_t l, duk_int_t r)
}
/* swap elements; deal with non-existent elements correctly */
- have_l = duk_get_prop_index(ctx, idx_obj, (duk_uarridx_t) l);
- have_r = duk_get_prop_index(ctx, idx_obj, (duk_uarridx_t) r);
+ have_l = duk_get_prop_index(thr, idx_obj, (duk_uarridx_t) l);
+ have_r = duk_get_prop_index(thr, idx_obj, (duk_uarridx_t) r);
if (have_r) {
/* right exists, [[Put]] regardless whether or not left exists */
- duk_put_prop_index(ctx, idx_obj, (duk_uarridx_t) l);
+ duk_put_prop_index(thr, idx_obj, (duk_uarridx_t) l);
} else {
- duk_del_prop_index(ctx, idx_obj, (duk_uarridx_t) l);
- duk_pop(ctx);
+ duk_del_prop_index(thr, idx_obj, (duk_uarridx_t) l);
+ duk_pop_undefined(thr);
}
if (have_l) {
- duk_put_prop_index(ctx, idx_obj, (duk_uarridx_t) r);
+ duk_put_prop_index(thr, idx_obj, (duk_uarridx_t) r);
} else {
- duk_del_prop_index(ctx, idx_obj, (duk_uarridx_t) r);
- duk_pop(ctx);
+ duk_del_prop_index(thr, idx_obj, (duk_uarridx_t) r);
+ duk_pop_undefined(thr);
}
}
#if defined(DUK_USE_DEBUG_LEVEL) && (DUK_USE_DEBUG_LEVEL >= 2)
/* Debug print which visualizes the qsort partitioning process. */
-DUK_LOCAL void duk__debuglog_qsort_state(duk_context *ctx, duk_int_t lo, duk_int_t hi, duk_int_t pivot) {
+DUK_LOCAL void duk__debuglog_qsort_state(duk_hthread *thr, duk_int_t lo, duk_int_t hi, duk_int_t pivot) {
char buf[4096];
char *ptr = buf;
duk_int_t i, n;
- n = (duk_int_t) duk_get_length(ctx, 1);
+ n = (duk_int_t) duk_get_length(thr, 1);
if (n > 4000) {
n = 4000;
}
@@ -23749,15 +24929,15 @@ DUK_LOCAL void duk__debuglog_qsort_state(duk_context *ctx, duk_int_t lo, duk_int
}
#endif
-DUK_LOCAL void duk__array_qsort(duk_context *ctx, duk_int_t lo, duk_int_t hi) {
+DUK_LOCAL void duk__array_qsort(duk_hthread *thr, duk_int_t lo, duk_int_t hi) {
duk_int_t p, l, r;
/* The lo/hi indices may be crossed and hi < 0 is possible at entry. */
DUK_DDD(DUK_DDDPRINT("duk__array_qsort: lo=%ld, hi=%ld, obj=%!T",
- (long) lo, (long) hi, (duk_tval *) duk_get_tval(ctx, 1)));
+ (long) lo, (long) hi, (duk_tval *) duk_get_tval(thr, 1)));
- DUK_ASSERT_TOP(ctx, 3);
+ DUK_ASSERT_TOP(thr, 3);
/* In some cases it may be that lo > hi, or hi < 0; these
* degenerate cases happen e.g. for empty arrays, and in
@@ -23773,14 +24953,14 @@ DUK_LOCAL void duk__array_qsort(duk_context *ctx, duk_int_t lo, duk_int_t hi) {
DUK_ASSERT(hi - lo + 1 >= 2);
/* randomized pivot selection */
- p = lo + (duk_int_t) (DUK_UTIL_GET_RANDOM_DOUBLE((duk_hthread *) ctx) * (duk_double_t) (hi - lo + 1));
+ p = lo + (duk_int_t) (DUK_UTIL_GET_RANDOM_DOUBLE(thr) * (duk_double_t) (hi - lo + 1));
DUK_ASSERT(p >= lo && p <= hi);
DUK_DDD(DUK_DDDPRINT("lo=%ld, hi=%ld, chose pivot p=%ld", (long) lo, (long) hi, (long) p));
/* move pivot out of the way */
- duk__array_sort_swap(ctx, p, lo);
+ duk__array_sort_swap(thr, p, lo);
p = lo;
- DUK_DDD(DUK_DDDPRINT("pivot moved out of the way: %!T", (duk_tval *) duk_get_tval(ctx, 1)));
+ DUK_DDD(DUK_DDDPRINT("pivot moved out of the way: %!T", (duk_tval *) duk_get_tval(thr, 1)));
l = lo + 1;
r = hi;
@@ -23792,7 +24972,7 @@ DUK_LOCAL void duk__array_qsort(duk_context *ctx, duk_int_t lo, duk_int_t hi) {
if (l >= hi) {
break;
}
- if (duk__array_sort_compare(ctx, l, p) >= 0) { /* !(l < p) */
+ if (duk__array_sort_compare(thr, l, p) >= 0) { /* !(l < p) */
break;
}
l++;
@@ -23803,7 +24983,7 @@ DUK_LOCAL void duk__array_qsort(duk_context *ctx, duk_int_t lo, duk_int_t hi) {
if (r <= lo) {
break;
}
- if (duk__array_sort_compare(ctx, p, r) >= 0) { /* !(p < r) */
+ if (duk__array_sort_compare(thr, p, r) >= 0) { /* !(p < r) */
break;
}
r--;
@@ -23815,9 +24995,9 @@ DUK_LOCAL void duk__array_qsort(duk_context *ctx, duk_int_t lo, duk_int_t hi) {
DUK_DDD(DUK_DDDPRINT("swap %ld and %ld", (long) l, (long) r));
- duk__array_sort_swap(ctx, l, r);
+ duk__array_sort_swap(thr, l, r);
- DUK_DDD(DUK_DDDPRINT("after swap: %!T", (duk_tval *) duk_get_tval(ctx, 1)));
+ DUK_DDD(DUK_DDDPRINT("after swap: %!T", (duk_tval *) duk_get_tval(thr, 1)));
l++;
r--;
}
@@ -23833,25 +25013,25 @@ DUK_LOCAL void duk__array_qsort(duk_context *ctx, duk_int_t lo, duk_int_t hi) {
*/
/* move pivot to its final place */
- DUK_DDD(DUK_DDDPRINT("before final pivot swap: %!T", (duk_tval *) duk_get_tval(ctx, 1)));
- duk__array_sort_swap(ctx, lo, r);
+ DUK_DDD(DUK_DDDPRINT("before final pivot swap: %!T", (duk_tval *) duk_get_tval(thr, 1)));
+ duk__array_sort_swap(thr, lo, r);
#if defined(DUK_USE_DEBUG_LEVEL) && (DUK_USE_DEBUG_LEVEL >= 2)
- duk__debuglog_qsort_state(ctx, lo, hi, r);
+ duk__debuglog_qsort_state(thr, lo, hi, r);
#endif
- DUK_DDD(DUK_DDDPRINT("recurse: pivot=%ld, obj=%!T", (long) r, (duk_tval *) duk_get_tval(ctx, 1)));
- duk__array_qsort(ctx, lo, r - 1);
- duk__array_qsort(ctx, r + 1, hi);
+ DUK_DDD(DUK_DDDPRINT("recurse: pivot=%ld, obj=%!T", (long) r, (duk_tval *) duk_get_tval(thr, 1)));
+ duk__array_qsort(thr, lo, r - 1);
+ duk__array_qsort(thr, r + 1, hi);
}
-DUK_INTERNAL duk_ret_t duk_bi_array_prototype_sort(duk_context *ctx) {
+DUK_INTERNAL duk_ret_t duk_bi_array_prototype_sort(duk_hthread *thr) {
duk_uint32_t len;
/* XXX: len >= 0x80000000 won't work below because a signed type
* is needed by qsort.
*/
- len = duk__push_this_obj_len_u32_limited(ctx);
+ len = duk__push_this_obj_len_u32_limited(thr);
/* stack[0] = compareFn
* stack[1] = ToObject(this)
@@ -23860,11 +25040,11 @@ DUK_INTERNAL duk_ret_t duk_bi_array_prototype_sort(duk_context *ctx) {
if (len > 0) {
/* avoid degenerate cases, so that (len - 1) won't underflow */
- duk__array_qsort(ctx, (duk_int_t) 0, (duk_int_t) (len - 1));
+ duk__array_qsort(thr, (duk_int_t) 0, (duk_int_t) (len - 1));
}
- DUK_ASSERT_TOP(ctx, 3);
- duk_pop(ctx);
+ DUK_ASSERT_TOP(thr, 3);
+ duk_pop_nodecref_unsafe(thr);
return 1; /* return ToObject(this) */
}
@@ -23881,9 +25061,10 @@ DUK_INTERNAL duk_ret_t duk_bi_array_prototype_sort(duk_context *ctx) {
* unshift is (close to?) <--> splice(0, 0, [items])?
*/
-DUK_INTERNAL duk_ret_t duk_bi_array_prototype_splice(duk_context *ctx) {
+DUK_INTERNAL duk_ret_t duk_bi_array_prototype_splice(duk_hthread *thr) {
duk_idx_t nargs;
- duk_uint32_t len;
+ duk_uint32_t len_u32;
+ duk_int_t len;
duk_bool_t have_delcount;
duk_int_t item_count;
duk_int_t act_start;
@@ -23892,9 +25073,9 @@ DUK_INTERNAL duk_ret_t duk_bi_array_prototype_splice(duk_context *ctx) {
DUK_UNREF(have_delcount);
- nargs = duk_get_top(ctx);
+ nargs = duk_get_top(thr);
if (nargs < 2) {
- duk_set_top(ctx, 2);
+ duk_set_top(thr, 2);
nargs = 2;
have_delcount = 0;
} else {
@@ -23904,18 +25085,20 @@ DUK_INTERNAL duk_ret_t duk_bi_array_prototype_splice(duk_context *ctx) {
/* XXX: len >= 0x80000000 won't work below because we need to be
* able to represent -len.
*/
- len = duk__push_this_obj_len_u32_limited(ctx);
+ len_u32 = duk__push_this_obj_len_u32_limited(thr);
+ len = (duk_int_t) len_u32;
+ DUK_ASSERT(len >= 0);
- act_start = duk_to_int_clamped(ctx, 0, -((duk_int_t) len), (duk_int_t) len);
+ act_start = duk_to_int_clamped(thr, 0, -len, len);
if (act_start < 0) {
act_start = len + act_start;
}
- DUK_ASSERT(act_start >= 0 && act_start <= (duk_int_t) len);
+ DUK_ASSERT(act_start >= 0 && act_start <= len);
#if defined(DUK_USE_NONSTD_ARRAY_SPLICE_DELCOUNT)
if (have_delcount) {
#endif
- del_count = duk_to_int_clamped(ctx, 1, 0, len - act_start);
+ del_count = duk_to_int_clamped(thr, 1, 0, len - act_start);
#if defined(DUK_USE_NONSTD_ARRAY_SPLICE_DELCOUNT)
} else {
/* E5.1 standard behavior when deleteCount is not given would be
@@ -23930,16 +25113,16 @@ DUK_INTERNAL duk_ret_t duk_bi_array_prototype_splice(duk_context *ctx) {
DUK_ASSERT(nargs >= 2);
item_count = (duk_int_t) (nargs - 2);
- DUK_ASSERT(del_count >= 0 && del_count <= (duk_int_t) len - act_start);
- DUK_ASSERT(del_count + act_start <= (duk_int_t) len);
+ DUK_ASSERT(del_count >= 0 && del_count <= len - act_start);
+ DUK_ASSERT(del_count + act_start <= len);
/* For now, restrict result array into 32-bit length range. */
if (((duk_double_t) len) - ((duk_double_t) del_count) + ((duk_double_t) item_count) > (duk_double_t) DUK_UINT32_MAX) {
DUK_D(DUK_DPRINT("Array.prototype.splice() would go beyond 32-bit length, throw"));
- DUK_DCERROR_RANGE_INVALID_LENGTH((duk_hthread *) ctx);
+ DUK_DCERROR_RANGE_INVALID_LENGTH(thr);
}
- duk_push_array(ctx);
+ duk_push_array(thr);
/* stack[0] = start
* stack[1] = deleteCount
@@ -23949,19 +25132,19 @@ DUK_INTERNAL duk_ret_t duk_bi_array_prototype_splice(duk_context *ctx) {
* stack[nargs+2] = result array -1
*/
- DUK_ASSERT_TOP(ctx, nargs + 3);
+ DUK_ASSERT_TOP(thr, nargs + 3);
/* Step 9: copy elements-to-be-deleted into the result array */
for (i = 0; i < del_count; i++) {
- if (duk_get_prop_index(ctx, -3, (duk_uarridx_t) (act_start + i))) {
- duk_xdef_prop_index_wec(ctx, -2, i); /* throw flag irrelevant (false in std alg) */
+ if (duk_get_prop_index(thr, -3, (duk_uarridx_t) (act_start + i))) {
+ duk_xdef_prop_index_wec(thr, -2, (duk_uarridx_t) i); /* throw flag irrelevant (false in std alg) */
} else {
- duk_pop(ctx);
+ duk_pop_undefined(thr);
}
}
- duk_push_u32(ctx, (duk_uint32_t) del_count);
- duk_xdef_prop_stridx_short(ctx, -2, DUK_STRIDX_LENGTH, DUK_PROPDESC_FLAGS_W);
+ duk_push_u32(thr, (duk_uint32_t) del_count);
+ duk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_LENGTH, DUK_PROPDESC_FLAGS_W);
/* Steps 12 and 13: reorganize elements to make room for itemCount elements */
@@ -23972,27 +25155,27 @@ DUK_INTERNAL duk_ret_t duk_bi_array_prototype_splice(duk_context *ctx) {
* [ A B C F G H ] (actual result at this point, C will be replaced)
*/
- DUK_ASSERT_TOP(ctx, nargs + 3);
+ DUK_ASSERT_TOP(thr, nargs + 3);
n = len - del_count;
for (i = act_start; i < n; i++) {
- if (duk_get_prop_index(ctx, -3, (duk_uarridx_t) (i + del_count))) {
- duk_put_prop_index(ctx, -4, (duk_uarridx_t) (i + item_count));
+ if (duk_get_prop_index(thr, -3, (duk_uarridx_t) (i + del_count))) {
+ duk_put_prop_index(thr, -4, (duk_uarridx_t) (i + item_count));
} else {
- duk_pop(ctx);
- duk_del_prop_index(ctx, -3, (duk_uarridx_t) (i + item_count));
+ duk_pop_undefined(thr);
+ duk_del_prop_index(thr, -3, (duk_uarridx_t) (i + item_count));
}
}
- DUK_ASSERT_TOP(ctx, nargs + 3);
+ DUK_ASSERT_TOP(thr, nargs + 3);
/* loop iterator init and limit changed from standard algorithm */
n = len - del_count + item_count;
for (i = len - 1; i >= n; i--) {
- duk_del_prop_index(ctx, -3, (duk_uarridx_t) i);
+ duk_del_prop_index(thr, -3, (duk_uarridx_t) i);
}
- DUK_ASSERT_TOP(ctx, nargs + 3);
+ DUK_ASSERT_TOP(thr, nargs + 3);
} else if (item_count > del_count) {
/* [ A B C D E F G H ] rel_index = 2, del_count 3, item count 4
* -> [ A B F G H ] (conceptual intermediate step)
@@ -24000,19 +25183,19 @@ DUK_INTERNAL duk_ret_t duk_bi_array_prototype_splice(duk_context *ctx) {
* [ A B C D E F F G H ] (actual result at this point)
*/
- DUK_ASSERT_TOP(ctx, nargs + 3);
+ DUK_ASSERT_TOP(thr, nargs + 3);
/* loop iterator init and limit changed from standard algorithm */
for (i = len - del_count - 1; i >= act_start; i--) {
- if (duk_get_prop_index(ctx, -3, (duk_uarridx_t) (i + del_count))) {
- duk_put_prop_index(ctx, -4, (duk_uarridx_t) (i + item_count));
+ if (duk_get_prop_index(thr, -3, (duk_uarridx_t) (i + del_count))) {
+ duk_put_prop_index(thr, -4, (duk_uarridx_t) (i + item_count));
} else {
- duk_pop(ctx);
- duk_del_prop_index(ctx, -3, (duk_uarridx_t) (i + item_count));
+ duk_pop_undefined(thr);
+ duk_del_prop_index(thr, -3, (duk_uarridx_t) (i + item_count));
}
}
- DUK_ASSERT_TOP(ctx, nargs + 3);
+ DUK_ASSERT_TOP(thr, nargs + 3);
} else {
/* [ A B C D E F G H ] rel_index = 2, del_count 3, item count 3
* -> [ A B F G H ] (conceptual intermediate step)
@@ -24020,24 +25203,24 @@ DUK_INTERNAL duk_ret_t duk_bi_array_prototype_splice(duk_context *ctx) {
* [ A B C D E F G H ] (actual result at this point)
*/
}
- DUK_ASSERT_TOP(ctx, nargs + 3);
+ DUK_ASSERT_TOP(thr, nargs + 3);
/* Step 15: insert itemCount elements into the hole made above */
for (i = 0; i < item_count; i++) {
- duk_dup(ctx, i + 2); /* args start at index 2 */
- duk_put_prop_index(ctx, -4, (duk_uarridx_t) (act_start + i));
+ duk_dup(thr, i + 2); /* args start at index 2 */
+ duk_put_prop_index(thr, -4, (duk_uarridx_t) (act_start + i));
}
/* Step 16: update length; note that the final length may be above 32 bit range
* (but we checked above that this isn't the case here)
*/
- duk_push_u32(ctx, len - del_count + item_count);
- duk_put_prop_stridx_short(ctx, -4, DUK_STRIDX_LENGTH);
+ duk_push_u32(thr, (duk_uint32_t) (len - del_count + item_count));
+ duk_put_prop_stridx_short(thr, -4, DUK_STRIDX_LENGTH);
/* result array is already at the top of stack */
- DUK_ASSERT_TOP(ctx, nargs + 3);
+ DUK_ASSERT_TOP(thr, nargs + 3);
return 1;
}
@@ -24045,13 +25228,13 @@ DUK_INTERNAL duk_ret_t duk_bi_array_prototype_splice(duk_context *ctx) {
* reverse()
*/
-DUK_INTERNAL duk_ret_t duk_bi_array_prototype_reverse(duk_context *ctx) {
+DUK_INTERNAL duk_ret_t duk_bi_array_prototype_reverse(duk_hthread *thr) {
duk_uint32_t len;
duk_uint32_t middle;
duk_uint32_t lower, upper;
duk_bool_t have_lower, have_upper;
- len = duk__push_this_obj_len_u32(ctx);
+ len = duk__push_this_obj_len_u32(thr);
middle = len / 2;
/* If len <= 1, middle will be 0 and for-loop bails out
@@ -24060,35 +25243,35 @@ DUK_INTERNAL duk_ret_t duk_bi_array_prototype_reverse(duk_context *ctx) {
for (lower = 0; lower < middle; lower++) {
DUK_ASSERT(len >= 2);
- DUK_ASSERT_TOP(ctx, 2);
+ DUK_ASSERT_TOP(thr, 2);
DUK_ASSERT(len >= lower + 1);
upper = len - lower - 1;
- have_lower = duk_get_prop_index(ctx, -2, (duk_uarridx_t) lower);
- have_upper = duk_get_prop_index(ctx, -3, (duk_uarridx_t) upper);
+ have_lower = duk_get_prop_index(thr, -2, (duk_uarridx_t) lower);
+ have_upper = duk_get_prop_index(thr, -3, (duk_uarridx_t) upper);
/* [ ToObject(this) ToUint32(length) lowerValue upperValue ] */
if (have_upper) {
- duk_put_prop_index(ctx, -4, (duk_uarridx_t) lower);
+ duk_put_prop_index(thr, -4, (duk_uarridx_t) lower);
} else {
- duk_del_prop_index(ctx, -4, (duk_uarridx_t) lower);
- duk_pop(ctx);
+ duk_del_prop_index(thr, -4, (duk_uarridx_t) lower);
+ duk_pop_undefined(thr);
}
if (have_lower) {
- duk_put_prop_index(ctx, -3, (duk_uarridx_t) upper);
+ duk_put_prop_index(thr, -3, (duk_uarridx_t) upper);
} else {
- duk_del_prop_index(ctx, -3, (duk_uarridx_t) upper);
- duk_pop(ctx);
+ duk_del_prop_index(thr, -3, (duk_uarridx_t) upper);
+ duk_pop_undefined(thr);
}
- DUK_ASSERT_TOP(ctx, 2);
+ DUK_ASSERT_TOP(thr, 2);
}
- DUK_ASSERT_TOP(ctx, 2);
- duk_pop(ctx); /* -> [ ToObject(this) ] */
+ DUK_ASSERT_TOP(thr, 2);
+ duk_pop_unsafe(thr); /* -> [ ToObject(this) ] */
return 1;
}
@@ -24096,8 +25279,9 @@ DUK_INTERNAL duk_ret_t duk_bi_array_prototype_reverse(duk_context *ctx) {
* slice()
*/
-DUK_INTERNAL duk_ret_t duk_bi_array_prototype_slice(duk_context *ctx) {
- duk_uint32_t len;
+DUK_INTERNAL duk_ret_t duk_bi_array_prototype_slice(duk_hthread *thr) {
+ duk_uint32_t len_u32;
+ duk_int_t len;
duk_int_t start, end;
duk_int_t i;
duk_uarridx_t idx;
@@ -24106,8 +25290,11 @@ DUK_INTERNAL duk_ret_t duk_bi_array_prototype_slice(duk_context *ctx) {
/* XXX: len >= 0x80000000 won't work below because we need to be
* able to represent -len.
*/
- len = duk__push_this_obj_len_u32_limited(ctx);
- duk_push_array(ctx);
+ len_u32 = duk__push_this_obj_len_u32_limited(thr);
+ len = (duk_int_t) len_u32;
+ DUK_ASSERT(len >= 0);
+
+ duk_push_array(thr);
/* stack[0] = start
* stack[1] = end
@@ -24116,41 +25303,41 @@ DUK_INTERNAL duk_ret_t duk_bi_array_prototype_slice(duk_context *ctx) {
* stack[4] = result array
*/
- start = duk_to_int_clamped(ctx, 0, -((duk_int_t) len), (duk_int_t) len);
+ start = duk_to_int_clamped(thr, 0, -len, len);
if (start < 0) {
start = len + start;
}
/* XXX: could duk_is_undefined() provide defaulting undefined to 'len'
* (the upper limit)?
*/
- if (duk_is_undefined(ctx, 1)) {
+ if (duk_is_undefined(thr, 1)) {
end = len;
} else {
- end = duk_to_int_clamped(ctx, 1, -((duk_int_t) len), (duk_int_t) len);
+ end = duk_to_int_clamped(thr, 1, -len, len);
if (end < 0) {
end = len + end;
}
}
- DUK_ASSERT(start >= 0 && (duk_uint32_t) start <= len);
- DUK_ASSERT(end >= 0 && (duk_uint32_t) end <= len);
+ DUK_ASSERT(start >= 0 && start <= len);
+ DUK_ASSERT(end >= 0 && end <= len);
idx = 0;
for (i = start; i < end; i++) {
- DUK_ASSERT_TOP(ctx, 5);
- if (duk_get_prop_index(ctx, 2, (duk_uarridx_t) i)) {
- duk_xdef_prop_index_wec(ctx, 4, idx);
+ DUK_ASSERT_TOP(thr, 5);
+ if (duk_get_prop_index(thr, 2, (duk_uarridx_t) i)) {
+ duk_xdef_prop_index_wec(thr, 4, idx);
res_length = idx + 1;
} else {
- duk_pop(ctx);
+ duk_pop_undefined(thr);
}
idx++;
- DUK_ASSERT_TOP(ctx, 5);
+ DUK_ASSERT_TOP(thr, 5);
}
- duk_push_u32(ctx, res_length);
- duk_xdef_prop_stridx_short(ctx, 4, DUK_STRIDX_LENGTH, DUK_PROPDESC_FLAGS_W);
+ duk_push_u32(thr, res_length);
+ duk_xdef_prop_stridx_short(thr, 4, DUK_STRIDX_LENGTH, DUK_PROPDESC_FLAGS_W);
- DUK_ASSERT_TOP(ctx, 5);
+ DUK_ASSERT_TOP(thr, 5);
return 1;
}
@@ -24158,18 +25345,18 @@ DUK_INTERNAL duk_ret_t duk_bi_array_prototype_slice(duk_context *ctx) {
* shift()
*/
-DUK_INTERNAL duk_ret_t duk_bi_array_prototype_shift(duk_context *ctx) {
+DUK_INTERNAL duk_ret_t duk_bi_array_prototype_shift(duk_hthread *thr) {
duk_uint32_t len;
duk_uint32_t i;
- len = duk__push_this_obj_len_u32(ctx);
+ len = duk__push_this_obj_len_u32(thr);
if (len == 0) {
- duk_push_int(ctx, 0);
- duk_put_prop_stridx_short(ctx, 0, DUK_STRIDX_LENGTH);
+ duk_push_int(thr, 0);
+ duk_put_prop_stridx_short(thr, 0, DUK_STRIDX_LENGTH);
return 0;
}
- duk_get_prop_index(ctx, 0, 0);
+ duk_get_prop_index(thr, 0, 0);
/* stack[0] = object (this)
* stack[1] = ToUint32(length)
@@ -24177,22 +25364,22 @@ DUK_INTERNAL duk_ret_t duk_bi_array_prototype_shift(duk_context *ctx) {
*/
for (i = 1; i < len; i++) {
- DUK_ASSERT_TOP(ctx, 3);
- if (duk_get_prop_index(ctx, 0, (duk_uarridx_t) i)) {
+ DUK_ASSERT_TOP(thr, 3);
+ if (duk_get_prop_index(thr, 0, (duk_uarridx_t) i)) {
/* fromPresent = true */
- duk_put_prop_index(ctx, 0, (duk_uarridx_t) (i - 1));
+ duk_put_prop_index(thr, 0, (duk_uarridx_t) (i - 1));
} else {
/* fromPresent = false */
- duk_del_prop_index(ctx, 0, (duk_uarridx_t) (i - 1));
- duk_pop(ctx);
+ duk_del_prop_index(thr, 0, (duk_uarridx_t) (i - 1));
+ duk_pop_undefined(thr);
}
}
- duk_del_prop_index(ctx, 0, (duk_uarridx_t) (len - 1));
+ duk_del_prop_index(thr, 0, (duk_uarridx_t) (len - 1));
- duk_push_u32(ctx, (duk_uint32_t) (len - 1));
- duk_put_prop_stridx_short(ctx, 0, DUK_STRIDX_LENGTH);
+ duk_push_u32(thr, (duk_uint32_t) (len - 1));
+ duk_put_prop_stridx_short(thr, 0, DUK_STRIDX_LENGTH);
- DUK_ASSERT_TOP(ctx, 3);
+ DUK_ASSERT_TOP(thr, 3);
return 1;
}
@@ -24200,20 +25387,20 @@ DUK_INTERNAL duk_ret_t duk_bi_array_prototype_shift(duk_context *ctx) {
* unshift()
*/
-DUK_INTERNAL duk_ret_t duk_bi_array_prototype_unshift(duk_context *ctx) {
+DUK_INTERNAL duk_ret_t duk_bi_array_prototype_unshift(duk_hthread *thr) {
duk_idx_t nargs;
duk_uint32_t len;
duk_uint32_t i;
- nargs = duk_get_top(ctx);
- len = duk__push_this_obj_len_u32(ctx);
+ nargs = duk_get_top(thr);
+ len = duk__push_this_obj_len_u32(thr);
/* stack[0...nargs-1] = unshift args (vararg)
* stack[nargs] = ToObject(this)
* stack[nargs+1] = ToUint32(length)
*/
- DUK_ASSERT_TOP(ctx, nargs + 2);
+ DUK_ASSERT_TOP(thr, nargs + 2);
/* Note: unshift() may operate on indices above unsigned 32-bit range
* and the final length may be >= 2**32. However, we restrict the
@@ -24222,39 +25409,39 @@ DUK_INTERNAL duk_ret_t duk_bi_array_prototype_unshift(duk_context *ctx) {
if (len + (duk_uint32_t) nargs < len) {
DUK_D(DUK_DPRINT("Array.prototype.unshift() would go beyond 32-bit length, throw"));
- DUK_DCERROR_RANGE_INVALID_LENGTH((duk_hthread *) ctx);
+ DUK_DCERROR_RANGE_INVALID_LENGTH(thr);
}
i = len;
while (i > 0) {
- DUK_ASSERT_TOP(ctx, nargs + 2);
+ DUK_ASSERT_TOP(thr, nargs + 2);
i--;
/* k+argCount-1; note that may be above 32-bit range */
- if (duk_get_prop_index(ctx, -2, (duk_uarridx_t) i)) {
+ if (duk_get_prop_index(thr, -2, (duk_uarridx_t) i)) {
/* fromPresent = true */
/* [ ... ToObject(this) ToUint32(length) val ] */
- duk_put_prop_index(ctx, -3, (duk_uarridx_t) (i + nargs)); /* -> [ ... ToObject(this) ToUint32(length) ] */
+ duk_put_prop_index(thr, -3, (duk_uarridx_t) (i + (duk_uint32_t) nargs)); /* -> [ ... ToObject(this) ToUint32(length) ] */
} else {
/* fromPresent = false */
/* [ ... ToObject(this) ToUint32(length) val ] */
- duk_pop(ctx);
- duk_del_prop_index(ctx, -2, (duk_uarridx_t) (i + nargs)); /* -> [ ... ToObject(this) ToUint32(length) ] */
+ duk_pop_undefined(thr);
+ duk_del_prop_index(thr, -2, (duk_uarridx_t) (i + (duk_uint32_t) nargs)); /* -> [ ... ToObject(this) ToUint32(length) ] */
}
- DUK_ASSERT_TOP(ctx, nargs + 2);
+ DUK_ASSERT_TOP(thr, nargs + 2);
}
for (i = 0; i < (duk_uint32_t) nargs; i++) {
- DUK_ASSERT_TOP(ctx, nargs + 2);
- duk_dup(ctx, i); /* -> [ ... ToObject(this) ToUint32(length) arg[i] ] */
- duk_put_prop_index(ctx, -3, (duk_uarridx_t) i);
- DUK_ASSERT_TOP(ctx, nargs + 2);
+ DUK_ASSERT_TOP(thr, nargs + 2);
+ duk_dup(thr, (duk_idx_t) i); /* -> [ ... ToObject(this) ToUint32(length) arg[i] ] */
+ duk_put_prop_index(thr, -3, (duk_uarridx_t) i);
+ DUK_ASSERT_TOP(thr, nargs + 2);
}
- DUK_ASSERT_TOP(ctx, nargs + 2);
- duk_push_u32(ctx, len + nargs);
- duk_dup_top(ctx); /* -> [ ... ToObject(this) ToUint32(length) final_len final_len ] */
- duk_put_prop_stridx_short(ctx, -4, DUK_STRIDX_LENGTH);
+ DUK_ASSERT_TOP(thr, nargs + 2);
+ duk_push_u32(thr, len + (duk_uint32_t) nargs);
+ duk_dup_top(thr); /* -> [ ... ToObject(this) ToUint32(length) final_len final_len ] */
+ duk_put_prop_stridx_short(thr, -4, DUK_STRIDX_LENGTH);
return 1;
}
@@ -24262,22 +25449,22 @@ DUK_INTERNAL duk_ret_t duk_bi_array_prototype_unshift(duk_context *ctx) {
* indexOf(), lastIndexOf()
*/
-DUK_INTERNAL duk_ret_t duk_bi_array_prototype_indexof_shared(duk_context *ctx) {
+DUK_INTERNAL duk_ret_t duk_bi_array_prototype_indexof_shared(duk_hthread *thr) {
duk_idx_t nargs;
duk_int_t i, len;
duk_int_t from_idx;
- duk_small_int_t idx_step = duk_get_current_magic(ctx); /* idx_step is +1 for indexOf, -1 for lastIndexOf */
+ duk_small_int_t idx_step = duk_get_current_magic(thr); /* idx_step is +1 for indexOf, -1 for lastIndexOf */
/* lastIndexOf() needs to be a vararg function because we must distinguish
* between an undefined fromIndex and a "not given" fromIndex; indexOf() is
* made vararg for symmetry although it doesn't strictly need to be.
*/
- nargs = duk_get_top(ctx);
- duk_set_top(ctx, 2);
+ nargs = duk_get_top(thr);
+ duk_set_top(thr, 2);
/* XXX: must be able to represent -len */
- len = (duk_int_t) duk__push_this_obj_len_u32_limited(ctx);
+ len = (duk_int_t) duk__push_this_obj_len_u32_limited(thr);
if (len == 0) {
goto not_found;
}
@@ -24304,7 +25491,7 @@ DUK_INTERNAL duk_ret_t duk_bi_array_prototype_indexof_shared(duk_context *ctx) {
* lastIndexOf: clamp fromIndex to [-len - 1, len - 1]
* (if clamped to -len-1 -> fromIndex becomes -1, terminates for-loop directly)
*/
- from_idx = duk_to_int_clamped(ctx,
+ from_idx = duk_to_int_clamped(thr,
1,
(idx_step > 0 ? -len : -len - 1),
(idx_step > 0 ? len : len - 1));
@@ -24330,21 +25517,21 @@ DUK_INTERNAL duk_ret_t duk_bi_array_prototype_indexof_shared(duk_context *ctx) {
*/
for (i = from_idx; i >= 0 && i < len; i += idx_step) {
- DUK_ASSERT_TOP(ctx, 4);
+ DUK_ASSERT_TOP(thr, 4);
- if (duk_get_prop_index(ctx, 2, (duk_uarridx_t) i)) {
- DUK_ASSERT_TOP(ctx, 5);
- if (duk_strict_equals(ctx, 0, 4)) {
- duk_push_int(ctx, i);
+ if (duk_get_prop_index(thr, 2, (duk_uarridx_t) i)) {
+ DUK_ASSERT_TOP(thr, 5);
+ if (duk_strict_equals(thr, 0, 4)) {
+ duk_push_int(thr, i);
return 1;
}
}
- duk_pop(ctx);
+ duk_pop_unsafe(thr);
}
not_found:
- duk_push_int(ctx, -1);
+ duk_push_int(thr, -1);
return 1;
}
@@ -24363,25 +25550,25 @@ DUK_INTERNAL duk_ret_t duk_bi_array_prototype_indexof_shared(duk_context *ctx) {
* 5 callers the net result is about 100 bytes / caller.
*/
-DUK_INTERNAL duk_ret_t duk_bi_array_prototype_iter_shared(duk_context *ctx) {
+DUK_INTERNAL duk_ret_t duk_bi_array_prototype_iter_shared(duk_hthread *thr) {
duk_uint32_t len;
duk_uint32_t i;
duk_uarridx_t k;
duk_bool_t bval;
- duk_small_int_t iter_type = duk_get_current_magic(ctx);
+ duk_small_int_t iter_type = duk_get_current_magic(thr);
duk_uint32_t res_length = 0;
/* each call this helper serves has nargs==2 */
- DUK_ASSERT_TOP(ctx, 2);
+ DUK_ASSERT_TOP(thr, 2);
- len = duk__push_this_obj_len_u32(ctx);
- duk_require_callable(ctx, 0);
+ len = duk__push_this_obj_len_u32(thr);
+ duk_require_callable(thr, 0);
/* if thisArg not supplied, behave as if undefined was supplied */
if (iter_type == DUK__ITER_MAP || iter_type == DUK__ITER_FILTER) {
- duk_push_array(ctx);
+ duk_push_array(thr);
} else {
- duk_push_undefined(ctx);
+ duk_push_undefined(thr);
}
/* stack[0] = callback
@@ -24393,9 +25580,9 @@ DUK_INTERNAL duk_ret_t duk_bi_array_prototype_iter_shared(duk_context *ctx) {
k = 0; /* result index for filter() */
for (i = 0; i < len; i++) {
- DUK_ASSERT_TOP(ctx, 5);
+ DUK_ASSERT_TOP(thr, 5);
- if (!duk_get_prop_index(ctx, 2, (duk_uarridx_t) i)) {
+ if (!duk_get_prop_index(thr, 2, (duk_uarridx_t) i)) {
#if defined(DUK_USE_NONSTD_ARRAY_MAP_TRAILER)
/* Real world behavior for map(): trailing non-existent
* elements don't invoke the user callback, but are still
@@ -24410,7 +25597,7 @@ DUK_INTERNAL duk_ret_t duk_bi_array_prototype_iter_shared(duk_context *ctx) {
* counted towards result 'length'.
*/
#endif
- duk_pop(ctx);
+ duk_pop_undefined(thr);
continue;
}
@@ -24419,23 +25606,23 @@ DUK_INTERNAL duk_ret_t duk_bi_array_prototype_iter_shared(duk_context *ctx) {
* effects.
*/
- duk_dup_0(ctx);
- duk_dup_1(ctx);
- duk_dup_m3(ctx);
- duk_push_u32(ctx, i);
- duk_dup_2(ctx); /* [ ... val callback thisArg val i obj ] */
- duk_call_method(ctx, 3); /* -> [ ... val retval ] */
+ duk_dup_0(thr);
+ duk_dup_1(thr);
+ duk_dup_m3(thr);
+ duk_push_u32(thr, i);
+ duk_dup_2(thr); /* [ ... val callback thisArg val i obj ] */
+ duk_call_method(thr, 3); /* -> [ ... val retval ] */
switch (iter_type) {
case DUK__ITER_EVERY:
- bval = duk_to_boolean(ctx, -1);
+ bval = duk_to_boolean(thr, -1);
if (!bval) {
/* stack top contains 'false' */
return 1;
}
break;
case DUK__ITER_SOME:
- bval = duk_to_boolean(ctx, -1);
+ bval = duk_to_boolean(thr, -1);
if (bval) {
/* stack top contains 'true' */
return 1;
@@ -24445,15 +25632,15 @@ DUK_INTERNAL duk_ret_t duk_bi_array_prototype_iter_shared(duk_context *ctx) {
/* nop */
break;
case DUK__ITER_MAP:
- duk_dup_top(ctx);
- duk_xdef_prop_index_wec(ctx, 4, (duk_uarridx_t) i); /* retval to result[i] */
+ duk_dup_top(thr);
+ duk_xdef_prop_index_wec(thr, 4, (duk_uarridx_t) i); /* retval to result[i] */
res_length = i + 1;
break;
case DUK__ITER_FILTER:
- bval = duk_to_boolean(ctx, -1);
+ bval = duk_to_boolean(thr, -1);
if (bval) {
- duk_dup_m2(ctx); /* orig value */
- duk_xdef_prop_index_wec(ctx, 4, (duk_uarridx_t) k);
+ duk_dup_m2(thr); /* orig value */
+ duk_xdef_prop_index_wec(thr, 4, (duk_uarridx_t) k);
k++;
res_length = k;
}
@@ -24462,27 +25649,27 @@ DUK_INTERNAL duk_ret_t duk_bi_array_prototype_iter_shared(duk_context *ctx) {
DUK_UNREACHABLE();
break;
}
- duk_pop_2(ctx);
+ duk_pop_2_unsafe(thr);
- DUK_ASSERT_TOP(ctx, 5);
+ DUK_ASSERT_TOP(thr, 5);
}
switch (iter_type) {
case DUK__ITER_EVERY:
- duk_push_true(ctx);
+ duk_push_true(thr);
break;
case DUK__ITER_SOME:
- duk_push_false(ctx);
+ duk_push_false(thr);
break;
case DUK__ITER_FOREACH:
- duk_push_undefined(ctx);
+ duk_push_undefined(thr);
break;
case DUK__ITER_MAP:
case DUK__ITER_FILTER:
- DUK_ASSERT_TOP(ctx, 5);
- DUK_ASSERT(duk_is_array(ctx, -1)); /* topmost element is the result array already */
- duk_push_u32(ctx, res_length);
- duk_xdef_prop_stridx_short(ctx, -2, DUK_STRIDX_LENGTH, DUK_PROPDESC_FLAGS_W);
+ DUK_ASSERT_TOP(thr, 5);
+ DUK_ASSERT(duk_is_array(thr, -1)); /* topmost element is the result array already */
+ duk_push_u32(thr, res_length);
+ duk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_LENGTH, DUK_PROPDESC_FLAGS_W);
break;
default:
DUK_UNREACHABLE();
@@ -24496,21 +25683,21 @@ DUK_INTERNAL duk_ret_t duk_bi_array_prototype_iter_shared(duk_context *ctx) {
* reduce(), reduceRight()
*/
-DUK_INTERNAL duk_ret_t duk_bi_array_prototype_reduce_shared(duk_context *ctx) {
+DUK_INTERNAL duk_ret_t duk_bi_array_prototype_reduce_shared(duk_hthread *thr) {
duk_idx_t nargs;
duk_bool_t have_acc;
duk_uint32_t i, len;
- duk_small_int_t idx_step = duk_get_current_magic(ctx); /* idx_step is +1 for reduce, -1 for reduceRight */
+ duk_small_int_t idx_step = duk_get_current_magic(thr); /* idx_step is +1 for reduce, -1 for reduceRight */
/* We're a varargs function because we need to detect whether
* initialValue was given or not.
*/
- nargs = duk_get_top(ctx);
+ nargs = duk_get_top(thr);
DUK_DDD(DUK_DDDPRINT("nargs=%ld", (long) nargs));
- duk_set_top(ctx, 2);
- len = duk__push_this_obj_len_u32(ctx);
- duk_require_callable(ctx, 0);
+ duk_set_top(thr, 2);
+ len = duk__push_this_obj_len_u32(thr);
+ duk_require_callable(thr, 0);
/* stack[0] = callback fn
* stack[1] = initialValue
@@ -24521,11 +25708,11 @@ DUK_INTERNAL duk_ret_t duk_bi_array_prototype_reduce_shared(duk_context *ctx) {
have_acc = 0;
if (nargs >= 2) {
- duk_dup_1(ctx);
+ duk_dup_1(thr);
have_acc = 1;
}
DUK_DDD(DUK_DDDPRINT("have_acc=%ld, acc=%!T",
- (long) have_acc, (duk_tval *) duk_get_tval(ctx, 3)));
+ (long) have_acc, (duk_tval *) duk_get_tval(thr, 3)));
/* For len == 0, i is initialized to len - 1 which underflows.
* The condition (i < len) will then exit the for-loop on the
@@ -24535,47 +25722,47 @@ DUK_INTERNAL duk_ret_t duk_bi_array_prototype_reduce_shared(duk_context *ctx) {
for (i = (idx_step >= 0 ? 0 : len - 1);
i < len; /* i >= 0 would always be true */
- i += idx_step) {
+ i += (duk_uint32_t) idx_step) {
DUK_DDD(DUK_DDDPRINT("i=%ld, len=%ld, have_acc=%ld, top=%ld, acc=%!T",
(long) i, (long) len, (long) have_acc,
- (long) duk_get_top(ctx),
- (duk_tval *) duk_get_tval(ctx, 4)));
+ (long) duk_get_top(thr),
+ (duk_tval *) duk_get_tval(thr, 4)));
- DUK_ASSERT((have_acc && duk_get_top(ctx) == 5) ||
- (!have_acc && duk_get_top(ctx) == 4));
+ DUK_ASSERT((have_acc && duk_get_top(thr) == 5) ||
+ (!have_acc && duk_get_top(thr) == 4));
- if (!duk_has_prop_index(ctx, 2, (duk_uarridx_t) i)) {
+ if (!duk_has_prop_index(thr, 2, (duk_uarridx_t) i)) {
continue;
}
if (!have_acc) {
- DUK_ASSERT_TOP(ctx, 4);
- duk_get_prop_index(ctx, 2, (duk_uarridx_t) i);
+ DUK_ASSERT_TOP(thr, 4);
+ duk_get_prop_index(thr, 2, (duk_uarridx_t) i);
have_acc = 1;
- DUK_ASSERT_TOP(ctx, 5);
+ DUK_ASSERT_TOP(thr, 5);
} else {
- DUK_ASSERT_TOP(ctx, 5);
- duk_dup_0(ctx);
- duk_dup(ctx, 4);
- duk_get_prop_index(ctx, 2, (duk_uarridx_t) i);
- duk_push_u32(ctx, i);
- duk_dup_2(ctx);
+ DUK_ASSERT_TOP(thr, 5);
+ duk_dup_0(thr);
+ duk_dup(thr, 4);
+ duk_get_prop_index(thr, 2, (duk_uarridx_t) i);
+ duk_push_u32(thr, i);
+ duk_dup_2(thr);
DUK_DDD(DUK_DDDPRINT("calling reduce function: func=%!T, prev=%!T, curr=%!T, idx=%!T, obj=%!T",
- (duk_tval *) duk_get_tval(ctx, -5), (duk_tval *) duk_get_tval(ctx, -4),
- (duk_tval *) duk_get_tval(ctx, -3), (duk_tval *) duk_get_tval(ctx, -2),
- (duk_tval *) duk_get_tval(ctx, -1)));
- duk_call(ctx, 4);
- DUK_DDD(DUK_DDDPRINT("-> result: %!T", (duk_tval *) duk_get_tval(ctx, -1)));
- duk_replace(ctx, 4);
- DUK_ASSERT_TOP(ctx, 5);
+ (duk_tval *) duk_get_tval(thr, -5), (duk_tval *) duk_get_tval(thr, -4),
+ (duk_tval *) duk_get_tval(thr, -3), (duk_tval *) duk_get_tval(thr, -2),
+ (duk_tval *) duk_get_tval(thr, -1)));
+ duk_call(thr, 4);
+ DUK_DDD(DUK_DDDPRINT("-> result: %!T", (duk_tval *) duk_get_tval(thr, -1)));
+ duk_replace(thr, 4);
+ DUK_ASSERT_TOP(thr, 5);
}
}
if (!have_acc) {
- DUK_DCERROR_TYPE_INVALID_ARGS((duk_hthread *) ctx);
+ DUK_DCERROR_TYPE_INVALID_ARGS(thr);
}
- DUK_ASSERT_TOP(ctx, 5);
+ DUK_ASSERT_TOP(thr, 5);
return 1;
}
@@ -24599,18 +25786,18 @@ DUK_INTERNAL duk_ret_t duk_bi_array_prototype_reduce_shared(duk_context *ctx) {
/* Shared helper to provide toString() and valueOf(). Checks 'this', gets
* the primitive value to stack top, and optionally coerces with ToString().
*/
-DUK_INTERNAL duk_ret_t duk_bi_boolean_prototype_tostring_shared(duk_context *ctx) {
+DUK_INTERNAL duk_ret_t duk_bi_boolean_prototype_tostring_shared(duk_hthread *thr) {
duk_tval *tv;
duk_hobject *h;
- duk_small_int_t coerce_tostring = duk_get_current_magic(ctx);
+ duk_small_int_t coerce_tostring = duk_get_current_magic(thr);
/* XXX: there is room to use a shared helper here, many built-ins
* check the 'this' type, and if it's an object, check its class,
* then get its internal value, etc.
*/
- duk_push_this(ctx);
- tv = duk_get_tval(ctx, -1);
+ duk_push_this(thr);
+ tv = duk_get_tval(thr, -1);
DUK_ASSERT(tv != NULL);
if (DUK_TVAL_IS_BOOLEAN(tv)) {
@@ -24620,40 +25807,37 @@ DUK_INTERNAL duk_ret_t duk_bi_boolean_prototype_tostring_shared(duk_context *ctx
DUK_ASSERT(h != NULL);
if (DUK_HOBJECT_GET_CLASS_NUMBER(h) == DUK_HOBJECT_CLASS_BOOLEAN) {
- duk_get_prop_stridx_short(ctx, -1, DUK_STRIDX_INT_VALUE);
- DUK_ASSERT(duk_is_boolean(ctx, -1));
+ duk_get_prop_stridx_short(thr, -1, DUK_STRIDX_INT_VALUE);
+ DUK_ASSERT(duk_is_boolean(thr, -1));
goto type_ok;
}
}
- DUK_DCERROR_TYPE_INVALID_ARGS((duk_hthread *) ctx);
+ DUK_DCERROR_TYPE_INVALID_ARGS(thr);
/* never here */
type_ok:
if (coerce_tostring) {
- duk_to_string(ctx, -1);
+ duk_to_string(thr, -1);
}
return 1;
}
-DUK_INTERNAL duk_ret_t duk_bi_boolean_constructor(duk_context *ctx) {
- duk_hthread *thr = (duk_hthread *) ctx;
+DUK_INTERNAL duk_ret_t duk_bi_boolean_constructor(duk_hthread *thr) {
duk_hobject *h_this;
- DUK_UNREF(thr);
+ duk_to_boolean(thr, 0);
- duk_to_boolean(ctx, 0);
-
- if (duk_is_constructor_call(ctx)) {
+ if (duk_is_constructor_call(thr)) {
/* XXX: helper; rely on Boolean.prototype as being non-writable, non-configurable */
- duk_push_this(ctx);
- h_this = duk_known_hobject(ctx, -1);
+ duk_push_this(thr);
+ h_this = duk_known_hobject(thr, -1);
DUK_ASSERT(DUK_HOBJECT_GET_PROTOTYPE(thr->heap, h_this) == thr->builtins[DUK_BIDX_BOOLEAN_PROTOTYPE]);
DUK_HOBJECT_SET_CLASS_NUMBER(h_this, DUK_HOBJECT_CLASS_BOOLEAN);
- duk_dup_0(ctx); /* -> [ val obj val ] */
- duk_xdef_prop_stridx_short(ctx, -2, DUK_STRIDX_INT_VALUE, DUK_PROPDESC_FLAGS_NONE); /* XXX: proper flags? */
+ duk_dup_0(thr); /* -> [ val obj val ] */
+ duk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_INT_VALUE, DUK_PROPDESC_FLAGS_NONE); /* XXX: proper flags? */
} /* unbalanced stack */
return 1;
@@ -24776,21 +25960,19 @@ static duk_uint16_t duk__buffer_elemtype_copy_compatible[9] = {
};
#endif /* !DUK_USE_PREFER_SIZE */
-DUK_LOCAL duk_hbufobj *duk__hbufobj_promote_this(duk_context *ctx) {
- duk_hthread *thr;
+DUK_LOCAL duk_hbufobj *duk__hbufobj_promote_this(duk_hthread *thr) {
duk_tval *tv_dst;
duk_hbufobj *res;
- thr = (duk_hthread *) ctx;
- duk_push_this(ctx);
- DUK_ASSERT(duk_is_buffer(ctx, -1));
- res = (duk_hbufobj *) duk_to_hobject(ctx, -1);
+ duk_push_this(thr);
+ DUK_ASSERT(duk_is_buffer(thr, -1));
+ res = (duk_hbufobj *) duk_to_hobject(thr, -1);
DUK_ASSERT_HBUFOBJ_VALID(res);
- DUK_DD(DUK_DDPRINT("promoted 'this' automatically to an ArrayBuffer: %!iT", duk_get_tval(ctx, -1)));
+ DUK_DD(DUK_DDPRINT("promoted 'this' automatically to an ArrayBuffer: %!iT", duk_get_tval(thr, -1)));
- tv_dst = duk_get_borrowed_this_tval(ctx);
+ tv_dst = duk_get_borrowed_this_tval(thr);
DUK_TVAL_SET_OBJECT_UPDREF(thr, tv_dst, (duk_hobject *) res);
- duk_pop(ctx);
+ duk_pop(thr);
return res;
}
@@ -24802,15 +25984,13 @@ DUK_LOCAL duk_hbufobj *duk__hbufobj_promote_this(duk_context *ctx) {
* always a duk_hbufobj *. Without the flag the return value can also be a
* plain buffer, and the caller must check for it using DUK_HEAPHDR_IS_BUFFER().
*/
-DUK_LOCAL duk_heaphdr *duk__getrequire_bufobj_this(duk_context *ctx, duk_small_uint_t flags) {
- duk_hthread *thr;
+DUK_LOCAL duk_heaphdr *duk__getrequire_bufobj_this(duk_hthread *thr, duk_small_uint_t flags) {
duk_tval *tv;
duk_hbufobj *h_this;
- DUK_ASSERT(ctx != NULL);
- thr = (duk_hthread *) ctx;
+ DUK_ASSERT(thr != NULL);
- tv = duk_get_borrowed_this_tval(ctx);
+ tv = duk_get_borrowed_this_tval(thr);
DUK_ASSERT(tv != NULL);
if (DUK_TVAL_IS_OBJECT(tv)) {
@@ -24829,7 +26009,7 @@ DUK_LOCAL duk_heaphdr *duk__getrequire_bufobj_this(duk_context *ctx, duk_small_u
* support to avoid promotion.
*/
/* XXX: make this conditional to a flag if call sites need it? */
- h_this = duk__hbufobj_promote_this(ctx);
+ h_this = duk__hbufobj_promote_this(thr);
DUK_ASSERT(h_this != NULL);
DUK_ASSERT_HBUFOBJ_VALID(h_this);
return (duk_heaphdr *) h_this;
@@ -24846,29 +26026,26 @@ DUK_LOCAL duk_heaphdr *duk__getrequire_bufobj_this(duk_context *ctx, duk_small_u
}
/* Check that 'this' is a duk_hbufobj and return a pointer to it. */
-DUK_LOCAL duk_hbufobj *duk__get_bufobj_this(duk_context *ctx) {
- return (duk_hbufobj *) duk__getrequire_bufobj_this(ctx, DUK__BUFOBJ_FLAG_PROMOTE);
+DUK_LOCAL duk_hbufobj *duk__get_bufobj_this(duk_hthread *thr) {
+ return (duk_hbufobj *) duk__getrequire_bufobj_this(thr, DUK__BUFOBJ_FLAG_PROMOTE);
}
/* Check that 'this' is a duk_hbufobj and return a pointer to it
* (NULL if not).
*/
-DUK_LOCAL duk_hbufobj *duk__require_bufobj_this(duk_context *ctx) {
- return (duk_hbufobj *) duk__getrequire_bufobj_this(ctx, DUK__BUFOBJ_FLAG_THROW | DUK__BUFOBJ_FLAG_PROMOTE);
+DUK_LOCAL duk_hbufobj *duk__require_bufobj_this(duk_hthread *thr) {
+ return (duk_hbufobj *) duk__getrequire_bufobj_this(thr, DUK__BUFOBJ_FLAG_THROW | DUK__BUFOBJ_FLAG_PROMOTE);
}
/* Check that value is a duk_hbufobj and return a pointer to it. */
-DUK_LOCAL duk_hbufobj *duk__require_bufobj_value(duk_context *ctx, duk_idx_t idx) {
- duk_hthread *thr;
+DUK_LOCAL duk_hbufobj *duk__require_bufobj_value(duk_hthread *thr, duk_idx_t idx) {
duk_tval *tv;
duk_hbufobj *h_obj;
- thr = (duk_hthread *) ctx;
-
/* Don't accept relative indices now. */
DUK_ASSERT(idx >= 0);
- tv = duk_require_tval(ctx, idx);
+ tv = duk_require_tval(thr, idx);
DUK_ASSERT(tv != NULL);
if (DUK_TVAL_IS_OBJECT(tv)) {
h_obj = (duk_hbufobj *) DUK_TVAL_GET_OBJECT(tv);
@@ -24878,7 +26055,7 @@ DUK_LOCAL duk_hbufobj *duk__require_bufobj_value(duk_context *ctx, duk_idx_t idx
return h_obj;
}
} else if (DUK_TVAL_IS_BUFFER(tv)) {
- h_obj = (duk_hbufobj *) duk_to_hobject(ctx, idx);
+ h_obj = (duk_hbufobj *) duk_to_hobject(thr, idx);
DUK_ASSERT(h_obj != NULL);
DUK_ASSERT_HBUFOBJ_VALID(h_obj);
return h_obj;
@@ -24888,17 +26065,13 @@ DUK_LOCAL duk_hbufobj *duk__require_bufobj_value(duk_context *ctx, duk_idx_t idx
return NULL; /* not reachable */
}
-DUK_LOCAL void duk__set_bufobj_buffer(duk_context *ctx, duk_hbufobj *h_bufobj, duk_hbuffer *h_val) {
- duk_hthread *thr;
-
- thr = (duk_hthread *) ctx;
- DUK_UNREF(thr);
-
- DUK_ASSERT(ctx != NULL);
+DUK_LOCAL void duk__set_bufobj_buffer(duk_hthread *thr, duk_hbufobj *h_bufobj, duk_hbuffer *h_val) {
+ DUK_ASSERT(thr != NULL);
DUK_ASSERT(h_bufobj != NULL);
DUK_ASSERT(h_bufobj->buf == NULL); /* no need to decref */
DUK_ASSERT(h_val != NULL);
DUK_ASSERT_HBUFOBJ_VALID(h_bufobj);
+ DUK_UNREF(thr);
h_bufobj->buf = h_val;
DUK_HBUFFER_INCREF(thr, h_val);
@@ -24911,23 +26084,19 @@ DUK_LOCAL void duk__set_bufobj_buffer(duk_context *ctx, duk_hbufobj *h_bufobj, d
}
/* Shared offset/length coercion helper. */
-DUK_LOCAL void duk__resolve_offset_opt_length(duk_context *ctx,
+DUK_LOCAL void duk__resolve_offset_opt_length(duk_hthread *thr,
duk_hbufobj *h_bufarg,
duk_idx_t idx_offset,
duk_idx_t idx_length,
duk_uint_t *out_offset,
duk_uint_t *out_length,
duk_bool_t throw_flag) {
- duk_hthread *thr;
duk_int_t offset_signed;
duk_int_t length_signed;
duk_uint_t offset;
duk_uint_t length;
- thr = (duk_hthread *) ctx;
- DUK_UNREF(thr);
-
- offset_signed = duk_to_int(ctx, idx_offset);
+ offset_signed = duk_to_int(thr, idx_offset);
if (offset_signed < 0) {
goto fail_range;
}
@@ -24938,11 +26107,11 @@ DUK_LOCAL void duk__resolve_offset_opt_length(duk_context *ctx,
DUK_ASSERT_DISABLE(offset >= 0); /* unsigned */
DUK_ASSERT(offset <= h_bufarg->length);
- if (duk_is_undefined(ctx, idx_length)) {
+ if (duk_is_undefined(thr, idx_length)) {
DUK_ASSERT(h_bufarg->length >= offset);
length = h_bufarg->length - offset; /* >= 0 */
} else {
- length_signed = duk_to_int(ctx, idx_length);
+ length_signed = duk_to_int(thr, idx_length);
if (length_signed < 0) {
goto fail_range;
}
@@ -24973,7 +26142,7 @@ DUK_LOCAL void duk__resolve_offset_opt_length(duk_context *ctx,
/* Shared lenient buffer length clamping helper. No negative indices, no
* element/byte shifting.
*/
-DUK_LOCAL void duk__clamp_startend_nonegidx_noshift(duk_context *ctx,
+DUK_LOCAL void duk__clamp_startend_nonegidx_noshift(duk_hthread *thr,
duk_int_t buffer_length,
duk_idx_t idx_start,
duk_idx_t idx_end,
@@ -24986,11 +26155,11 @@ DUK_LOCAL void duk__clamp_startend_nonegidx_noshift(duk_context *ctx,
DUK_ASSERT(out_end_offset != NULL);
/* undefined coerces to zero which is correct */
- start_offset = duk_to_int_clamped(ctx, idx_start, 0, buffer_length);
- if (duk_is_undefined(ctx, idx_end)) {
+ start_offset = duk_to_int_clamped(thr, idx_start, 0, buffer_length);
+ if (duk_is_undefined(thr, idx_end)) {
end_offset = buffer_length;
} else {
- end_offset = duk_to_int_clamped(ctx, idx_end, start_offset, buffer_length);
+ end_offset = duk_to_int_clamped(thr, idx_end, start_offset, buffer_length);
}
DUK_ASSERT(start_offset >= 0);
@@ -25010,7 +26179,7 @@ DUK_LOCAL void duk__clamp_startend_nonegidx_noshift(duk_context *ctx,
* indices are clamped to zero length; and final indices are clamped
* against input slice. Used for e.g. ArrayBuffer slice().
*/
-DUK_LOCAL void duk__clamp_startend_negidx_shifted(duk_context *ctx,
+DUK_LOCAL void duk__clamp_startend_negidx_shifted(duk_hthread *thr,
duk_int_t buffer_length,
duk_uint8_t buffer_shift,
duk_idx_t idx_start,
@@ -25030,14 +26199,14 @@ DUK_LOCAL void duk__clamp_startend_negidx_shifted(duk_context *ctx,
* indices first also avoids potential for wrapping.
*/
- start_offset = duk_to_int(ctx, idx_start);
+ start_offset = duk_to_int(thr, idx_start);
if (start_offset < 0) {
start_offset = buffer_length + start_offset;
}
- if (duk_is_undefined(ctx, idx_end)) {
+ if (duk_is_undefined(thr, idx_end)) {
end_offset = buffer_length;
} else {
- end_offset = duk_to_int(ctx, idx_end);
+ end_offset = duk_to_int(thr, idx_end);
if (end_offset < 0) {
end_offset = buffer_length + end_offset;
}
@@ -25068,45 +26237,41 @@ DUK_LOCAL void duk__clamp_startend_negidx_shifted(duk_context *ctx,
*out_end_offset = end_offset;
}
-DUK_INTERNAL void duk_hbufobj_promote_plain(duk_context *ctx, duk_idx_t idx) {
- if (duk_is_buffer(ctx, idx)) {
- duk_to_object(ctx, idx);
+DUK_INTERNAL void duk_hbufobj_promote_plain(duk_hthread *thr, duk_idx_t idx) {
+ if (duk_is_buffer(thr, idx)) {
+ duk_to_object(thr, idx);
}
}
DUK_INTERNAL void duk_hbufobj_push_uint8array_from_plain(duk_hthread *thr, duk_hbuffer *h_buf) {
- duk_context *ctx;
-
- ctx = (duk_context *) thr;
-
/* Push Uint8Array which will share the same underlying buffer as
* the plain buffer argument. Also create an ArrayBuffer with the
* same backing for the result .buffer property.
*/
- duk_push_hbuffer(ctx, h_buf);
- duk_push_buffer_object(ctx, -1, 0, (duk_size_t) DUK_HBUFFER_GET_SIZE(h_buf), DUK_BUFOBJ_UINT8ARRAY);
- duk_remove_m2(ctx);
+ duk_push_hbuffer(thr, h_buf);
+ duk_push_buffer_object(thr, -1, 0, (duk_size_t) DUK_HBUFFER_GET_SIZE(h_buf), DUK_BUFOBJ_UINT8ARRAY);
+ duk_remove_m2(thr);
#if 0
/* More verbose equivalent; maybe useful if e.g. .buffer is omitted. */
- h_bufobj = duk_push_bufobj_raw(ctx,
+ h_bufobj = duk_push_bufobj_raw(thr,
DUK_HOBJECT_FLAG_EXTENSIBLE |
DUK_HOBJECT_FLAG_BUFOBJ |
DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_UINT8ARRAY),
DUK_BIDX_UINT8ARRAY_PROTOTYPE);
DUK_ASSERT(h_bufobj != NULL);
- duk__set_bufobj_buffer(ctx, h_bufobj, h_buf);
+ duk__set_bufobj_buffer(thr, h_bufobj, h_buf);
h_bufobj->is_typedarray = 1;
DUK_ASSERT_HBUFOBJ_VALID(h_bufobj);
- h_arrbuf = duk_push_bufobj_raw(ctx,
+ h_arrbuf = duk_push_bufobj_raw(thr,
DUK_HOBJECT_FLAG_EXTENSIBLE |
DUK_HOBJECT_FLAG_BUFOBJ |
DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_ARRAYBUFFER),
DUK_BIDX_ARRAYBUFFER_PROTOTYPE);
DUK_ASSERT(h_arrbuf != NULL);
- duk__set_bufobj_buffer(ctx, h_arrbuf, h_buf);
+ duk__set_bufobj_buffer(thr, h_arrbuf, h_buf);
DUK_ASSERT(h_arrbuf->is_typedarray == 0);
DUK_ASSERT_HBUFOBJ_VALID(h_arrbuf);
@@ -25114,12 +26279,12 @@ DUK_INTERNAL void duk_hbufobj_push_uint8array_from_plain(duk_hthread *thr, duk_h
h_bufobj->buf_prop = (duk_hobject *) h_arrbuf;
DUK_ASSERT(h_arrbuf != NULL);
DUK_HBUFOBJ_INCREF(thr, h_arrbuf);
- duk_pop(ctx);
+ duk_pop(thr);
#endif
}
/* Indexed read helper for buffer objects, also called from outside this file. */
-DUK_INTERNAL void duk_hbufobj_push_validated_read(duk_context *ctx, duk_hbufobj *h_bufobj, duk_uint8_t *p, duk_small_uint_t elem_size) {
+DUK_INTERNAL void duk_hbufobj_push_validated_read(duk_hthread *thr, duk_hbufobj *h_bufobj, duk_uint8_t *p, duk_small_uint_t elem_size) {
duk_double_union du;
DUK_MEMCPY((void *) du.uc, (const void *) p, (size_t) elem_size);
@@ -25127,28 +26292,28 @@ DUK_INTERNAL void duk_hbufobj_push_validated_read(duk_context *ctx, duk_hbufobj
switch (h_bufobj->elem_type) {
case DUK_HBUFOBJ_ELEM_UINT8:
case DUK_HBUFOBJ_ELEM_UINT8CLAMPED:
- duk_push_uint(ctx, (duk_uint_t) du.uc[0]);
+ duk_push_uint(thr, (duk_uint_t) du.uc[0]);
break;
case DUK_HBUFOBJ_ELEM_INT8:
- duk_push_int(ctx, (duk_int_t) (duk_int8_t) du.uc[0]);
+ duk_push_int(thr, (duk_int_t) (duk_int8_t) du.uc[0]);
break;
case DUK_HBUFOBJ_ELEM_UINT16:
- duk_push_uint(ctx, (duk_uint_t) du.us[0]);
+ duk_push_uint(thr, (duk_uint_t) du.us[0]);
break;
case DUK_HBUFOBJ_ELEM_INT16:
- duk_push_int(ctx, (duk_int_t) (duk_int16_t) du.us[0]);
+ duk_push_int(thr, (duk_int_t) (duk_int16_t) du.us[0]);
break;
case DUK_HBUFOBJ_ELEM_UINT32:
- duk_push_uint(ctx, (duk_uint_t) du.ui[0]);
+ duk_push_uint(thr, (duk_uint_t) du.ui[0]);
break;
case DUK_HBUFOBJ_ELEM_INT32:
- duk_push_int(ctx, (duk_int_t) (duk_int32_t) du.ui[0]);
+ duk_push_int(thr, (duk_int_t) (duk_int32_t) du.ui[0]);
break;
case DUK_HBUFOBJ_ELEM_FLOAT32:
- duk_push_number(ctx, (duk_double_t) du.f[0]);
+ duk_push_number(thr, (duk_double_t) du.f[0]);
break;
case DUK_HBUFOBJ_ELEM_FLOAT64:
- duk_push_number(ctx, (duk_double_t) du.d);
+ duk_push_number(thr, (duk_double_t) du.d);
break;
default:
DUK_UNREACHABLE();
@@ -25156,7 +26321,7 @@ DUK_INTERNAL void duk_hbufobj_push_validated_read(duk_context *ctx, duk_hbufobj
}
/* Indexed write helper for buffer objects, also called from outside this file. */
-DUK_INTERNAL void duk_hbufobj_validated_write(duk_context *ctx, duk_hbufobj *h_bufobj, duk_uint8_t *p, duk_small_uint_t elem_size) {
+DUK_INTERNAL void duk_hbufobj_validated_write(duk_hthread *thr, duk_hbufobj *h_bufobj, duk_uint8_t *p, duk_small_uint_t elem_size) {
duk_double_union du;
/* NOTE! Caller must ensure that any side effects from the
@@ -25169,31 +26334,31 @@ DUK_INTERNAL void duk_hbufobj_validated_write(duk_context *ctx, duk_hbufobj *h_b
switch (h_bufobj->elem_type) {
case DUK_HBUFOBJ_ELEM_UINT8:
- du.uc[0] = (duk_uint8_t) duk_to_uint32(ctx, -1);
+ du.uc[0] = (duk_uint8_t) duk_to_uint32(thr, -1);
break;
case DUK_HBUFOBJ_ELEM_UINT8CLAMPED:
- du.uc[0] = (duk_uint8_t) duk_to_uint8clamped(ctx, -1);
+ du.uc[0] = (duk_uint8_t) duk_to_uint8clamped(thr, -1);
break;
case DUK_HBUFOBJ_ELEM_INT8:
- du.uc[0] = (duk_uint8_t) duk_to_int32(ctx, -1);
+ du.uc[0] = (duk_uint8_t) duk_to_int32(thr, -1);
break;
case DUK_HBUFOBJ_ELEM_UINT16:
- du.us[0] = (duk_uint16_t) duk_to_uint32(ctx, -1);
+ du.us[0] = (duk_uint16_t) duk_to_uint32(thr, -1);
break;
case DUK_HBUFOBJ_ELEM_INT16:
- du.us[0] = (duk_uint16_t) duk_to_int32(ctx, -1);
+ du.us[0] = (duk_uint16_t) duk_to_int32(thr, -1);
break;
case DUK_HBUFOBJ_ELEM_UINT32:
- du.ui[0] = (duk_uint32_t) duk_to_uint32(ctx, -1);
+ du.ui[0] = (duk_uint32_t) duk_to_uint32(thr, -1);
break;
case DUK_HBUFOBJ_ELEM_INT32:
- du.ui[0] = (duk_uint32_t) duk_to_int32(ctx, -1);
+ du.ui[0] = (duk_uint32_t) duk_to_int32(thr, -1);
break;
case DUK_HBUFOBJ_ELEM_FLOAT32:
- du.f[0] = (duk_float_t) duk_to_number_m1(ctx);
+ du.f[0] = (duk_float_t) duk_to_number_m1(thr);
break;
case DUK_HBUFOBJ_ELEM_FLOAT64:
- du.d = (duk_double_t) duk_to_number_m1(ctx);
+ du.d = (duk_double_t) duk_to_number_m1(thr);
break;
default:
DUK_UNREACHABLE();
@@ -25205,16 +26370,16 @@ DUK_INTERNAL void duk_hbufobj_validated_write(duk_context *ctx, duk_hbufobj *h_b
/* Helper to create a fixed buffer from argument value at index 0.
* Node.js and allocPlain() compatible.
*/
-DUK_LOCAL duk_hbuffer *duk__hbufobj_fixed_from_argvalue(duk_context *ctx) {
+DUK_LOCAL duk_hbuffer *duk__hbufobj_fixed_from_argvalue(duk_hthread *thr) {
duk_int_t len;
duk_int_t i;
duk_size_t buf_size;
duk_uint8_t *buf;
- switch (duk_get_type(ctx, 0)) {
+ switch (duk_get_type(thr, 0)) {
case DUK_TYPE_NUMBER: {
- len = duk_to_int_clamped(ctx, 0, 0, DUK_INT_MAX);
- (void) duk_push_fixed_buffer_zero(ctx, (duk_size_t) len);
+ len = duk_to_int_clamped(thr, 0, 0, DUK_INT_MAX);
+ (void) duk_push_fixed_buffer_zero(thr, (duk_size_t) len);
break;
}
case DUK_TYPE_BUFFER: { /* Treat like Uint8Array. */
@@ -25229,51 +26394,51 @@ DUK_LOCAL duk_hbuffer *duk__hbufobj_fixed_from_argvalue(duk_context *ctx) {
* https://nodejs.org/api/buffer.html#buffer_buffer_from_buffer_alloc_and_buffer_allocunsafe
*/
- h = duk_known_hobject(ctx, 0);
+ h = duk_known_hobject(thr, 0);
if (DUK_HOBJECT_GET_CLASS_NUMBER(h) == DUK_HOBJECT_CLASS_ARRAYBUFFER) {
DUK_ASSERT(DUK_HOBJECT_IS_BUFOBJ(h));
h_bufobj = (duk_hbufobj *) h;
if (DUK_UNLIKELY(h_bufobj->buf == NULL)) {
- DUK_ERROR_TYPE_INVALID_ARGS((duk_hthread *) ctx);
+ DUK_ERROR_TYPE_INVALID_ARGS(thr);
}
if (DUK_UNLIKELY(h_bufobj->offset != 0 || h_bufobj->length != DUK_HBUFFER_GET_SIZE(h_bufobj->buf))) {
/* No support for ArrayBuffers with slice
* offset/length.
*/
- DUK_ERROR_TYPE_INVALID_ARGS((duk_hthread *) ctx);
+ DUK_ERROR_TYPE_INVALID_ARGS(thr);
}
- duk_push_hbuffer(ctx, h_bufobj->buf);
+ duk_push_hbuffer(thr, h_bufobj->buf);
return h_bufobj->buf;
}
goto slow_copy;
}
case DUK_TYPE_STRING: {
/* ignore encoding for now */
- duk_require_hstring_notsymbol(ctx, 0);
- duk_dup_0(ctx);
- (void) duk_to_buffer(ctx, -1, &buf_size);
+ duk_require_hstring_notsymbol(thr, 0);
+ duk_dup_0(thr);
+ (void) duk_to_buffer(thr, -1, &buf_size);
break;
}
default:
- DUK_ERROR_TYPE_INVALID_ARGS((duk_hthread *) ctx);
+ DUK_ERROR_TYPE_INVALID_ARGS(thr);
}
done:
- DUK_ASSERT(duk_is_buffer(ctx, -1));
- return duk_known_hbuffer(ctx, -1);
+ DUK_ASSERT(duk_is_buffer(thr, -1));
+ return duk_known_hbuffer(thr, -1);
slow_copy:
/* XXX: fast path for typed arrays and other buffer objects? */
- (void) duk_get_prop_stridx_short(ctx, 0, DUK_STRIDX_LENGTH);
- len = duk_to_int_clamped(ctx, -1, 0, DUK_INT_MAX);
- duk_pop(ctx);
- buf = (duk_uint8_t *) duk_push_fixed_buffer_nozero(ctx, (duk_size_t) len); /* no zeroing, all indices get initialized */
+ (void) duk_get_prop_stridx_short(thr, 0, DUK_STRIDX_LENGTH);
+ len = duk_to_int_clamped(thr, -1, 0, DUK_INT_MAX);
+ duk_pop(thr);
+ buf = (duk_uint8_t *) duk_push_fixed_buffer_nozero(thr, (duk_size_t) len); /* no zeroing, all indices get initialized */
for (i = 0; i < len; i++) {
/* XXX: fast path for array or buffer arguments? */
- duk_get_prop_index(ctx, 0, (duk_uarridx_t) i);
- buf[i] = (duk_uint8_t) (duk_to_uint32(ctx, -1) & 0xffU);
- duk_pop(ctx);
+ duk_get_prop_index(thr, 0, (duk_uarridx_t) i);
+ buf[i] = (duk_uint8_t) (duk_to_uint32(thr, -1) & 0xffU);
+ duk_pop(thr);
}
goto done;
}
@@ -25288,19 +26453,19 @@ DUK_LOCAL duk_hbuffer *duk__hbufobj_fixed_from_argvalue(duk_context *ctx) {
* constructor entry point is used.
*/
#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)
-DUK_INTERNAL duk_ret_t duk_bi_nodejs_buffer_constructor(duk_context *ctx) {
+DUK_INTERNAL duk_ret_t duk_bi_nodejs_buffer_constructor(duk_hthread *thr) {
duk_hbuffer *h_buf;
- h_buf = duk__hbufobj_fixed_from_argvalue(ctx);
+ h_buf = duk__hbufobj_fixed_from_argvalue(thr);
DUK_ASSERT(h_buf != NULL);
- duk_push_buffer_object(ctx,
+ duk_push_buffer_object(thr,
-1,
0,
DUK_HBUFFER_FIXED_GET_SIZE((duk_hbuffer_fixed *) h_buf),
DUK_BUFOBJ_UINT8ARRAY);
- duk_push_hobject_bidx(ctx, DUK_BIDX_NODEJS_BUFFER_PROTOTYPE);
- duk_set_prototype(ctx, -2);
+ duk_push_hobject_bidx(thr, DUK_BIDX_NODEJS_BUFFER_PROTOTYPE);
+ duk_set_prototype(thr, -2);
/* XXX: a more direct implementation */
@@ -25313,33 +26478,30 @@ DUK_INTERNAL duk_ret_t duk_bi_nodejs_buffer_constructor(duk_context *ctx) {
*/
#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)
-DUK_INTERNAL duk_ret_t duk_bi_arraybuffer_constructor(duk_context *ctx) {
- duk_hthread *thr;
+DUK_INTERNAL duk_ret_t duk_bi_arraybuffer_constructor(duk_hthread *thr) {
duk_hbufobj *h_bufobj;
duk_hbuffer *h_val;
duk_int_t len;
- DUK_ASSERT_CTX_VALID(ctx);
- thr = (duk_hthread *) ctx;
- DUK_UNREF(thr);
+ DUK_ASSERT_CTX_VALID(thr);
- duk_require_constructor_call(ctx);
+ duk_require_constructor_call(thr);
- len = duk_to_int(ctx, 0);
+ len = duk_to_int(thr, 0);
if (len < 0) {
goto fail_length;
}
- (void) duk_push_fixed_buffer_zero(ctx, (duk_size_t) len);
- h_val = (duk_hbuffer *) duk_known_hbuffer(ctx, -1);
+ (void) duk_push_fixed_buffer_zero(thr, (duk_size_t) len);
+ h_val = (duk_hbuffer *) duk_known_hbuffer(thr, -1);
- h_bufobj = duk_push_bufobj_raw(ctx,
+ h_bufobj = duk_push_bufobj_raw(thr,
DUK_HOBJECT_FLAG_EXTENSIBLE |
DUK_HOBJECT_FLAG_BUFOBJ |
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);
+ duk__set_bufobj_buffer(thr, h_bufobj, h_val);
DUK_ASSERT_HBUFOBJ_VALID(h_bufobj);
return 1;
@@ -25358,8 +26520,7 @@ DUK_INTERNAL duk_ret_t duk_bi_arraybuffer_constructor(duk_context *ctx) {
*/
#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)
-DUK_INTERNAL duk_ret_t duk_bi_typedarray_constructor(duk_context *ctx) {
- duk_hthread *thr;
+DUK_INTERNAL duk_ret_t duk_bi_typedarray_constructor(duk_hthread *thr) {
duk_tval *tv;
duk_hobject *h_obj;
duk_hbufobj *h_bufobj = NULL;
@@ -25377,24 +26538,21 @@ DUK_INTERNAL duk_ret_t duk_bi_typedarray_constructor(duk_context *ctx) {
duk_uint_t byte_length;
duk_small_uint_t copy_mode;
- thr = (duk_hthread *) ctx;
- DUK_UNREF(thr);
-
/* XXX: The same copy helpers could be shared with at least some
* buffer functions.
*/
- duk_require_constructor_call(ctx);
+ duk_require_constructor_call(thr);
/* We could fit built-in index into magic but that'd make the magic
* number dependent on built-in numbering (genbuiltins.py doesn't
* handle that yet). So map both class and prototype from the
* element type.
*/
- magic = duk_get_current_magic(ctx);
- shift = magic & 0x03; /* bits 0...1: shift */
- elem_type = (magic >> 2) & 0x0f; /* bits 2...5: type */
- elem_size = 1 << shift;
+ magic = (duk_small_uint_t) duk_get_current_magic(thr);
+ shift = magic & 0x03U; /* bits 0...1: shift */
+ elem_type = (magic >> 2) & 0x0fU; /* bits 2...5: type */
+ elem_size = 1U << shift;
align_mask = elem_size - 1;
DUK_ASSERT(elem_type < sizeof(duk__buffer_proto_from_elemtype) / sizeof(duk_uint8_t));
proto_bidx = duk__buffer_proto_from_elemtype[elem_type];
@@ -25416,9 +26574,9 @@ DUK_INTERNAL duk_ret_t duk_bi_typedarray_constructor(duk_context *ctx) {
* coerce to an ArrayBuffer object and use that as .buffer. The underlying
* buffer will be the same but result .buffer !== inputPlainBuffer.
*/
- duk_hbufobj_promote_plain(ctx, 0);
+ duk_hbufobj_promote_plain(thr, 0);
- tv = duk_get_tval(ctx, 0);
+ tv = duk_get_tval(thr, 0);
DUK_ASSERT(tv != NULL); /* arg count */
if (DUK_TVAL_IS_OBJECT(tv)) {
h_obj = DUK_TVAL_GET_OBJECT(tv);
@@ -25434,7 +26592,7 @@ DUK_INTERNAL duk_ret_t duk_bi_typedarray_constructor(duk_context *ctx) {
h_bufarg = (duk_hbufobj *) h_obj;
- byte_offset_signed = duk_to_int(ctx, 1);
+ byte_offset_signed = duk_to_int(thr, 1);
if (byte_offset_signed < 0) {
goto fail_arguments;
}
@@ -25444,7 +26602,7 @@ DUK_INTERNAL duk_ret_t duk_bi_typedarray_constructor(duk_context *ctx) {
/* Must be >= 0 and multiple of element size. */
goto fail_arguments;
}
- if (duk_is_undefined(ctx, 2)) {
+ if (duk_is_undefined(thr, 2)) {
DUK_ASSERT(h_bufarg->length >= byte_offset);
byte_length = h_bufarg->length - byte_offset;
if ((byte_length & align_mask) != 0) {
@@ -25455,7 +26613,7 @@ DUK_INTERNAL duk_ret_t duk_bi_typedarray_constructor(duk_context *ctx) {
}
elem_length = (byte_length >> shift);
} else {
- elem_length_signed = duk_to_int(ctx, 2);
+ elem_length_signed = duk_to_int(thr, 2);
if (elem_length_signed < 0) {
goto fail_arguments;
}
@@ -25479,11 +26637,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_bufobj_raw(ctx,
+ h_bufobj = duk_push_bufobj_raw(thr,
DUK_HOBJECT_FLAG_EXTENSIBLE |
DUK_HOBJECT_FLAG_BUFOBJ |
DUK_HOBJECT_CLASS_AS_FLAGS(class_num),
- proto_bidx);
+ (duk_small_int_t) proto_bidx);
h_val = h_bufarg->buf;
if (h_val == NULL) {
DUK_DCERROR_TYPE_INVALID_ARGS(thr);
@@ -25548,7 +26706,7 @@ DUK_INTERNAL duk_ret_t duk_bi_typedarray_constructor(duk_context *ctx) {
#endif /* !DUK_USE_PREFER_SIZE */
} else {
/* Array or Array-like */
- elem_length_signed = (duk_int_t) duk_get_length(ctx, 0);
+ elem_length_signed = (duk_int_t) duk_get_length(thr, 0);
copy_mode = 2;
}
} else {
@@ -25556,7 +26714,7 @@ DUK_INTERNAL duk_ret_t duk_bi_typedarray_constructor(duk_context *ctx) {
* V8 behavior (except for "null", which we coerce to
* 0 but V8 TypeErrors).
*/
- elem_length_signed = duk_to_int(ctx, 0);
+ elem_length_signed = duk_to_int(thr, 0);
copy_mode = 3;
}
if (elem_length_signed < 0) {
@@ -25582,15 +26740,15 @@ DUK_INTERNAL duk_ret_t duk_bi_typedarray_constructor(duk_context *ctx) {
*/
/* Push the resulting view object on top of a plain fixed buffer. */
- (void) duk_push_fixed_buffer(ctx, byte_length);
- h_val = duk_known_hbuffer(ctx, -1);
+ (void) duk_push_fixed_buffer(thr, byte_length);
+ h_val = duk_known_hbuffer(thr, -1);
DUK_ASSERT(h_val != NULL);
- h_bufobj = duk_push_bufobj_raw(ctx,
+ h_bufobj = duk_push_bufobj_raw(thr,
DUK_HOBJECT_FLAG_EXTENSIBLE |
DUK_HOBJECT_FLAG_BUFOBJ |
DUK_HOBJECT_CLASS_AS_FLAGS(class_num),
- proto_bidx);
+ (duk_small_int_t) proto_bidx);
h_bufobj->buf = h_val;
DUK_HBUFFER_INCREF(thr, h_val);
@@ -25651,7 +26809,7 @@ DUK_INTERNAL duk_ret_t duk_bi_typedarray_constructor(duk_context *ctx) {
DUK_ASSERT(h_bufarg->buf != NULL);
DUK_ASSERT(DUK_HBUFOBJ_VALID_SLICE(h_bufarg));
- src_elem_size = 1 << h_bufarg->shift;
+ src_elem_size = (duk_small_uint_t) (1U << h_bufarg->shift);
dst_elem_size = elem_size;
p_src = DUK_HBUFOBJ_GET_SLICE_BASE(thr->heap, h_bufarg);
@@ -25670,9 +26828,9 @@ DUK_INTERNAL duk_ret_t duk_bi_typedarray_constructor(duk_context *ctx) {
/* A validated read() is always a number, so it's write coercion
* is always side effect free an won't invalidate pointers etc.
*/
- duk_hbufobj_push_validated_read(ctx, h_bufarg, p_src, src_elem_size);
- duk_hbufobj_validated_write(ctx, h_bufobj, p_dst, dst_elem_size);
- duk_pop(ctx);
+ duk_hbufobj_push_validated_read(thr, h_bufarg, p_src, src_elem_size);
+ duk_hbufobj_validated_write(thr, h_bufobj, p_dst, dst_elem_size);
+ duk_pop(thr);
p_src += src_elem_size;
p_dst += dst_elem_size;
}
@@ -25688,8 +26846,8 @@ DUK_INTERNAL duk_ret_t duk_bi_typedarray_constructor(duk_context *ctx) {
DUK_DDD(DUK_DDDPRINT("using slow copy"));
for (i = 0; i < elem_length; i++) {
- duk_get_prop_index(ctx, 0, (duk_uarridx_t) i);
- duk_put_prop_index(ctx, -2, (duk_uarridx_t) i);
+ duk_get_prop_index(thr, 0, (duk_uarridx_t) i);
+ duk_put_prop_index(thr, -2, (duk_uarridx_t) i);
}
break;
}
@@ -25715,7 +26873,7 @@ DUK_INTERNAL duk_ret_t duk_bi_typedarray_constructor(duk_context *ctx) {
* supported to create a plain fixed buffer. Disabled for now.
*/
#if 0
-DUK_INTERNAL duk_ret_t duk_bi_typedarray_constructor(duk_context *ctx) {
+DUK_INTERNAL duk_ret_t duk_bi_typedarray_constructor(duk_hthread *thr) {
duk_int_t elem_length_signed;
duk_uint_t byte_length;
@@ -25723,44 +26881,44 @@ DUK_INTERNAL duk_ret_t duk_bi_typedarray_constructor(duk_context *ctx) {
* buffer functions.
*/
- duk_require_constructor_call(ctx);
+ duk_require_constructor_call(thr);
- elem_length_signed = duk_require_int(ctx, 0);
+ elem_length_signed = duk_require_int(thr, 0);
if (elem_length_signed < 0) {
goto fail_arguments;
}
byte_length = (duk_uint_t) elem_length_signed;
- (void) duk_push_fixed_buffer_zero(ctx, (duk_size_t) byte_length);
+ (void) duk_push_fixed_buffer_zero(thr, (duk_size_t) byte_length);
return 1;
fail_arguments:
- DUK_DCERROR_RANGE_INVALID_ARGS((duk_hthread *) ctx);
+ DUK_DCERROR_RANGE_INVALID_ARGS(thr);
}
#endif /* 0 */
#endif /* DUK_USE_BUFFEROBJECT_SUPPORT */
#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)
-DUK_INTERNAL duk_ret_t duk_bi_dataview_constructor(duk_context *ctx) {
+DUK_INTERNAL duk_ret_t duk_bi_dataview_constructor(duk_hthread *thr) {
duk_hbufobj *h_bufarg;
duk_hbufobj *h_bufobj;
duk_hbuffer *h_val;
duk_uint_t offset;
duk_uint_t length;
- duk_require_constructor_call(ctx);
+ duk_require_constructor_call(thr);
- h_bufarg = duk__require_bufobj_value(ctx, 0);
+ h_bufarg = duk__require_bufobj_value(thr, 0);
DUK_ASSERT(h_bufarg != NULL);
if (DUK_HOBJECT_GET_CLASS_NUMBER((duk_hobject *) h_bufarg) != DUK_HOBJECT_CLASS_ARRAYBUFFER) {
- DUK_DCERROR_TYPE_INVALID_ARGS((duk_hthread *) ctx);
+ DUK_DCERROR_TYPE_INVALID_ARGS(thr);
}
- duk__resolve_offset_opt_length(ctx, h_bufarg, 1, 2, &offset, &length, 1 /*throw_flag*/);
+ duk__resolve_offset_opt_length(thr, h_bufarg, 1, 2, &offset, &length, 1 /*throw_flag*/);
DUK_ASSERT(offset <= h_bufarg->length);
DUK_ASSERT(offset + length <= h_bufarg->length);
- h_bufobj = duk_push_bufobj_raw(ctx,
+ h_bufobj = duk_push_bufobj_raw(thr,
DUK_HOBJECT_FLAG_EXTENSIBLE |
DUK_HOBJECT_FLAG_BUFOBJ |
DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_DATAVIEW),
@@ -25768,7 +26926,7 @@ DUK_INTERNAL duk_ret_t duk_bi_dataview_constructor(duk_context *ctx) {
h_val = h_bufarg->buf;
if (h_val == NULL) {
- DUK_DCERROR_TYPE_INVALID_ARGS((duk_hthread *) ctx);
+ DUK_DCERROR_TYPE_INVALID_ARGS(thr);
}
h_bufobj->buf = h_val;
DUK_HBUFFER_INCREF(thr, h_val);
@@ -25781,7 +26939,7 @@ DUK_INTERNAL duk_ret_t duk_bi_dataview_constructor(duk_context *ctx) {
DUK_ASSERT(h_bufobj->buf_prop == NULL);
h_bufobj->buf_prop = (duk_hobject *) h_bufarg;
DUK_ASSERT(h_bufarg != NULL);
- DUK_HBUFOBJ_INCREF((duk_hthread *) ctx, h_bufarg);
+ DUK_HBUFOBJ_INCREF(thr, h_bufarg);
DUK_ASSERT_HBUFOBJ_VALID(h_bufobj);
return 1;
@@ -25793,14 +26951,14 @@ DUK_INTERNAL duk_ret_t duk_bi_dataview_constructor(duk_context *ctx) {
*/
#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)
-DUK_INTERNAL duk_ret_t duk_bi_arraybuffer_isview(duk_context *ctx) {
+DUK_INTERNAL duk_ret_t duk_bi_arraybuffer_isview(duk_hthread *thr) {
duk_hobject *h_obj;
duk_bool_t ret = 0;
- if (duk_is_buffer(ctx, 0)) {
+ if (duk_is_buffer(thr, 0)) {
ret = 1;
} else {
- h_obj = duk_get_hobject(ctx, 0);
+ h_obj = duk_get_hobject(thr, 0);
if (h_obj != NULL && DUK_HOBJECT_IS_BUFOBJ(h_obj)) {
/* DataView needs special casing: ArrayBuffer.isView() is
* true, but ->is_typedarray is 0.
@@ -25809,7 +26967,7 @@ DUK_INTERNAL duk_ret_t duk_bi_arraybuffer_isview(duk_context *ctx) {
(DUK_HOBJECT_GET_CLASS_NUMBER(h_obj) == DUK_HOBJECT_CLASS_DATAVIEW);
}
}
- duk_push_boolean(ctx, ret);
+ duk_push_boolean(thr, ret);
return 1;
}
#endif /* DUK_USE_BUFFEROBJECT_SUPPORT */
@@ -25819,8 +26977,8 @@ DUK_INTERNAL duk_ret_t duk_bi_arraybuffer_isview(duk_context *ctx) {
*/
#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)
-DUK_INTERNAL duk_ret_t duk_bi_uint8array_allocplain(duk_context *ctx) {
- duk__hbufobj_fixed_from_argvalue(ctx);
+DUK_INTERNAL duk_ret_t duk_bi_uint8array_allocplain(duk_hthread *thr) {
+ duk__hbufobj_fixed_from_argvalue(thr);
return 1;
}
#endif /* DUK_USE_BUFFEROBJECT_SUPPORT */
@@ -25830,12 +26988,12 @@ DUK_INTERNAL duk_ret_t duk_bi_uint8array_allocplain(duk_context *ctx) {
*/
#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)
-DUK_INTERNAL duk_ret_t duk_bi_uint8array_plainof(duk_context *ctx) {
+DUK_INTERNAL duk_ret_t duk_bi_uint8array_plainof(duk_hthread *thr) {
duk_hbufobj *h_bufobj;
#if !defined(DUK_USE_PREFER_SIZE)
/* Avoid churn if argument is already a plain buffer. */
- if (duk_is_buffer(ctx, 0)) {
+ if (duk_is_buffer(thr, 0)) {
return 1;
}
#endif
@@ -25844,11 +27002,11 @@ DUK_INTERNAL duk_ret_t duk_bi_uint8array_plainof(duk_context *ctx) {
* argument we'll create a pointless temporary (but still work
* correctly).
*/
- h_bufobj = duk__require_bufobj_value(ctx, 0);
+ h_bufobj = duk__require_bufobj_value(thr, 0);
if (h_bufobj->buf == NULL) {
- duk_push_undefined(ctx);
+ duk_push_undefined(thr);
} else {
- duk_push_hbuffer(ctx, h_bufobj->buf);
+ duk_push_hbuffer(thr, h_bufobj->buf);
}
return 1;
}
@@ -25859,27 +27017,23 @@ DUK_INTERNAL duk_ret_t duk_bi_uint8array_plainof(duk_context *ctx) {
*/
#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)
-DUK_INTERNAL duk_ret_t duk_bi_nodejs_buffer_tostring(duk_context *ctx) {
- duk_hthread *thr;
+DUK_INTERNAL duk_ret_t duk_bi_nodejs_buffer_tostring(duk_hthread *thr) {
duk_hbufobj *h_this;
duk_int_t start_offset, end_offset;
duk_uint8_t *buf_slice;
duk_size_t slice_length;
- thr = (duk_hthread *) ctx;
- DUK_UNREF(thr);
-
- h_this = duk__get_bufobj_this(ctx);
+ h_this = duk__get_bufobj_this(thr);
if (h_this == NULL) {
/* XXX: happens e.g. when evaluating: String(Buffer.prototype). */
- duk_push_string(ctx, "[object Object]");
+ duk_push_string(thr, "[object Object]");
return 1;
}
DUK_ASSERT_HBUFOBJ_VALID(h_this);
/* Ignore encoding for now. */
- duk__clamp_startend_nonegidx_noshift(ctx,
+ duk__clamp_startend_nonegidx_noshift(thr,
(duk_int_t) h_this->length,
1 /*idx_start*/,
2 /*idx_end*/,
@@ -25887,12 +27041,12 @@ DUK_INTERNAL duk_ret_t duk_bi_nodejs_buffer_tostring(duk_context *ctx) {
&end_offset);
slice_length = (duk_size_t) (end_offset - start_offset);
- buf_slice = (duk_uint8_t *) duk_push_fixed_buffer_nozero(ctx, slice_length); /* all bytes initialized below */
+ buf_slice = (duk_uint8_t *) duk_push_fixed_buffer_nozero(thr, slice_length); /* all bytes initialized below */
DUK_ASSERT(buf_slice != NULL);
/* Neutered or uncovered, TypeError. */
if (h_this->buf == NULL ||
- !DUK_HBUFOBJ_VALID_BYTEOFFSET_EXCL(h_this, start_offset + slice_length)) {
+ !DUK_HBUFOBJ_VALID_BYTEOFFSET_EXCL(h_this, (duk_size_t) start_offset + slice_length)) {
DUK_DCERROR_TYPE_INVALID_ARGS(thr);
}
@@ -25902,7 +27056,7 @@ DUK_INTERNAL duk_ret_t duk_bi_nodejs_buffer_tostring(duk_context *ctx) {
* its stability is difficult).
*/
- DUK_ASSERT(DUK_HBUFOBJ_VALID_BYTEOFFSET_EXCL(h_this, start_offset + slice_length));
+ DUK_ASSERT(DUK_HBUFOBJ_VALID_BYTEOFFSET_EXCL(h_this, (duk_size_t) start_offset + slice_length));
DUK_MEMCPY((void *) buf_slice,
(const void *) (DUK_HBUFOBJ_GET_SLICE_BASE(thr->heap, h_this) + start_offset),
(size_t) slice_length);
@@ -25911,9 +27065,9 @@ DUK_INTERNAL duk_ret_t duk_bi_nodejs_buffer_tostring(duk_context *ctx) {
* string. Result will be valid UTF-8; non-CESU-8 inputs are currently
* interpreted loosely. Value stack convention is a bit odd for now.
*/
- duk_replace(ctx, 0);
- duk_set_top(ctx, 1);
- return duk_textdecoder_decode_utf8_nodejs(ctx);
+ duk_replace(thr, 0);
+ duk_set_top(thr, 1);
+ return duk_textdecoder_decode_utf8_nodejs(thr);
}
#endif /* DUK_USE_BUFFEROBJECT_SUPPORT */
@@ -25922,44 +27076,37 @@ DUK_INTERNAL duk_ret_t duk_bi_nodejs_buffer_tostring(duk_context *ctx) {
*/
#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)
-DUK_INTERNAL duk_ret_t duk_bi_nodejs_buffer_tojson(duk_context *ctx) {
- duk_hthread *thr;
+DUK_INTERNAL duk_ret_t duk_bi_nodejs_buffer_tojson(duk_hthread *thr) {
duk_hbufobj *h_this;
- duk_harray *h_arr;
duk_uint8_t *buf;
duk_uint_t i, n;
duk_tval *tv;
- thr = (duk_hthread *) ctx;
- DUK_UNREF(thr);
-
- h_this = duk__require_bufobj_this(ctx);
+ h_this = duk__require_bufobj_this(thr);
DUK_ASSERT(h_this != NULL);
if (h_this->buf == NULL || !DUK_HBUFOBJ_VALID_SLICE(h_this)) {
/* Serialize uncovered backing buffer as a null; doesn't
* really matter as long we're memory safe.
*/
- duk_push_null(ctx);
+ duk_push_null(thr);
return 1;
}
- duk_push_object(ctx);
- duk_push_hstring_stridx(ctx, DUK_STRIDX_UC_BUFFER);
- duk_put_prop_stridx_short(ctx, -2, DUK_STRIDX_TYPE);
+ duk_push_object(thr);
+ duk_push_hstring_stridx(thr, DUK_STRIDX_UC_BUFFER);
+ duk_put_prop_stridx_short(thr, -2, DUK_STRIDX_TYPE);
+ /* XXX: uninitialized would be OK */
DUK_ASSERT_DISABLE((duk_size_t) h_this->length <= (duk_size_t) DUK_UINT32_MAX);
- h_arr = duk_push_harray_with_size(ctx, (duk_uint32_t) h_this->length); /* XXX: needs revision with >4G buffers */
- DUK_ASSERT(h_arr != NULL);
- DUK_ASSERT(h_arr->length == h_this->length);
- tv = DUK_HOBJECT_A_GET_BASE(thr->heap, (duk_hobject *) h_arr);
+ tv = duk_push_harray_with_size_outptr(thr, (duk_uint32_t) h_this->length); /* XXX: needs revision with >4G buffers */
DUK_ASSERT(h_this->buf != NULL);
buf = DUK_HBUFOBJ_GET_SLICE_BASE(thr->heap, h_this);
for (i = 0, n = h_this->length; i < n; i++) {
DUK_TVAL_SET_U32(tv + i, (duk_uint32_t) buf[i]); /* no need for decref or incref */
}
- duk_put_prop_stridx_short(ctx, -2, DUK_STRIDX_DATA);
+ duk_put_prop_stridx_short(thr, -2, DUK_STRIDX_DATA);
return 1;
}
@@ -25972,26 +27119,22 @@ DUK_INTERNAL duk_ret_t duk_bi_nodejs_buffer_tojson(duk_context *ctx) {
*/
#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)
-DUK_INTERNAL duk_ret_t duk_bi_buffer_compare_shared(duk_context *ctx) {
- duk_hthread *thr;
+DUK_INTERNAL duk_ret_t duk_bi_buffer_compare_shared(duk_hthread *thr) {
duk_small_uint_t magic;
duk_hbufobj *h_bufarg1;
duk_hbufobj *h_bufarg2;
duk_small_int_t comp_res;
- thr = (duk_hthread *) ctx;
- DUK_UNREF(thr);
-
/* XXX: keep support for plain buffers and non-Node.js buffers? */
- magic = duk_get_current_magic(ctx);
- if (magic & 0x02) {
+ magic = (duk_small_uint_t) duk_get_current_magic(thr);
+ if (magic & 0x02U) {
/* Static call style. */
- h_bufarg1 = duk__require_bufobj_value(ctx, 0);
- h_bufarg2 = duk__require_bufobj_value(ctx, 1);
+ h_bufarg1 = duk__require_bufobj_value(thr, 0);
+ h_bufarg2 = duk__require_bufobj_value(thr, 1);
} else {
- h_bufarg1 = duk__require_bufobj_this(ctx);
- h_bufarg2 = duk__require_bufobj_value(ctx, 0);
+ h_bufarg1 = duk__require_bufobj_this(thr);
+ h_bufarg2 = duk__require_bufobj_value(thr, 0);
}
DUK_ASSERT(h_bufarg1 != NULL);
DUK_ASSERT(h_bufarg2 != NULL);
@@ -26012,12 +27155,12 @@ DUK_INTERNAL duk_ret_t duk_bi_buffer_compare_shared(duk_context *ctx) {
comp_res = -1; /* either nonzero value is ok */
}
- if (magic & 0x01) {
+ if (magic & 0x01U) {
/* compare: similar to string comparison but for buffer data. */
- duk_push_int(ctx, comp_res);
+ duk_push_int(thr, comp_res);
} else {
/* equals */
- duk_push_boolean(ctx, (comp_res == 0));
+ duk_push_boolean(thr, (comp_res == 0));
}
return 1;
@@ -26029,8 +27172,7 @@ DUK_INTERNAL duk_ret_t duk_bi_buffer_compare_shared(duk_context *ctx) {
*/
#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)
-DUK_INTERNAL duk_ret_t duk_bi_nodejs_buffer_fill(duk_context *ctx) {
- duk_hthread *thr;
+DUK_INTERNAL duk_ret_t duk_bi_nodejs_buffer_fill(duk_hthread *thr) {
duk_hbufobj *h_this;
const duk_uint8_t *fill_str_ptr;
duk_size_t fill_str_len;
@@ -26040,10 +27182,7 @@ DUK_INTERNAL duk_ret_t duk_bi_nodejs_buffer_fill(duk_context *ctx) {
duk_size_t fill_length;
duk_uint8_t *p;
- thr = (duk_hthread *) ctx;
- DUK_UNREF(thr);
-
- h_this = duk__require_bufobj_this(ctx);
+ h_this = duk__require_bufobj_this(thr);
DUK_ASSERT(h_this != NULL);
if (h_this->buf == NULL) {
DUK_DCERROR_TYPE_INVALID_ARGS(thr);
@@ -26051,19 +27190,19 @@ DUK_INTERNAL duk_ret_t duk_bi_nodejs_buffer_fill(duk_context *ctx) {
/* [ value offset end ] */
- if (duk_is_string_notsymbol(ctx, 0)) {
- fill_str_ptr = (const duk_uint8_t *) duk_get_lstring(ctx, 0, &fill_str_len);
+ if (duk_is_string_notsymbol(thr, 0)) {
+ fill_str_ptr = (const duk_uint8_t *) duk_get_lstring(thr, 0, &fill_str_len);
DUK_ASSERT(fill_str_ptr != NULL);
} else {
/* Symbols get ToNumber() coerced and cause TypeError. */
- fill_value = (duk_uint8_t) duk_to_uint32(ctx, 0);
+ fill_value = (duk_uint8_t) duk_to_uint32(thr, 0);
fill_str_ptr = (const duk_uint8_t *) &fill_value;
fill_str_len = 1;
}
/* Fill offset handling is more lenient than in Node.js. */
- duk__clamp_startend_nonegidx_noshift(ctx,
+ duk__clamp_startend_nonegidx_noshift(thr,
(duk_int_t) h_this->length,
1 /*idx_start*/,
2 /*idx_end*/,
@@ -26086,7 +27225,7 @@ DUK_INTERNAL duk_ret_t duk_bi_nodejs_buffer_fill(duk_context *ctx) {
} else if (fill_str_len > 1) {
duk_size_t i, n, t;
- for (i = 0, n = (fill_end - fill_offset), t = 0; i < n; i++) {
+ for (i = 0, n = (duk_size_t) (fill_end - fill_offset), t = 0; i < n; i++) {
p[i] = fill_str_ptr[t++];
if (t >= fill_str_len) {
t = 0;
@@ -26097,7 +27236,7 @@ DUK_INTERNAL duk_ret_t duk_bi_nodejs_buffer_fill(duk_context *ctx) {
}
/* Return the Buffer to allow chaining: b.fill(0x11).fill(0x22, 3, 5).toString() */
- duk_push_this(ctx);
+ duk_push_this(thr);
return 1;
}
#endif /* DUK_USE_BUFFEROBJECT_SUPPORT */
@@ -26107,25 +27246,21 @@ DUK_INTERNAL duk_ret_t duk_bi_nodejs_buffer_fill(duk_context *ctx) {
*/
#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)
-DUK_INTERNAL duk_ret_t duk_bi_nodejs_buffer_write(duk_context *ctx) {
- duk_hthread *thr;
+DUK_INTERNAL duk_ret_t duk_bi_nodejs_buffer_write(duk_hthread *thr) {
duk_hbufobj *h_this;
duk_uint_t offset;
duk_uint_t length;
const duk_uint8_t *str_data;
duk_size_t str_len;
- thr = (duk_hthread *) ctx;
- DUK_UNREF(thr);
-
/* XXX: very inefficient support for plain buffers */
- h_this = duk__require_bufobj_this(ctx);
+ h_this = duk__require_bufobj_this(thr);
DUK_ASSERT(h_this != NULL);
/* Argument must be a string, e.g. a buffer is not allowed. */
- str_data = (const duk_uint8_t *) duk_require_lstring_notsymbol(ctx, 0, &str_len);
+ str_data = (const duk_uint8_t *) duk_require_lstring_notsymbol(thr, 0, &str_len);
- duk__resolve_offset_opt_length(ctx, h_this, 1, 2, &offset, &length, 0 /*throw_flag*/);
+ duk__resolve_offset_opt_length(thr, h_this, 1, 2, &offset, &length, 0 /*throw_flag*/);
DUK_ASSERT(offset <= h_this->length);
DUK_ASSERT(offset + length <= h_this->length);
@@ -26144,7 +27279,7 @@ DUK_INTERNAL duk_ret_t duk_bi_nodejs_buffer_write(duk_context *ctx) {
DUK_DDD(DUK_DDDPRINT("write() target buffer is not covered, silent ignore"));
}
- duk_push_uint(ctx, length);
+ duk_push_uint(thr, length);
return 1;
}
#endif /* DUK_USE_BUFFEROBJECT_SUPPORT */
@@ -26154,8 +27289,7 @@ DUK_INTERNAL duk_ret_t duk_bi_nodejs_buffer_write(duk_context *ctx) {
*/
#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)
-DUK_INTERNAL duk_ret_t duk_bi_nodejs_buffer_copy(duk_context *ctx) {
- duk_hthread *thr;
+DUK_INTERNAL duk_ret_t duk_bi_nodejs_buffer_copy(duk_hthread *thr) {
duk_hbufobj *h_this;
duk_hbufobj *h_bufarg;
duk_int_t source_length;
@@ -26166,22 +27300,19 @@ DUK_INTERNAL duk_ret_t duk_bi_nodejs_buffer_copy(duk_context *ctx) {
/* [ targetBuffer targetStart sourceStart sourceEnd ] */
- thr = (duk_hthread *) ctx;
- DUK_UNREF(thr);
-
- h_this = duk__require_bufobj_this(ctx);
- h_bufarg = duk__require_bufobj_value(ctx, 0);
+ h_this = duk__require_bufobj_this(thr);
+ h_bufarg = duk__require_bufobj_value(thr, 0);
DUK_ASSERT(h_this != NULL);
DUK_ASSERT(h_bufarg != NULL);
source_length = (duk_int_t) h_this->length;
target_length = (duk_int_t) h_bufarg->length;
- target_start = duk_to_int(ctx, 1);
- source_start = duk_to_int(ctx, 2);
- if (duk_is_undefined(ctx, 3)) {
+ target_start = duk_to_int(thr, 1);
+ source_start = duk_to_int(thr, 2);
+ if (duk_is_undefined(thr, 3)) {
source_end = source_length;
} else {
- source_end = duk_to_int(ctx, 3);
+ source_end = duk_to_int(thr, 3);
}
DUK_DDD(DUK_DDDPRINT("checking copy args: target_start=%ld, target_length=%ld, "
@@ -26205,7 +27336,7 @@ DUK_INTERNAL duk_ret_t duk_bi_nodejs_buffer_copy(duk_context *ctx) {
}
if (source_uend >= (duk_uint_t) source_length) {
/* Source end clamped silently to available length. */
- source_uend = source_length;
+ source_uend = (duk_uint_t) source_length;
}
copy_size = source_uend - source_ustart;
if (target_ustart + copy_size > (duk_uint_t) target_length) {
@@ -26251,7 +27382,7 @@ DUK_INTERNAL duk_ret_t duk_bi_nodejs_buffer_copy(duk_context *ctx) {
* The return value matters because of code like:
* "off += buf.copy(...)".
*/
- duk_push_uint(ctx, copy_size);
+ duk_push_uint(thr, copy_size);
return 1;
fail_bounds:
@@ -26296,8 +27427,7 @@ DUK_INTERNAL duk_ret_t duk_bi_nodejs_buffer_copy(duk_context *ctx) {
*/
#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)
-DUK_INTERNAL duk_ret_t duk_bi_typedarray_set(duk_context *ctx) {
- duk_hthread *thr;
+DUK_INTERNAL duk_ret_t duk_bi_typedarray_set(duk_hthread *thr) {
duk_hbufobj *h_this;
duk_hobject *h_obj;
duk_uarridx_t i, n;
@@ -26305,10 +27435,7 @@ DUK_INTERNAL duk_ret_t duk_bi_typedarray_set(duk_context *ctx) {
duk_uint_t offset_elems;
duk_uint_t offset_bytes;
- thr = (duk_hthread *) ctx;
- DUK_UNREF(thr);
-
- h_this = duk__require_bufobj_this(ctx);
+ h_this = duk__require_bufobj_this(thr);
DUK_ASSERT(h_this != NULL);
DUK_ASSERT_HBUFOBJ_VALID(h_this);
@@ -26317,14 +27444,14 @@ DUK_INTERNAL duk_ret_t duk_bi_typedarray_set(duk_context *ctx) {
return 0;
}
- duk_hbufobj_promote_plain(ctx, 0);
- h_obj = duk_require_hobject(ctx, 0);
+ duk_hbufobj_promote_plain(thr, 0);
+ h_obj = duk_require_hobject(thr, 0);
/* XXX: V8 throws a TypeError for negative values. Would it
* be more useful to interpret negative offsets here from the
* end of the buffer too?
*/
- offset_signed = duk_to_int(ctx, 1);
+ offset_signed = duk_to_int(thr, 1);
if (offset_signed < 0) {
/* For some reason this is a TypeError (at least in V8). */
DUK_DCERROR_TYPE_INVALID_ARGS(thr);
@@ -26472,7 +27599,7 @@ DUK_INTERNAL duk_ret_t duk_bi_typedarray_set(duk_context *ctx) {
duk_uint8_t *p_src_copy;
DUK_DDD(DUK_DDDPRINT("there is overlap, make a copy of the source"));
- p_src_copy = (duk_uint8_t *) duk_push_fixed_buffer_nozero(ctx, src_length);
+ p_src_copy = (duk_uint8_t *) duk_push_fixed_buffer_nozero(thr, src_length);
DUK_ASSERT(p_src_copy != NULL);
DUK_MEMCPY((void *) p_src_copy, (const void *) p_src_base, (size_t) src_length);
@@ -26484,7 +27611,7 @@ DUK_INTERNAL duk_ret_t duk_bi_typedarray_set(duk_context *ctx) {
"p_dst_base=%p, dst_length=%ld, valstack top=%ld",
(void *) p_src_base, (long) src_length,
(void *) p_dst_base, (long) dst_length,
- (long) duk_get_top(ctx)));
+ (long) duk_get_top(thr)));
/* Ready to make the copy. We must proceed element by element
* and must avoid any side effects that might cause the buffer
@@ -26494,8 +27621,8 @@ DUK_INTERNAL duk_ret_t duk_bi_typedarray_set(duk_context *ctx) {
* numbers are handled which should be side effect safe.
*/
- src_elem_size = 1 << h_bufarg->shift;
- dst_elem_size = 1 << h_this->shift;
+ src_elem_size = (duk_small_uint_t) (1U << h_bufarg->shift);
+ dst_elem_size = (duk_small_uint_t) (1U << h_this->shift);
p_src = p_src_base;
p_dst = p_dst_base;
p_src_end = p_src_base + src_length;
@@ -26507,9 +27634,9 @@ DUK_INTERNAL duk_ret_t duk_bi_typedarray_set(duk_context *ctx) {
/* A validated read() is always a number, so it's write coercion
* is always side effect free an won't invalidate pointers etc.
*/
- duk_hbufobj_push_validated_read(ctx, h_bufarg, p_src, src_elem_size);
- duk_hbufobj_validated_write(ctx, h_this, p_dst, dst_elem_size);
- duk_pop(ctx);
+ duk_hbufobj_push_validated_read(thr, h_bufarg, p_src, src_elem_size);
+ duk_hbufobj_validated_write(thr, h_this, p_dst, dst_elem_size);
+ duk_pop(thr);
p_src += src_elem_size;
p_dst += dst_elem_size;
}
@@ -26525,7 +27652,7 @@ DUK_INTERNAL duk_ret_t duk_bi_typedarray_set(duk_context *ctx) {
* would be needed for every element anyway.
*/
- n = (duk_uarridx_t) duk_get_length(ctx, 0);
+ n = (duk_uarridx_t) duk_get_length(thr, 0);
DUK_ASSERT(offset_bytes <= h_this->length);
if ((n << h_this->shift) > h_this->length - offset_bytes) {
/* Overflow not an issue because subtraction is used on the right
@@ -26542,12 +27669,12 @@ DUK_INTERNAL duk_ret_t duk_bi_typedarray_set(duk_context *ctx) {
* the results anyway.
*/
- DUK_ASSERT_TOP(ctx, 2);
- duk_push_this(ctx);
+ DUK_ASSERT_TOP(thr, 2);
+ duk_push_this(thr);
for (i = 0; i < n; i++) {
- duk_get_prop_index(ctx, 0, i);
- duk_put_prop_index(ctx, 2, offset_elems + i);
+ duk_get_prop_index(thr, 0, i);
+ duk_put_prop_index(thr, 2, offset_elems + i);
}
}
@@ -26579,17 +27706,13 @@ DUK_INTERNAL duk_ret_t duk_bi_typedarray_set(duk_context *ctx) {
*/
#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)
-DUK_LOCAL void duk__arraybuffer_plain_slice(duk_context *ctx, duk_hbuffer *h_val) {
- duk_hthread *thr;
+DUK_LOCAL void duk__arraybuffer_plain_slice(duk_hthread *thr, duk_hbuffer *h_val) {
duk_int_t start_offset, end_offset;
duk_uint_t slice_length;
duk_uint8_t *p_copy;
duk_size_t copy_length;
- thr = (duk_hthread *) ctx;
- DUK_UNREF(thr);
-
- duk__clamp_startend_negidx_shifted(ctx,
+ duk__clamp_startend_negidx_shifted(thr,
(duk_int_t) DUK_HBUFFER_GET_SIZE(h_val),
0 /*buffer_shift*/,
0 /*idx_start*/,
@@ -26601,7 +27724,7 @@ DUK_LOCAL void duk__arraybuffer_plain_slice(duk_context *ctx, duk_hbuffer *h_val
DUK_ASSERT(end_offset >= start_offset);
slice_length = (duk_uint_t) (end_offset - start_offset);
- p_copy = (duk_uint8_t *) duk_push_fixed_buffer_nozero(ctx, (duk_size_t) slice_length);
+ p_copy = (duk_uint8_t *) duk_push_fixed_buffer_nozero(thr, (duk_size_t) slice_length);
DUK_ASSERT(p_copy != NULL);
copy_length = slice_length;
@@ -26615,8 +27738,7 @@ DUK_LOCAL void duk__arraybuffer_plain_slice(duk_context *ctx, duk_hbuffer *h_val
/* Shared helper for slice/subarray operation.
* Magic: 0x01=isView, 0x02=copy, 0x04=Node.js Buffer special handling.
*/
-DUK_INTERNAL duk_ret_t duk_bi_buffer_slice_shared(duk_context *ctx) {
- duk_hthread *thr;
+DUK_INTERNAL duk_ret_t duk_bi_buffer_slice_shared(duk_hthread *thr) {
duk_small_int_t magic;
duk_small_uint_t res_class_num;
duk_small_int_t res_proto_bidx;
@@ -26627,14 +27749,11 @@ DUK_INTERNAL duk_ret_t duk_bi_buffer_slice_shared(duk_context *ctx) {
duk_uint_t slice_length;
duk_tval *tv;
- thr = (duk_hthread *) ctx;
- DUK_UNREF(thr);
-
/* [ start end ] */
- magic = duk_get_current_magic(ctx);
+ magic = duk_get_current_magic(thr);
- tv = duk_get_borrowed_this_tval(ctx);
+ tv = duk_get_borrowed_this_tval(thr);
DUK_ASSERT(tv != NULL);
if (DUK_TVAL_IS_BUFFER(tv)) {
@@ -26644,7 +27763,7 @@ DUK_INTERNAL duk_ret_t duk_bi_buffer_slice_shared(duk_context *ctx) {
if (magic & 0x02) {
/* Make copy: ArrayBuffer.prototype.slice() uses this. */
- duk__arraybuffer_plain_slice(ctx, h_val);
+ duk__arraybuffer_plain_slice(thr, h_val);
return 1;
} else {
/* View into existing buffer: cannot be done if the
@@ -26661,7 +27780,7 @@ DUK_INTERNAL duk_ret_t duk_bi_buffer_slice_shared(duk_context *ctx) {
}
tv = NULL; /* No longer valid nor needed. */
- h_this = duk__require_bufobj_this(ctx);
+ h_this = duk__require_bufobj_this(thr);
/* Slice offsets are element (not byte) offsets, which only matters
* for TypedArray views, Node.js Buffer and ArrayBuffer have shift
@@ -26672,7 +27791,7 @@ DUK_INTERNAL duk_ret_t duk_bi_buffer_slice_shared(duk_context *ctx) {
* against the underlying buffer here.
*/
- duk__clamp_startend_negidx_shifted(ctx,
+ duk__clamp_startend_negidx_shifted(thr,
(duk_int_t) h_this->length,
(duk_uint8_t) h_this->shift,
0 /*idx_start*/,
@@ -26680,6 +27799,8 @@ DUK_INTERNAL duk_ret_t duk_bi_buffer_slice_shared(duk_context *ctx) {
&start_offset,
&end_offset);
DUK_ASSERT(end_offset >= start_offset);
+ DUK_ASSERT(start_offset >= 0);
+ DUK_ASSERT(end_offset >= 0);
slice_length = (duk_uint_t) (end_offset - start_offset);
/* The resulting buffer object gets the same class and prototype as
@@ -26701,14 +27822,14 @@ DUK_INTERNAL duk_ret_t duk_bi_buffer_slice_shared(duk_context *ctx) {
if (magic & 0x04) {
res_proto_bidx = DUK_BIDX_NODEJS_BUFFER_PROTOTYPE;
}
- h_bufobj = duk_push_bufobj_raw(ctx,
+ h_bufobj = duk_push_bufobj_raw(thr,
DUK_HOBJECT_FLAG_EXTENSIBLE |
DUK_HOBJECT_FLAG_BUFOBJ |
DUK_HOBJECT_CLASS_AS_FLAGS(res_class_num),
res_proto_bidx);
DUK_ASSERT(h_bufobj != NULL);
- h_bufobj->length = slice_length;
+ DUK_ASSERT(h_bufobj->length == 0);
h_bufobj->shift = h_this->shift; /* inherit */
h_bufobj->elem_type = h_this->elem_type; /* inherit */
h_bufobj->is_typedarray = magic & 0x01;
@@ -26724,7 +27845,7 @@ DUK_INTERNAL duk_ret_t duk_bi_buffer_slice_shared(duk_context *ctx) {
duk_uint8_t *p_copy;
duk_size_t copy_length;
- p_copy = (duk_uint8_t *) duk_push_fixed_buffer_zero(ctx, (duk_size_t) slice_length); /* must be zeroed, not all bytes always copied */
+ p_copy = (duk_uint8_t *) duk_push_fixed_buffer_zero(thr, (duk_size_t) slice_length); /* must be zeroed, not all bytes always copied */
DUK_ASSERT(p_copy != NULL);
/* Copy slice, respecting underlying buffer limits; remainder
@@ -26735,17 +27856,19 @@ DUK_INTERNAL duk_ret_t duk_bi_buffer_slice_shared(duk_context *ctx) {
(const void *) (DUK_HBUFOBJ_GET_SLICE_BASE(thr->heap, h_this) + start_offset),
copy_length);
- h_val = duk_known_hbuffer(ctx, -1);
+ h_val = duk_known_hbuffer(thr, -1);
h_bufobj->buf = h_val;
DUK_HBUFFER_INCREF(thr, h_val);
+ h_bufobj->length = slice_length;
DUK_ASSERT(h_bufobj->offset == 0);
- duk_pop(ctx); /* reachable so pop OK */
+ duk_pop(thr); /* reachable so pop OK */
} else {
h_bufobj->buf = h_val;
DUK_HBUFFER_INCREF(thr, h_val);
- h_bufobj->offset = (duk_uint_t) (h_this->offset + start_offset);
+ h_bufobj->length = slice_length;
+ h_bufobj->offset = h_this->offset + (duk_uint_t) start_offset;
/* Copy the .buffer property, needed for TypedArray.prototype.subarray().
*
@@ -26768,14 +27891,14 @@ DUK_INTERNAL duk_ret_t duk_bi_buffer_slice_shared(duk_context *ctx) {
*/
#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)
-DUK_INTERNAL duk_ret_t duk_bi_nodejs_buffer_is_encoding(duk_context *ctx) {
+DUK_INTERNAL duk_ret_t duk_bi_nodejs_buffer_is_encoding(duk_hthread *thr) {
const char *encoding;
/* only accept lowercase 'utf8' now. */
- encoding = duk_to_string(ctx, 0);
- DUK_ASSERT(duk_is_string(ctx, 0)); /* guaranteed by duk_to_string() */
- duk_push_boolean(ctx, DUK_STRCMP(encoding, "utf8") == 0);
+ encoding = duk_to_string(thr, 0);
+ DUK_ASSERT(duk_is_string(thr, 0)); /* guaranteed by duk_to_string() */
+ duk_push_boolean(thr, DUK_STRCMP(encoding, "utf8") == 0);
return 1;
}
#endif /* DUK_USE_BUFFEROBJECT_SUPPORT */
@@ -26785,16 +27908,13 @@ DUK_INTERNAL duk_ret_t duk_bi_nodejs_buffer_is_encoding(duk_context *ctx) {
*/
#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)
-DUK_INTERNAL duk_ret_t duk_bi_nodejs_buffer_is_buffer(duk_context *ctx) {
- duk_hthread *thr;
+DUK_INTERNAL duk_ret_t duk_bi_nodejs_buffer_is_buffer(duk_hthread *thr) {
duk_hobject *h;
duk_hobject *h_proto;
duk_bool_t ret = 0;
- thr = (duk_hthread *) ctx;
-
- DUK_ASSERT(duk_get_top(ctx) >= 1); /* nargs */
- h = duk_get_hobject(ctx, 0);
+ DUK_ASSERT(duk_get_top(thr) >= 1); /* nargs */
+ h = duk_get_hobject(thr, 0);
if (h != NULL) {
h_proto = thr->builtins[DUK_BIDX_NODEJS_BUFFER_PROTOTYPE];
DUK_ASSERT(h_proto != NULL);
@@ -26805,7 +27925,7 @@ DUK_INTERNAL duk_ret_t duk_bi_nodejs_buffer_is_buffer(duk_context *ctx) {
}
}
- duk_push_boolean(ctx, ret);
+ duk_push_boolean(thr, ret);
return 1;
}
#endif /* DUK_USE_BUFFEROBJECT_SUPPORT */
@@ -26815,7 +27935,7 @@ DUK_INTERNAL duk_ret_t duk_bi_nodejs_buffer_is_buffer(duk_context *ctx) {
*/
#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)
-DUK_INTERNAL duk_ret_t duk_bi_nodejs_buffer_byte_length(duk_context *ctx) {
+DUK_INTERNAL duk_ret_t duk_bi_nodejs_buffer_byte_length(duk_hthread *thr) {
const char *str;
duk_size_t len;
@@ -26834,9 +27954,9 @@ DUK_INTERNAL duk_ret_t duk_bi_nodejs_buffer_byte_length(duk_context *ctx) {
* (The 20 comes from '[object Uint32Array]'.length
*/
- str = duk_to_lstring(ctx, 0, &len);
+ str = duk_to_lstring(thr, 0, &len);
DUK_UNREF(str);
- duk_push_size_t(ctx, len);
+ duk_push_size_t(thr, len);
return 1;
}
#endif /* DUK_USE_BUFFEROBJECT_SUPPORT */
@@ -26846,10 +27966,9 @@ DUK_INTERNAL duk_ret_t duk_bi_nodejs_buffer_byte_length(duk_context *ctx) {
*/
#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)
-DUK_INTERNAL duk_ret_t duk_bi_nodejs_buffer_concat(duk_context *ctx) {
- duk_hthread *thr;
+DUK_INTERNAL duk_ret_t duk_bi_nodejs_buffer_concat(duk_hthread *thr) {
duk_hobject *h_arg;
- duk_int_t total_length = 0;
+ duk_uint_t total_length;
duk_hbufobj *h_bufobj;
duk_hbufobj *h_bufres;
duk_hbuffer *h_val;
@@ -26858,63 +27977,66 @@ DUK_INTERNAL duk_ret_t duk_bi_nodejs_buffer_concat(duk_context *ctx) {
duk_size_t space_left;
duk_size_t copy_size;
- thr = (duk_hthread *) ctx;
- DUK_UNREF(thr);
-
/* Node.js accepts only actual Arrays. */
- h_arg = duk_require_hobject(ctx, 0);
+ h_arg = duk_require_hobject(thr, 0);
if (DUK_HOBJECT_GET_CLASS_NUMBER(h_arg) != DUK_HOBJECT_CLASS_ARRAY) {
DUK_DCERROR_TYPE_INVALID_ARGS(thr);
}
/* Compute result length and validate argument buffers. */
- n = (duk_uint_t) duk_get_length(ctx, 0);
+ n = (duk_uint_t) duk_get_length(thr, 0);
+ total_length = 0;
for (i = 0; i < n; i++) {
/* Neutered checks not necessary here: neutered buffers have
* zero 'length' so we'll effectively skip them.
*/
- DUK_ASSERT_TOP(ctx, 2); /* [ array totalLength ] */
- duk_get_prop_index(ctx, 0, (duk_uarridx_t) i); /* -> [ array totalLength buf ] */
- h_bufobj = duk__require_bufobj_value(ctx, 2);
+ DUK_ASSERT_TOP(thr, 2); /* [ array totalLength ] */
+ duk_get_prop_index(thr, 0, (duk_uarridx_t) i); /* -> [ array totalLength buf ] */
+ h_bufobj = duk__require_bufobj_value(thr, 2);
DUK_ASSERT(h_bufobj != NULL);
total_length += h_bufobj->length;
- duk_pop(ctx);
+ if (DUK_UNLIKELY(total_length < h_bufobj->length)) {
+ DUK_DCERROR_RANGE_INVALID_ARGS(thr); /* Wrapped. */
+ }
+ duk_pop(thr);
}
/* In Node.js v0.12.1 a 1-element array is special and won't create a
* copy, this was fixed later so an explicit check no longer needed.
*/
/* User totalLength overrides a computed length, but we'll check
- * every copy in the copy loop. Note that duk_to_uint() can
+ * every copy in the copy loop. Note that duk_to_int() can
* technically have arbitrary side effects so we need to recheck
* the buffers in the copy loop.
*/
- if (!duk_is_undefined(ctx, 1) && n > 0) {
+ if (!duk_is_undefined(thr, 1) && n > 0) {
/* For n == 0, Node.js ignores totalLength argument and
* returns a zero length buffer.
*/
- total_length = duk_to_int(ctx, 1);
- }
- if (total_length < 0) {
- DUK_DCERROR_RANGE_INVALID_ARGS(thr);
+ duk_int_t total_length_signed;
+ total_length_signed = duk_to_int(thr, 1);
+ if (total_length_signed < 0) {
+ DUK_DCERROR_RANGE_INVALID_ARGS(thr);
+ }
+ total_length = (duk_uint_t) total_length_signed;
}
- h_bufres = duk_push_bufobj_raw(ctx,
+ h_bufres = duk_push_bufobj_raw(thr,
DUK_HOBJECT_FLAG_EXTENSIBLE |
DUK_HOBJECT_FLAG_BUFOBJ |
DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_UINT8ARRAY),
DUK_BIDX_NODEJS_BUFFER_PROTOTYPE);
DUK_ASSERT(h_bufres != NULL);
- p = (duk_uint8_t *) duk_push_fixed_buffer_zero(ctx, total_length); /* must be zeroed, all bytes not necessarily written over */
+ p = (duk_uint8_t *) duk_push_fixed_buffer_zero(thr, total_length); /* must be zeroed, all bytes not necessarily written over */
DUK_ASSERT(p != NULL);
- space_left = total_length;
+ space_left = (duk_size_t) total_length;
for (i = 0; i < n; i++) {
- DUK_ASSERT_TOP(ctx, 4); /* [ array totalLength bufres buf ] */
+ DUK_ASSERT_TOP(thr, 4); /* [ array totalLength bufres buf ] */
- duk_get_prop_index(ctx, 0, (duk_uarridx_t) i);
- h_bufobj = duk__require_bufobj_value(ctx, 4);
+ duk_get_prop_index(thr, 0, (duk_uarridx_t) i);
+ h_bufobj = duk__require_bufobj_value(thr, 4);
DUK_ASSERT(h_bufobj != NULL);
copy_size = h_bufobj->length;
@@ -26934,16 +28056,16 @@ DUK_INTERNAL duk_ret_t duk_bi_nodejs_buffer_concat(duk_context *ctx) {
p += copy_size;
space_left -= copy_size;
- duk_pop(ctx);
+ duk_pop(thr);
}
- h_val = duk_known_hbuffer(ctx, -1);
+ h_val = duk_known_hbuffer(thr, -1);
- duk__set_bufobj_buffer(ctx, h_bufres, h_val);
+ duk__set_bufobj_buffer(thr, h_bufres, h_val);
h_bufres->is_typedarray = 1;
DUK_ASSERT_HBUFOBJ_VALID(h_bufres);
- duk_pop(ctx); /* pop plain buffer, now reachable through h_bufres */
+ duk_pop(thr); /* pop plain buffer, now reachable through h_bufres */
return 1; /* return h_bufres */
}
@@ -26974,9 +28096,8 @@ DUK_INTERNAL duk_ret_t duk_bi_nodejs_buffer_concat(duk_context *ctx) {
#define DUK__FLD_TYPEDARRAY (1 << 5)
/* XXX: split into separate functions for each field type? */
-DUK_INTERNAL duk_ret_t duk_bi_buffer_readfield(duk_context *ctx) {
- duk_hthread *thr;
- duk_small_int_t magic = (duk_small_int_t) duk_get_current_magic(ctx);
+DUK_INTERNAL duk_ret_t duk_bi_buffer_readfield(duk_hthread *thr) {
+ duk_small_int_t magic = (duk_small_int_t) duk_get_current_magic(thr);
duk_small_int_t magic_ftype;
duk_small_int_t magic_bigendian;
duk_small_int_t magic_signed;
@@ -26991,15 +28112,12 @@ DUK_INTERNAL duk_ret_t duk_bi_buffer_readfield(duk_context *ctx) {
duk_uint8_t *buf;
duk_double_union du;
- thr = (duk_hthread *) ctx;
- DUK_UNREF(thr);
-
magic_ftype = magic & 0x0007;
magic_bigendian = magic & 0x0008;
magic_signed = magic & 0x0010;
magic_typedarray = magic & 0x0020;
- h_this = duk__require_bufobj_this(ctx); /* XXX: very inefficient for plain buffers */
+ h_this = duk__require_bufobj_this(thr); /* XXX: very inefficient for plain buffers */
DUK_ASSERT(h_this != NULL);
buffer_length = h_this->length;
@@ -27011,12 +28129,12 @@ DUK_INTERNAL duk_ret_t duk_bi_buffer_readfield(duk_context *ctx) {
if (magic_typedarray) {
no_assert = 0;
#if defined(DUK_USE_INTEGER_LE)
- endswap = !duk_to_boolean(ctx, 1); /* 1=little endian */
+ endswap = !duk_to_boolean(thr, 1); /* 1=little endian */
#else
- endswap = duk_to_boolean(ctx, 1); /* 1=little endian */
+ endswap = duk_to_boolean(thr, 1); /* 1=little endian */
#endif
} else {
- no_assert = duk_to_boolean(ctx, (magic_ftype == DUK__FLD_VARINT) ? 2 : 1);
+ no_assert = duk_to_boolean(thr, (magic_ftype == DUK__FLD_VARINT) ? 2 : 1);
#if defined(DUK_USE_INTEGER_LE)
endswap = magic_bigendian;
#else
@@ -27028,7 +28146,7 @@ DUK_INTERNAL duk_ret_t duk_bi_buffer_readfield(duk_context *ctx) {
* This ensures we can add a small byte length (1-8) to the offset in
* bound checks and not wrap.
*/
- offset_signed = duk_to_int(ctx, 0);
+ offset_signed = duk_to_int(thr, 0);
offset = (duk_uint_t) offset_signed;
if (offset_signed < 0) {
goto fail_bounds;
@@ -27069,9 +28187,9 @@ DUK_INTERNAL duk_ret_t duk_bi_buffer_readfield(duk_context *ctx) {
}
tmp = buf[offset];
if (magic_signed) {
- duk_push_int(ctx, (duk_int_t) ((duk_int8_t) tmp));
+ duk_push_int(thr, (duk_int_t) ((duk_int8_t) tmp));
} else {
- duk_push_uint(ctx, (duk_uint_t) tmp);
+ duk_push_uint(thr, (duk_uint_t) tmp);
}
break;
}
@@ -27086,9 +28204,9 @@ DUK_INTERNAL duk_ret_t duk_bi_buffer_readfield(duk_context *ctx) {
tmp = DUK_BSWAP16(tmp);
}
if (magic_signed) {
- duk_push_int(ctx, (duk_int_t) ((duk_int16_t) tmp));
+ duk_push_int(thr, (duk_int_t) ((duk_int16_t) tmp));
} else {
- duk_push_uint(ctx, (duk_uint_t) tmp);
+ duk_push_uint(thr, (duk_uint_t) tmp);
}
break;
}
@@ -27103,9 +28221,9 @@ DUK_INTERNAL duk_ret_t duk_bi_buffer_readfield(duk_context *ctx) {
tmp = DUK_BSWAP32(tmp);
}
if (magic_signed) {
- duk_push_int(ctx, (duk_int_t) ((duk_int32_t) tmp));
+ duk_push_int(thr, (duk_int_t) ((duk_int32_t) tmp));
} else {
- duk_push_uint(ctx, (duk_uint_t) tmp);
+ duk_push_uint(thr, (duk_uint_t) tmp);
}
break;
}
@@ -27120,7 +28238,7 @@ DUK_INTERNAL duk_ret_t duk_bi_buffer_readfield(duk_context *ctx) {
tmp = DUK_BSWAP32(tmp);
du.ui[0] = tmp;
}
- duk_push_number(ctx, (duk_double_t) du.f[0]);
+ duk_push_number(thr, (duk_double_t) du.f[0]);
break;
}
case DUK__FLD_DOUBLE: {
@@ -27131,7 +28249,7 @@ DUK_INTERNAL duk_ret_t duk_bi_buffer_readfield(duk_context *ctx) {
if (endswap) {
DUK_DBLUNION_BSWAP64(&du);
}
- duk_push_number(ctx, (duk_double_t) du.d);
+ duk_push_number(thr, (duk_double_t) du.d);
break;
}
case DUK__FLD_VARINT: {
@@ -27149,7 +28267,7 @@ DUK_INTERNAL duk_ret_t duk_bi_buffer_readfield(duk_context *ctx) {
#endif
const duk_uint8_t *p;
- field_bytelen = duk_get_int(ctx, 1); /* avoid side effects! */
+ field_bytelen = duk_get_int(thr, 1); /* avoid side effects! */
if (field_bytelen < 1 || field_bytelen > 6) {
goto fail_field_length;
}
@@ -27185,11 +28303,11 @@ DUK_INTERNAL duk_ret_t duk_bi_buffer_readfield(duk_context *ctx) {
if (magic_signed) {
/* Shift to sign extend. */
- shift_tmp = 64 - (field_bytelen * 8);
+ shift_tmp = (duk_small_uint_t) (64U - (duk_small_uint_t) field_bytelen * 8U);
tmp = (tmp << shift_tmp) >> shift_tmp;
}
- duk_push_i64(ctx, tmp);
+ duk_push_i64(thr, tmp);
#else
highbyte = p[i];
if (magic_signed && (highbyte & 0x80) != 0) {
@@ -27207,7 +28325,7 @@ DUK_INTERNAL duk_ret_t duk_bi_buffer_readfield(duk_context *ctx) {
tmp = (tmp * 256.0) + (duk_double_t) p[i];
}
- duk_push_number(ctx, tmp);
+ duk_push_number(thr, tmp);
#endif
break;
}
@@ -27225,7 +28343,7 @@ DUK_INTERNAL duk_ret_t duk_bi_buffer_readfield(duk_context *ctx) {
/* Node.js return value for noAssert out-of-bounds reads is
* usually (but not always) NaN. Return NaN consistently.
*/
- duk_push_nan(ctx);
+ duk_push_nan(thr);
return 1;
}
DUK_DCERROR_RANGE_INVALID_ARGS(thr);
@@ -27234,9 +28352,8 @@ DUK_INTERNAL duk_ret_t duk_bi_buffer_readfield(duk_context *ctx) {
#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;
- duk_small_int_t magic = (duk_small_int_t) duk_get_current_magic(ctx);
+DUK_INTERNAL duk_ret_t duk_bi_buffer_writefield(duk_hthread *thr) {
+ duk_small_int_t magic = (duk_small_int_t) duk_get_current_magic(thr);
duk_small_int_t magic_ftype;
duk_small_int_t magic_bigendian;
duk_small_int_t magic_signed;
@@ -27252,16 +28369,13 @@ DUK_INTERNAL duk_ret_t duk_bi_buffer_writefield(duk_context *ctx) {
duk_double_union du;
duk_int_t nbytes = 0;
- thr = (duk_hthread *) ctx;
- DUK_UNREF(thr);
-
magic_ftype = magic & 0x0007;
magic_bigendian = magic & 0x0008;
magic_signed = magic & 0x0010;
magic_typedarray = magic & 0x0020;
DUK_UNREF(magic_signed);
- h_this = duk__require_bufobj_this(ctx); /* XXX: very inefficient for plain buffers */
+ h_this = duk__require_bufobj_this(thr); /* XXX: very inefficient for plain buffers */
DUK_ASSERT(h_this != NULL);
buffer_length = h_this->length;
@@ -27273,13 +28387,13 @@ DUK_INTERNAL duk_ret_t duk_bi_buffer_writefield(duk_context *ctx) {
if (magic_typedarray) {
no_assert = 0;
#if defined(DUK_USE_INTEGER_LE)
- endswap = !duk_to_boolean(ctx, 2); /* 1=little endian */
+ endswap = !duk_to_boolean(thr, 2); /* 1=little endian */
#else
- endswap = duk_to_boolean(ctx, 2); /* 1=little endian */
+ endswap = duk_to_boolean(thr, 2); /* 1=little endian */
#endif
- duk_swap(ctx, 0, 1); /* offset/value order different from Node.js */
+ duk_swap(thr, 0, 1); /* offset/value order different from Node.js */
} else {
- no_assert = duk_to_boolean(ctx, (magic_ftype == DUK__FLD_VARINT) ? 3 : 2);
+ no_assert = duk_to_boolean(thr, (magic_ftype == DUK__FLD_VARINT) ? 3 : 2);
#if defined(DUK_USE_INTEGER_LE)
endswap = magic_bigendian;
#else
@@ -27291,7 +28405,7 @@ DUK_INTERNAL duk_ret_t duk_bi_buffer_writefield(duk_context *ctx) {
* This ensures we can add a small byte length (1-8) to the offset in
* bound checks and not wrap.
*/
- offset_signed = duk_to_int(ctx, 1);
+ offset_signed = duk_to_int(thr, 1);
offset = (duk_uint_t) offset_signed;
/* We need 'nbytes' even for a failed offset; return value must be
@@ -27301,7 +28415,7 @@ DUK_INTERNAL duk_ret_t duk_bi_buffer_writefield(duk_context *ctx) {
DUK_ASSERT(magic_ftype >= 0 && magic_ftype < (duk_small_int_t) (sizeof(duk__buffer_nbytes_from_fldtype) / sizeof(duk_uint8_t)));
nbytes = duk__buffer_nbytes_from_fldtype[magic_ftype];
} else {
- nbytes = duk_get_int(ctx, 2);
+ nbytes = duk_get_int(thr, 2);
if (nbytes < 1 || nbytes > 6) {
goto fail_field_length;
}
@@ -27316,7 +28430,7 @@ DUK_INTERNAL duk_ret_t duk_bi_buffer_writefield(duk_context *ctx) {
DUK_DDD(DUK_DDDPRINT("writefield, value=%!T, buffer_length=%ld, offset=%ld, no_assert=%d, "
"magic=%04x, magic_fieldtype=%d, magic_bigendian=%d, magic_signed=%d, "
"endswap=%d",
- duk_get_tval(ctx, 0), (long) buffer_length, (long) offset, (int) no_assert,
+ duk_get_tval(thr, 0), (long) buffer_length, (long) offset, (int) no_assert,
(unsigned int) magic, (int) magic_ftype, (int) (magic_bigendian >> 3),
(int) (magic_signed >> 4), (int) endswap));
@@ -27324,7 +28438,7 @@ DUK_INTERNAL duk_ret_t duk_bi_buffer_writefield(duk_context *ctx) {
* the field type specific coercion below can't have side effects
* that would invalidate check_length.
*/
- duk_to_number(ctx, 0);
+ duk_to_number(thr, 0);
/* Update 'buffer_length' to be the effective, safe limit which
* takes into account the underlying buffer. This value will be
@@ -27352,7 +28466,7 @@ DUK_INTERNAL duk_ret_t duk_bi_buffer_writefield(duk_context *ctx) {
goto fail_bounds;
}
/* sign doesn't matter when writing */
- buf[offset] = (duk_uint8_t) duk_to_uint32(ctx, 0);
+ buf[offset] = (duk_uint8_t) duk_to_uint32(thr, 0);
break;
}
case DUK__FLD_16BIT: {
@@ -27360,7 +28474,7 @@ DUK_INTERNAL duk_ret_t duk_bi_buffer_writefield(duk_context *ctx) {
if (offset + 2U > check_length) {
goto fail_bounds;
}
- tmp = (duk_uint16_t) duk_to_uint32(ctx, 0);
+ tmp = (duk_uint16_t) duk_to_uint32(thr, 0);
if (endswap) {
tmp = DUK_BSWAP16(tmp);
}
@@ -27374,7 +28488,7 @@ DUK_INTERNAL duk_ret_t duk_bi_buffer_writefield(duk_context *ctx) {
if (offset + 4U > check_length) {
goto fail_bounds;
}
- tmp = (duk_uint32_t) duk_to_uint32(ctx, 0);
+ tmp = (duk_uint32_t) duk_to_uint32(thr, 0);
if (endswap) {
tmp = DUK_BSWAP32(tmp);
}
@@ -27388,7 +28502,7 @@ DUK_INTERNAL duk_ret_t duk_bi_buffer_writefield(duk_context *ctx) {
if (offset + 4U > check_length) {
goto fail_bounds;
}
- du.f[0] = (duk_float_t) duk_to_number(ctx, 0);
+ du.f[0] = (duk_float_t) duk_to_number(thr, 0);
if (endswap) {
tmp = du.ui[0];
tmp = DUK_BSWAP32(tmp);
@@ -27402,7 +28516,7 @@ DUK_INTERNAL duk_ret_t duk_bi_buffer_writefield(duk_context *ctx) {
if (offset + 8U > check_length) {
goto fail_bounds;
}
- du.d = (duk_double_t) duk_to_number(ctx, 0);
+ du.d = (duk_double_t) duk_to_number(thr, 0);
if (endswap) {
DUK_DBLUNION_BSWAP64(&du);
}
@@ -27452,7 +28566,7 @@ DUK_INTERNAL duk_ret_t duk_bi_buffer_writefield(duk_context *ctx) {
*/
#if defined(DUK_USE_64BIT_OPS)
- tmp = (duk_int64_t) duk_to_number(ctx, 0);
+ tmp = (duk_int64_t) duk_to_number(thr, 0);
p = (duk_uint8_t *) (buf + offset);
do {
i += i_step;
@@ -27461,7 +28575,7 @@ DUK_INTERNAL duk_ret_t duk_bi_buffer_writefield(duk_context *ctx) {
tmp = tmp >> 8; /* unnecessary shift for last byte */
} while (i != i_end);
#else
- tmp = duk_to_number(ctx, 0);
+ tmp = duk_to_number(thr, 0);
p = (duk_uint8_t *) (buf + offset);
do {
i += i_step;
@@ -27487,7 +28601,7 @@ DUK_INTERNAL duk_ret_t duk_bi_buffer_writefield(duk_context *ctx) {
*/
return 0;
}
- duk_push_uint(ctx, offset + nbytes);
+ duk_push_uint(thr, offset + (duk_uint_t) nbytes);
return 1;
fail_neutered:
@@ -27503,7 +28617,7 @@ DUK_INTERNAL duk_ret_t duk_bi_buffer_writefield(duk_context *ctx) {
if (magic_typedarray) {
return 0;
}
- duk_push_uint(ctx, offset + nbytes);
+ duk_push_uint(thr, offset + (duk_uint_t) nbytes);
return 1;
}
DUK_DCERROR_RANGE_INVALID_ARGS(thr);
@@ -27515,10 +28629,10 @@ DUK_INTERNAL duk_ret_t duk_bi_buffer_writefield(duk_context *ctx) {
*/
#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)
-DUK_LOCAL duk_hbufobj *duk__autospawn_arraybuffer(duk_context *ctx, duk_hbuffer *h_buf) {
+DUK_LOCAL duk_hbufobj *duk__autospawn_arraybuffer(duk_hthread *thr, duk_hbuffer *h_buf) {
duk_hbufobj *h_res;
- h_res = duk_push_bufobj_raw(ctx,
+ h_res = duk_push_bufobj_raw(thr,
DUK_HOBJECT_FLAG_EXTENSIBLE |
DUK_HOBJECT_FLAG_BUFOBJ |
DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_ARRAYBUFFER),
@@ -27526,20 +28640,20 @@ DUK_LOCAL duk_hbufobj *duk__autospawn_arraybuffer(duk_context *ctx, duk_hbuffer
DUK_ASSERT(h_res != NULL);
DUK_UNREF(h_res);
- duk__set_bufobj_buffer(ctx, h_res, h_buf);
+ duk__set_bufobj_buffer(thr, h_res, h_buf);
DUK_ASSERT_HBUFOBJ_VALID(h_res);
DUK_ASSERT(h_res->buf_prop == NULL);
return h_res;
}
-DUK_INTERNAL duk_ret_t duk_bi_typedarray_buffer_getter(duk_context *ctx) {
+DUK_INTERNAL duk_ret_t duk_bi_typedarray_buffer_getter(duk_hthread *thr) {
duk_hbufobj *h_bufobj;
- h_bufobj = (duk_hbufobj *) duk__getrequire_bufobj_this(ctx, DUK__BUFOBJ_FLAG_THROW /*flags*/);
+ h_bufobj = (duk_hbufobj *) duk__getrequire_bufobj_this(thr, DUK__BUFOBJ_FLAG_THROW /*flags*/);
DUK_ASSERT(h_bufobj != NULL);
if (DUK_HEAPHDR_IS_BUFFER((duk_heaphdr *) h_bufobj)) {
DUK_DD(DUK_DDPRINT("autospawn ArrayBuffer for plain buffer"));
- (void) duk__autospawn_arraybuffer(ctx, (duk_hbuffer *) h_bufobj);
+ (void) duk__autospawn_arraybuffer(thr, (duk_hbuffer *) h_bufobj);
return 1;
} else {
if (h_bufobj->buf_prop == NULL &&
@@ -27548,7 +28662,7 @@ DUK_INTERNAL duk_ret_t duk_bi_typedarray_buffer_getter(duk_context *ctx) {
duk_hbufobj *h_arrbuf;
DUK_DD(DUK_DDPRINT("autospawn ArrayBuffer for typed array or DataView"));
- h_arrbuf = duk__autospawn_arraybuffer(ctx, h_bufobj->buf);
+ h_arrbuf = duk__autospawn_arraybuffer(thr, h_bufobj->buf);
if (h_bufobj->buf_prop == NULL) {
/* Must recheck buf_prop, in case ArrayBuffer
@@ -27573,68 +28687,68 @@ DUK_INTERNAL duk_ret_t duk_bi_typedarray_buffer_getter(duk_context *ctx) {
/* Left on stack; pushed for the second time below (OK). */
}
if (h_bufobj->buf_prop) {
- duk_push_hobject(ctx, h_bufobj->buf_prop);
+ duk_push_hobject(thr, h_bufobj->buf_prop);
return 1;
}
}
return 0;
}
-DUK_INTERNAL duk_ret_t duk_bi_typedarray_byteoffset_getter(duk_context *ctx) {
+DUK_INTERNAL duk_ret_t duk_bi_typedarray_byteoffset_getter(duk_hthread *thr) {
duk_hbufobj *h_bufobj;
- h_bufobj = (duk_hbufobj *) duk__getrequire_bufobj_this(ctx, DUK__BUFOBJ_FLAG_THROW /*flags*/);
+ h_bufobj = (duk_hbufobj *) duk__getrequire_bufobj_this(thr, DUK__BUFOBJ_FLAG_THROW /*flags*/);
DUK_ASSERT(h_bufobj != NULL);
if (DUK_HEAPHDR_IS_BUFFER((duk_heaphdr *) h_bufobj)) {
- duk_push_uint(ctx, 0);
+ duk_push_uint(thr, 0);
} else {
/* If neutered must return 0; offset is zeroed during
* neutering.
*/
- duk_push_uint(ctx, h_bufobj->offset);
+ duk_push_uint(thr, h_bufobj->offset);
}
return 1;
}
-DUK_INTERNAL duk_ret_t duk_bi_typedarray_bytelength_getter(duk_context *ctx) {
+DUK_INTERNAL duk_ret_t duk_bi_typedarray_bytelength_getter(duk_hthread *thr) {
duk_hbufobj *h_bufobj;
- h_bufobj = (duk_hbufobj *) duk__getrequire_bufobj_this(ctx, DUK__BUFOBJ_FLAG_THROW /*flags*/);
+ h_bufobj = (duk_hbufobj *) duk__getrequire_bufobj_this(thr, DUK__BUFOBJ_FLAG_THROW /*flags*/);
DUK_ASSERT(h_bufobj != NULL);
if (DUK_HEAPHDR_IS_BUFFER((duk_heaphdr *) h_bufobj)) {
duk_hbuffer *h_buf;
h_buf = (duk_hbuffer *) h_bufobj;
DUK_ASSERT(DUK_HBUFFER_GET_SIZE(h_buf) <= DUK_UINT_MAX); /* Buffer limits. */
- duk_push_uint(ctx, (duk_uint_t) DUK_HBUFFER_GET_SIZE(h_buf));
+ duk_push_uint(thr, (duk_uint_t) DUK_HBUFFER_GET_SIZE(h_buf));
} else {
/* If neutered must return 0; length is zeroed during
* neutering.
*/
- duk_push_uint(ctx, h_bufobj->length);
+ duk_push_uint(thr, h_bufobj->length);
}
return 1;
}
#else /* DUK_USE_BUFFEROBJECT_SUPPORT */
/* No .buffer getter without ArrayBuffer support. */
#if 0
-DUK_INTERNAL duk_ret_t duk_bi_typedarray_buffer_getter(duk_context *ctx) {
+DUK_INTERNAL duk_ret_t duk_bi_typedarray_buffer_getter(duk_hthread *thr) {
return 0;
}
#endif
-DUK_INTERNAL duk_ret_t duk_bi_typedarray_byteoffset_getter(duk_context *ctx) {
- duk_push_uint(ctx, 0);
+DUK_INTERNAL duk_ret_t duk_bi_typedarray_byteoffset_getter(duk_hthread *thr) {
+ duk_push_uint(thr, 0);
return 1;
}
-DUK_INTERNAL duk_ret_t duk_bi_typedarray_bytelength_getter(duk_context *ctx) {
+DUK_INTERNAL duk_ret_t duk_bi_typedarray_bytelength_getter(duk_hthread *thr) {
duk_hbuffer *h_buf;
/* XXX: helper? */
- duk_push_this(ctx);
- h_buf = duk_require_hbuffer(ctx, -1);
- duk_push_uint(ctx, DUK_HBUFFER_GET_SIZE(h_buf));
+ duk_push_this(thr);
+ h_buf = duk_require_hbuffer(thr, -1);
+ duk_push_uint(thr, DUK_HBUFFER_GET_SIZE(h_buf));
return 1;
}
#endif /* DUK_USE_BUFFEROBJECT_SUPPORT */
@@ -27672,10 +28786,10 @@ DUK_INTERNAL duk_ret_t duk_bi_typedarray_bytelength_getter(duk_context *ctx) {
* Forward declarations
*/
-DUK_LOCAL_DECL duk_double_t duk__push_this_get_timeval_tzoffset(duk_context *ctx, duk_small_uint_t flags, duk_int_t *out_tzoffset);
-DUK_LOCAL_DECL duk_double_t duk__push_this_get_timeval(duk_context *ctx, duk_small_uint_t flags);
-DUK_LOCAL_DECL void duk__twodigit_year_fixup(duk_context *ctx, duk_idx_t idx_val);
-DUK_LOCAL_DECL duk_ret_t duk__set_this_timeval_from_dparts(duk_context *ctx, duk_double_t *dparts, duk_small_uint_t flags);
+DUK_LOCAL_DECL duk_double_t duk__push_this_get_timeval_tzoffset(duk_hthread *thr, duk_small_uint_t flags, duk_int_t *out_tzoffset);
+DUK_LOCAL_DECL duk_double_t duk__push_this_get_timeval(duk_hthread *thr, duk_small_uint_t flags);
+DUK_LOCAL_DECL void duk__twodigit_year_fixup(duk_hthread *thr, duk_idx_t idx_val);
+DUK_LOCAL_DECL duk_ret_t duk__set_this_timeval_from_dparts(duk_hthread *thr, duk_double_t *dparts, duk_small_uint_t flags);
/*
* Other file level defines
@@ -27839,7 +28953,7 @@ DUK_LOCAL const duk_uint32_t duk__parse_iso8601_control[] = {
*/
};
-DUK_LOCAL duk_bool_t duk__parse_string_iso8601_subset(duk_context *ctx, const char *str) {
+DUK_LOCAL duk_bool_t duk__parse_string_iso8601_subset(duk_hthread *thr, const char *str) {
duk_int_t parts[DUK__NUM_ISO8601_PARSER_PARTS];
duk_double_t dparts[DUK_DATE_IDX_NUM_PARTS];
duk_double_t d;
@@ -27887,7 +29001,7 @@ DUK_LOCAL duk_bool_t duk__parse_string_iso8601_subset(duk_context *ctx, const ch
}
} else {
duk_uint_fast32_t match_val;
- duk_small_int_t sep_idx;
+ duk_small_uint_t sep_idx;
if (ndigits <= 0) {
goto reject;
@@ -28011,7 +29125,7 @@ DUK_LOCAL duk_bool_t duk__parse_string_iso8601_subset(duk_context *ctx, const ch
}
d = duk_bi_date_get_timeval_from_dparts(dparts, 0 /*flags*/);
- duk_push_number(ctx, d);
+ duk_push_number(thr, d);
return 1;
}
@@ -28034,7 +29148,7 @@ DUK_LOCAL duk_bool_t duk__parse_string_iso8601_subset(duk_context *ctx, const ch
* UTC and '2012/01/01' as local time.
*/
-DUK_LOCAL duk_ret_t duk__parse_string(duk_context *ctx, const char *str) {
+DUK_LOCAL duk_ret_t duk__parse_string(duk_hthread *thr, const char *str) {
/* XXX: there is a small risk here: because the ISO 8601 parser is
* very loose, it may end up parsing some datetime values which
* would be better parsed with a platform specific parser.
@@ -28043,7 +29157,7 @@ DUK_LOCAL duk_ret_t duk__parse_string(duk_context *ctx, const char *str) {
DUK_ASSERT(str != NULL);
DUK_DDD(DUK_DDDPRINT("parse datetime from string '%s'", (const char *) str));
- if (duk__parse_string_iso8601_subset(ctx, str) != 0) {
+ if (duk__parse_string_iso8601_subset(thr, str) != 0) {
return 1;
}
@@ -28053,14 +29167,14 @@ DUK_LOCAL duk_ret_t duk__parse_string(duk_context *ctx, const char *str) {
* - Don't push anything on stack and return 0
*/
- if (DUK_USE_DATE_PARSE_STRING(ctx, str) != 0) {
+ if (DUK_USE_DATE_PARSE_STRING(thr, str) != 0) {
return 1;
}
#else
/* No platform-specific parsing, this is not an error. */
#endif
- duk_push_nan(ctx);
+ duk_push_nan(thr);
return 1;
}
@@ -28253,9 +29367,9 @@ DUK_LOCAL duk_double_t duk__make_day(duk_double_t year, duk_double_t month, duk_
return (duk_double_t) day_num + day;
}
-/* Split time value into parts. The time value is assumed to be an internal
- * one, i.e. finite, no fractions. Possible local time adjustment has already
- * been applied when reading the time value.
+/* Split time value into parts. The time value may contain fractions (it may
+ * come from duk_time_to_components() API call) which are truncated. Possible
+ * local time adjustment has already been applied when reading the time value.
*/
DUK_INTERNAL void duk_bi_date_timeval_to_parts(duk_double_t d, duk_int_t *parts, duk_double_t *dparts, duk_small_uint_t flags) {
duk_double_t d1, d2;
@@ -28274,7 +29388,8 @@ DUK_INTERNAL void duk_bi_date_timeval_to_parts(duk_double_t d, duk_int_t *parts,
duk_small_int_t arridx;
DUK_ASSERT(DUK_ISFINITE(d)); /* caller checks */
- DUK_ASSERT(DUK_FLOOR(d) == d); /* no fractions in internal time */
+ d = DUK_FLOOR(d); /* remove fractions if present */
+ DUK_ASSERT(DUK_FLOOR(d) == d);
/* The timevalue must be in valid Ecmascript range, but since a local
* time offset can be applied, we need to allow a +/- 24h leeway to
@@ -28284,7 +29399,7 @@ DUK_INTERNAL void duk_bi_date_timeval_to_parts(duk_double_t d, duk_int_t *parts,
DUK_UNREF(duk_bi_date_timeval_in_leeway_range);
DUK_ASSERT(duk_bi_date_timeval_in_leeway_range(d));
- /* these computations are guaranteed to be exact for the valid
+ /* These computations are guaranteed to be exact for the valid
* E5 time value range, assuming milliseconds without fractions.
*/
d1 = (duk_double_t) DUK_FMOD(d, (double) DUK_DATE_MSEC_DAY);
@@ -28540,21 +29655,20 @@ DUK_INTERNAL duk_double_t duk_bi_date_get_timeval_from_dparts(duk_double_t *dpar
* internal time value. At the end, stack is: [ ... this timeval ].
* Returns the time value. Local time adjustment is done if requested.
*/
-DUK_LOCAL duk_double_t duk__push_this_get_timeval_tzoffset(duk_context *ctx, duk_small_uint_t flags, duk_int_t *out_tzoffset) {
- duk_hthread *thr = (duk_hthread *) ctx;
+DUK_LOCAL duk_double_t duk__push_this_get_timeval_tzoffset(duk_hthread *thr, duk_small_uint_t flags, duk_int_t *out_tzoffset) {
duk_hobject *h;
duk_double_t d;
duk_int_t tzoffset = 0;
- duk_push_this(ctx);
- h = duk_get_hobject(ctx, -1); /* XXX: getter with class check, useful in built-ins */
+ duk_push_this(thr);
+ h = duk_get_hobject(thr, -1); /* XXX: getter with class check, useful in built-ins */
if (h == NULL || DUK_HOBJECT_GET_CLASS_NUMBER(h) != DUK_HOBJECT_CLASS_DATE) {
DUK_ERROR_TYPE(thr, "expected Date");
}
- duk_get_prop_stridx_short(ctx, -1, DUK_STRIDX_INT_VALUE);
- d = duk_to_number_m1(ctx);
- duk_pop(ctx);
+ duk_get_prop_stridx_short(thr, -1, DUK_STRIDX_INT_VALUE);
+ d = duk_to_number_m1(thr);
+ duk_pop(thr);
if (DUK_ISNAN(d)) {
if (flags & DUK_DATE_FLAG_NAN_TO_ZERO) {
@@ -28582,23 +29696,23 @@ DUK_LOCAL duk_double_t duk__push_this_get_timeval_tzoffset(duk_context *ctx, duk
return d;
}
-DUK_LOCAL duk_double_t duk__push_this_get_timeval(duk_context *ctx, duk_small_uint_t flags) {
- return duk__push_this_get_timeval_tzoffset(ctx, flags, NULL);
+DUK_LOCAL duk_double_t duk__push_this_get_timeval(duk_hthread *thr, duk_small_uint_t flags) {
+ return duk__push_this_get_timeval_tzoffset(thr, flags, NULL);
}
/* Set timeval to 'this' from dparts, push the new time value onto the
* 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) {
+DUK_LOCAL duk_ret_t duk__set_this_timeval_from_dparts(duk_hthread *thr, duk_double_t *dparts, duk_small_uint_t flags) {
duk_double_t d;
/* [ ... this ] */
d = duk_bi_date_get_timeval_from_dparts(dparts, flags);
- duk_push_number(ctx, d); /* -> [ ... this timeval_new ] */
- duk_dup_top(ctx); /* -> [ ... this timeval_new timeval_new ] */
- duk_put_prop_stridx_short(ctx, -3, DUK_STRIDX_INT_VALUE);
+ duk_push_number(thr, d); /* -> [ ... this timeval_new ] */
+ duk_dup_top(thr); /* -> [ ... this timeval_new timeval_new ] */
+ duk_put_prop_stridx_short(thr, -3, DUK_STRIDX_INT_VALUE);
/* stack top: new time value, return 1 to allow tail calls */
return 1;
@@ -28628,13 +29742,23 @@ DUK_LOCAL void duk__format_parts_iso8601(duk_int_t *parts, duk_int_t tzoffset, d
/* tzoffset seconds are dropped; 16 bits suffice for
* time offset in minutes
*/
+ const char *fmt;
+ duk_small_int_t tmp, arg_hours, arg_minutes;
+
if (tzoffset >= 0) {
- duk_small_int_t tmp = tzoffset / 60;
- DUK_SNPRINTF(tzstr, sizeof(tzstr), "+%02d:%02d", (int) (tmp / 60), (int) (tmp % 60));
+ tmp = tzoffset;
+ fmt = "+%02d:%02d";
} else {
- duk_small_int_t tmp = -tzoffset / 60;
- DUK_SNPRINTF(tzstr, sizeof(tzstr), "-%02d:%02d", (int) (tmp / 60), (int) (tmp % 60));
+ tmp = -tzoffset;
+ fmt = "-%02d:%02d";
}
+ tmp = tmp / 60;
+ arg_hours = tmp / 60;
+ arg_minutes = tmp % 60;
+ DUK_ASSERT(arg_hours <= 24); /* Even less is actually guaranteed for a valid tzoffset. */
+ arg_hours = arg_hours & 0x3f; /* For [0,24] this is a no-op, but fixes GCC 7 warning, see https://github.com/svaarala/duktape/issues/1602. */
+
+ DUK_SNPRINTF(tzstr, sizeof(tzstr), fmt, (int) arg_hours, (int) arg_minutes);
tzstr[sizeof(tzstr) - 1] = (char) 0;
} else {
tzstr[0] = DUK_ASC_UC_Z;
@@ -28665,7 +29789,7 @@ DUK_LOCAL void duk__format_parts_iso8601(duk_int_t *parts, duk_int_t tzoffset, d
* internal time value, and format date and/or time in a few formats.
* Return value allows tail calls.
*/
-DUK_LOCAL duk_ret_t duk__to_string_helper(duk_context *ctx, duk_small_uint_t flags) {
+DUK_LOCAL duk_ret_t duk__to_string_helper(duk_hthread *thr, duk_small_uint_t flags) {
duk_double_t d;
duk_int_t parts[DUK_DATE_IDX_NUM_PARTS];
duk_int_t tzoffset; /* seconds, doesn't fit into 16 bits */
@@ -28674,9 +29798,9 @@ DUK_LOCAL duk_ret_t duk__to_string_helper(duk_context *ctx, duk_small_uint_t fla
DUK_UNREF(rc); /* unreferenced with some options */
- d = duk__push_this_get_timeval_tzoffset(ctx, flags, &tzoffset);
+ d = duk__push_this_get_timeval_tzoffset(thr, flags, &tzoffset);
if (DUK_ISNAN(d)) {
- duk_push_hstring_stridx(ctx, DUK_STRIDX_INVALID_DATE);
+ duk_push_hstring_stridx(thr, DUK_STRIDX_INVALID_DATE);
return 1;
}
DUK_ASSERT(DUK_ISFINITE(d));
@@ -28697,7 +29821,7 @@ DUK_LOCAL duk_ret_t duk__to_string_helper(duk_context *ctx, duk_small_uint_t fla
* - Don't push anything and return 0
*/
- rc = DUK_USE_DATE_FORMAT_STRING(ctx, parts, tzoffset, flags);
+ rc = DUK_USE_DATE_FORMAT_STRING(thr, parts, tzoffset, flags);
if (rc != 0) {
return 1;
}
@@ -28712,7 +29836,7 @@ DUK_LOCAL duk_ret_t duk__to_string_helper(duk_context *ctx, duk_small_uint_t fla
* is shared.
*/
duk__format_parts_iso8601(parts, tzoffset, flags, buf);
- duk_push_string(ctx, (const char *) buf);
+ duk_push_string(thr, (const char *) buf);
return 1;
}
@@ -28721,7 +29845,7 @@ DUK_LOCAL duk_ret_t duk__to_string_helper(duk_context *ctx, duk_small_uint_t fla
* local time), push a specified component as a return value to the
* 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_LOCAL duk_ret_t duk__get_part_helper(duk_hthread *thr, duk_small_uint_t flags_and_idx) {
duk_double_t d;
duk_int_t parts[DUK_DATE_IDX_NUM_PARTS];
duk_small_uint_t idx_part = (duk_small_uint_t) (flags_and_idx >> DUK_DATE_FLAG_VALUE_SHIFT); /* unpack args */
@@ -28729,9 +29853,9 @@ DUK_LOCAL duk_ret_t duk__get_part_helper(duk_context *ctx, duk_small_uint_t flag
DUK_ASSERT_DISABLE(idx_part >= 0); /* unsigned */
DUK_ASSERT(idx_part < DUK_DATE_IDX_NUM_PARTS);
- d = duk__push_this_get_timeval(ctx, flags_and_idx);
+ d = duk__push_this_get_timeval(thr, flags_and_idx);
if (DUK_ISNAN(d)) {
- duk_push_nan(ctx);
+ duk_push_nan(thr);
return 1;
}
DUK_ASSERT(DUK_ISFINITE(d));
@@ -28742,7 +29866,7 @@ DUK_LOCAL duk_ret_t duk__get_part_helper(duk_context *ctx, duk_small_uint_t flag
* only in certain cases. The legacy getYear() getter applies -1900
* unconditionally.
*/
- duk_push_int(ctx, (flags_and_idx & DUK_DATE_FLAG_SUB1900) ? parts[idx_part] - 1900 : parts[idx_part]);
+ duk_push_int(thr, (flags_and_idx & DUK_DATE_FLAG_SUB1900) ? parts[idx_part] - 1900 : parts[idx_part]);
return 1;
}
@@ -28753,7 +29877,7 @@ DUK_LOCAL duk_ret_t duk__get_part_helper(duk_context *ctx, duk_small_uint_t flag
* new time value as a return value to the value stack and return 1
* (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_LOCAL duk_ret_t duk__set_part_helper(duk_hthread *thr, duk_small_uint_t flags_and_maxnargs) {
duk_double_t d;
duk_int_t parts[DUK_DATE_IDX_NUM_PARTS];
duk_double_t dparts[DUK_DATE_IDX_NUM_PARTS];
@@ -28762,8 +29886,8 @@ DUK_LOCAL duk_ret_t duk__set_part_helper(duk_context *ctx, duk_small_uint_t flag
duk_small_uint_t idx_first, idx;
duk_small_uint_t i;
- nargs = duk_get_top(ctx);
- d = duk__push_this_get_timeval(ctx, flags_and_maxnargs);
+ nargs = duk_get_top(thr);
+ d = duk__push_this_get_timeval(thr, flags_and_maxnargs);
DUK_ASSERT(DUK_ISFINITE(d) || DUK_ISNAN(d));
if (DUK_ISFINITE(d)) {
@@ -28818,10 +29942,10 @@ DUK_LOCAL duk_ret_t duk__set_part_helper(duk_context *ctx, duk_small_uint_t flag
DUK_ASSERT(idx < DUK_DATE_IDX_NUM_PARTS);
if (idx == DUK_DATE_IDX_YEAR && (flags_and_maxnargs & DUK_DATE_FLAG_YEAR_FIXUP)) {
- duk__twodigit_year_fixup(ctx, (duk_idx_t) i);
+ duk__twodigit_year_fixup(thr, (duk_idx_t) i);
}
- dparts[idx] = duk_to_number(ctx, i);
+ dparts[idx] = duk_to_number(thr, (duk_idx_t) i);
if (idx == DUK_DATE_IDX_DAY) {
/* Day-of-month is one-based in the API, but zero-based
@@ -28841,10 +29965,10 @@ DUK_LOCAL duk_ret_t duk__set_part_helper(duk_context *ctx, duk_small_uint_t flag
* for part setters.
*/
if (DUK_ISFINITE(d)) {
- return duk__set_this_timeval_from_dparts(ctx, dparts, flags_and_maxnargs);
+ return duk__set_this_timeval_from_dparts(thr, dparts, flags_and_maxnargs);
} else {
/* Internal timevalue is already NaN, so don't touch it. */
- duk_push_nan(ctx);
+ duk_push_nan(thr);
return 1;
}
}
@@ -28852,7 +29976,7 @@ DUK_LOCAL duk_ret_t duk__set_part_helper(duk_context *ctx, duk_small_uint_t flag
/* Apply ToNumber() to specified index; if ToInteger(val) in [0,99], add
* 1900 and replace value at idx_val.
*/
-DUK_LOCAL void duk__twodigit_year_fixup(duk_context *ctx, duk_idx_t idx_val) {
+DUK_LOCAL void duk__twodigit_year_fixup(duk_hthread *thr, duk_idx_t idx_val) {
duk_double_t d;
/* XXX: idx_val would fit into 16 bits, but using duk_small_uint_t
@@ -28860,25 +29984,25 @@ DUK_LOCAL void duk__twodigit_year_fixup(duk_context *ctx, duk_idx_t idx_val) {
*/
/* E5 Sections 15.9.3.1, B.2.4, B.2.5 */
- duk_to_number(ctx, idx_val);
- if (duk_is_nan(ctx, idx_val)) {
+ duk_to_number(thr, idx_val);
+ if (duk_is_nan(thr, idx_val)) {
return;
}
- duk_dup(ctx, idx_val);
- duk_to_int(ctx, -1);
- d = duk_get_number(ctx, -1); /* get as double to handle huge numbers correctly */
+ duk_dup(thr, idx_val);
+ duk_to_int(thr, -1);
+ d = duk_get_number(thr, -1); /* get as double to handle huge numbers correctly */
if (d >= 0.0 && d <= 99.0) {
d += 1900.0;
- duk_push_number(ctx, d);
- duk_replace(ctx, idx_val);
+ duk_push_number(thr, d);
+ duk_replace(thr, idx_val);
}
- duk_pop(ctx);
+ duk_pop(thr);
}
/* Set datetime parts from stack arguments, defaulting any missing values.
* Day-of-week is not set; it is not required when setting the time value.
*/
-DUK_LOCAL void duk__set_parts_from_args(duk_context *ctx, duk_double_t *dparts, duk_idx_t nargs) {
+DUK_LOCAL void duk__set_parts_from_args(duk_hthread *thr, duk_double_t *dparts, duk_idx_t nargs) {
duk_double_t d;
duk_small_uint_t i;
duk_small_uint_t idx;
@@ -28886,7 +30010,7 @@ DUK_LOCAL void duk__set_parts_from_args(duk_context *ctx, duk_double_t *dparts,
/* Causes a ToNumber() coercion, but doesn't break coercion order since
* year is coerced first anyway.
*/
- duk__twodigit_year_fixup(ctx, 0);
+ duk__twodigit_year_fixup(thr, 0);
/* There are at most 7 args, but we use 8 here so that also
* DUK_DATE_IDX_WEEKDAY gets initialized (to zero) to avoid the potential
@@ -28896,7 +30020,7 @@ DUK_LOCAL void duk__set_parts_from_args(duk_context *ctx, duk_double_t *dparts,
/* Note: rely on index ordering */
idx = DUK_DATE_IDX_YEAR + i;
if ((duk_idx_t) i < nargs) {
- d = duk_to_number(ctx, (duk_idx_t) i);
+ d = duk_to_number(thr, (duk_idx_t) i);
if (idx == DUK_DATE_IDX_DAY) {
/* Convert day from one-based to zero-based (internal). This may
* cause the day part to be negative, which is OK.
@@ -29053,9 +30177,9 @@ static duk_uint16_t duk__date_magics[] = {
DUK_DATE_FLAG_NAN_TO_ZERO + DUK_DATE_FLAG_YEAR_FIXUP + (3 << DUK_DATE_FLAG_VALUE_SHIFT),
};
-DUK_LOCAL duk_small_uint_t duk__date_get_indirect_magic(duk_context *ctx) {
- duk_small_int_t magicidx = (duk_small_uint_t) duk_get_current_magic(ctx);
- DUK_ASSERT(magicidx >= 0 && magicidx < (duk_small_int_t) (sizeof(duk__date_magics) / sizeof(duk_uint16_t)));
+DUK_LOCAL duk_small_uint_t duk__date_get_indirect_magic(duk_hthread *thr) {
+ duk_small_uint_t magicidx = (duk_small_uint_t) duk_get_current_magic(thr);
+ DUK_ASSERT(magicidx < (duk_small_int_t) (sizeof(duk__date_magics) / sizeof(duk_uint16_t)));
return (duk_small_uint_t) duk__date_magics[magicidx];
}
@@ -29064,15 +30188,15 @@ DUK_LOCAL duk_small_uint_t duk__date_get_indirect_magic(duk_context *ctx) {
* Constructor calls
*/
-DUK_INTERNAL duk_ret_t duk_bi_date_constructor(duk_context *ctx) {
- duk_idx_t nargs = duk_get_top(ctx);
- duk_bool_t is_cons = duk_is_constructor_call(ctx);
+DUK_INTERNAL duk_ret_t duk_bi_date_constructor(duk_hthread *thr) {
+ duk_idx_t nargs = duk_get_top(thr);
+ duk_bool_t is_cons = duk_is_constructor_call(thr);
duk_double_t dparts[DUK_DATE_IDX_NUM_PARTS];
duk_double_t d;
DUK_DDD(DUK_DDDPRINT("Date constructor, nargs=%ld, is_cons=%ld", (long) nargs, (long) is_cons));
- (void) duk_push_object_helper(ctx,
+ (void) duk_push_object_helper(thr,
DUK_HOBJECT_FLAG_EXTENSIBLE |
DUK_HOBJECT_FLAG_FASTREFS |
DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_DATE),
@@ -29083,43 +30207,43 @@ DUK_INTERNAL duk_ret_t duk_bi_date_constructor(duk_context *ctx) {
*/
if (nargs == 0 || !is_cons) {
- d = duk__timeclip(DUK_USE_DATE_GET_NOW(ctx));
- duk_push_number(ctx, d);
- duk_xdef_prop_stridx_short(ctx, -2, DUK_STRIDX_INT_VALUE, DUK_PROPDESC_FLAGS_W);
+ d = duk__timeclip(duk_time_get_ecmascript_time_nofrac(thr));
+ duk_push_number(thr, d);
+ duk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_INT_VALUE, DUK_PROPDESC_FLAGS_W);
if (!is_cons) {
/* called as a normal function: return new Date().toString() */
- duk_to_string(ctx, -1);
+ duk_to_string(thr, -1);
}
return 1;
} else if (nargs == 1) {
const char *str;
- duk_to_primitive(ctx, 0, DUK_HINT_NONE);
- str = duk_get_string_notsymbol(ctx, 0);
+ duk_to_primitive(thr, 0, DUK_HINT_NONE);
+ str = duk_get_string_notsymbol(thr, 0);
if (str) {
- duk__parse_string(ctx, str);
- duk_replace(ctx, 0); /* may be NaN */
+ duk__parse_string(thr, str);
+ duk_replace(thr, 0); /* may be NaN */
}
- d = duk__timeclip(duk_to_number(ctx, 0)); /* symbols fail here */
- duk_push_number(ctx, d);
- duk_xdef_prop_stridx_short(ctx, -2, DUK_STRIDX_INT_VALUE, DUK_PROPDESC_FLAGS_W);
+ d = duk__timeclip(duk_to_number(thr, 0)); /* symbols fail here */
+ duk_push_number(thr, d);
+ duk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_INT_VALUE, DUK_PROPDESC_FLAGS_W);
return 1;
}
- duk__set_parts_from_args(ctx, dparts, nargs);
+ duk__set_parts_from_args(thr, dparts, nargs);
/* Parts are in local time, convert when setting. */
- (void) duk__set_this_timeval_from_dparts(ctx, dparts, DUK_DATE_FLAG_LOCALTIME /*flags*/); /* -> [ ... this timeval ] */
- duk_pop(ctx); /* -> [ ... this ] */
+ (void) duk__set_this_timeval_from_dparts(thr, dparts, DUK_DATE_FLAG_LOCALTIME /*flags*/); /* -> [ ... this timeval ] */
+ duk_pop(thr); /* -> [ ... this ] */
return 1;
}
-DUK_INTERNAL duk_ret_t duk_bi_date_constructor_parse(duk_context *ctx) {
- return duk__parse_string(ctx, duk_to_string(ctx, 0));
+DUK_INTERNAL duk_ret_t duk_bi_date_constructor_parse(duk_hthread *thr) {
+ return duk__parse_string(thr, duk_to_string(thr, 0));
}
-DUK_INTERNAL duk_ret_t duk_bi_date_constructor_utc(duk_context *ctx) {
- duk_idx_t nargs = duk_get_top(ctx);
+DUK_INTERNAL duk_ret_t duk_bi_date_constructor_utc(duk_hthread *thr) {
+ duk_idx_t nargs = duk_get_top(thr);
duk_double_t dparts[DUK_DATE_IDX_NUM_PARTS];
duk_double_t d;
@@ -29128,21 +30252,21 @@ DUK_INTERNAL duk_ret_t duk_bi_date_constructor_utc(duk_context *ctx) {
*/
if (nargs < 2) {
- duk_push_nan(ctx);
+ duk_push_nan(thr);
} else {
- duk__set_parts_from_args(ctx, dparts, nargs);
+ duk__set_parts_from_args(thr, dparts, nargs);
d = duk_bi_date_get_timeval_from_dparts(dparts, 0 /*flags*/);
- duk_push_number(ctx, d);
+ duk_push_number(thr, d);
}
return 1;
}
-DUK_INTERNAL duk_ret_t duk_bi_date_constructor_now(duk_context *ctx) {
+DUK_INTERNAL duk_ret_t duk_bi_date_constructor_now(duk_hthread *thr) {
duk_double_t d;
- d = DUK_USE_DATE_GET_NOW(ctx);
+ d = duk_time_get_ecmascript_time_nofrac(thr);
DUK_ASSERT(duk__timeclip(d) == d); /* TimeClip() should never be necessary */
- duk_push_number(ctx, d);
+ duk_push_number(thr, d);
return 1;
}
@@ -29180,44 +30304,44 @@ DUK_INTERNAL duk_ret_t duk_bi_date_constructor_now(duk_context *ctx) {
* toISOString() requires a RangeError for invalid date values.
*/
-DUK_INTERNAL duk_ret_t duk_bi_date_prototype_tostring_shared(duk_context *ctx) {
- duk_small_uint_t flags = duk__date_get_indirect_magic(ctx);
- return duk__to_string_helper(ctx, flags);
+DUK_INTERNAL duk_ret_t duk_bi_date_prototype_tostring_shared(duk_hthread *thr) {
+ duk_small_uint_t flags = duk__date_get_indirect_magic(thr);
+ return duk__to_string_helper(thr, flags);
}
-DUK_INTERNAL duk_ret_t duk_bi_date_prototype_value_of(duk_context *ctx) {
+DUK_INTERNAL duk_ret_t duk_bi_date_prototype_value_of(duk_hthread *thr) {
/* This native function is also used for Date.prototype.getTime()
* as their behavior is identical.
*/
- duk_double_t d = duk__push_this_get_timeval(ctx, 0 /*flags*/); /* -> [ this ] */
+ duk_double_t d = duk__push_this_get_timeval(thr, 0 /*flags*/); /* -> [ this ] */
DUK_ASSERT(DUK_ISFINITE(d) || DUK_ISNAN(d));
- duk_push_number(ctx, d);
+ duk_push_number(thr, d);
return 1;
}
-DUK_INTERNAL duk_ret_t duk_bi_date_prototype_to_json(duk_context *ctx) {
+DUK_INTERNAL duk_ret_t duk_bi_date_prototype_to_json(duk_hthread *thr) {
/* Note: toJSON() is a generic function which works even if 'this'
* is not a Date. The sole argument is ignored.
*/
- duk_push_this(ctx);
- duk_to_object(ctx, -1);
+ duk_push_this(thr);
+ duk_to_object(thr, -1);
- duk_dup_top(ctx);
- duk_to_primitive(ctx, -1, DUK_HINT_NUMBER);
- if (duk_is_number(ctx, -1)) {
- duk_double_t d = duk_get_number(ctx, -1);
+ duk_dup_top(thr);
+ duk_to_primitive(thr, -1, DUK_HINT_NUMBER);
+ if (duk_is_number(thr, -1)) {
+ duk_double_t d = duk_get_number(thr, -1);
if (!DUK_ISFINITE(d)) {
- duk_push_null(ctx);
+ duk_push_null(thr);
return 1;
}
}
- duk_pop(ctx);
+ duk_pop(thr);
- duk_get_prop_stridx_short(ctx, -1, DUK_STRIDX_TO_ISO_STRING);
- duk_dup_m2(ctx); /* -> [ O toIsoString O ] */
- duk_call_method(ctx, 0);
+ duk_get_prop_stridx_short(thr, -1, DUK_STRIDX_TO_ISO_STRING);
+ duk_dup_m2(thr); /* -> [ O toIsoString O ] */
+ duk_call_method(thr, 0);
return 1;
}
@@ -29262,12 +30386,12 @@ DUK_INTERNAL duk_ret_t duk_bi_date_prototype_to_json(duk_context *ctx) {
* function (duk_bi_date_prototype_value_of).
*/
-DUK_INTERNAL duk_ret_t duk_bi_date_prototype_get_shared(duk_context *ctx) {
- duk_small_uint_t flags_and_idx = duk__date_get_indirect_magic(ctx);
- return duk__get_part_helper(ctx, flags_and_idx);
+DUK_INTERNAL duk_ret_t duk_bi_date_prototype_get_shared(duk_hthread *thr) {
+ duk_small_uint_t flags_and_idx = duk__date_get_indirect_magic(thr);
+ return duk__get_part_helper(thr, flags_and_idx);
}
-DUK_INTERNAL duk_ret_t duk_bi_date_prototype_get_timezone_offset(duk_context *ctx) {
+DUK_INTERNAL duk_ret_t duk_bi_date_prototype_get_timezone_offset(duk_hthread *thr) {
/*
* Return (t - LocalTime(t)) in minutes:
*
@@ -29286,14 +30410,14 @@ DUK_INTERNAL duk_ret_t duk_bi_date_prototype_get_timezone_offset(duk_context *ct
duk_int_t tzoffset;
/* Note: DST adjustment is determined using UTC time. */
- d = duk__push_this_get_timeval(ctx, 0 /*flags*/);
+ d = duk__push_this_get_timeval(thr, 0 /*flags*/);
DUK_ASSERT(DUK_ISFINITE(d) || DUK_ISNAN(d));
if (DUK_ISNAN(d)) {
- duk_push_nan(ctx);
+ duk_push_nan(thr);
} else {
DUK_ASSERT(DUK_ISFINITE(d));
tzoffset = DUK_USE_DATE_GET_LOCAL_TZOFFSET(d);
- duk_push_int(ctx, -tzoffset / 60);
+ duk_push_int(thr, -tzoffset / 60);
}
return 1;
}
@@ -29347,19 +30471,19 @@ DUK_INTERNAL duk_ret_t duk_bi_date_prototype_get_timezone_offset(duk_context *ct
* the year will be set regardless of actual argument count.
*/
-DUK_INTERNAL duk_ret_t duk_bi_date_prototype_set_shared(duk_context *ctx) {
- duk_small_uint_t flags_and_maxnargs = duk__date_get_indirect_magic(ctx);
- return duk__set_part_helper(ctx, flags_and_maxnargs);
+DUK_INTERNAL duk_ret_t duk_bi_date_prototype_set_shared(duk_hthread *thr) {
+ duk_small_uint_t flags_and_maxnargs = duk__date_get_indirect_magic(thr);
+ return duk__set_part_helper(thr, flags_and_maxnargs);
}
-DUK_INTERNAL duk_ret_t duk_bi_date_prototype_set_time(duk_context *ctx) {
+DUK_INTERNAL duk_ret_t duk_bi_date_prototype_set_time(duk_hthread *thr) {
duk_double_t d;
- (void) duk__push_this_get_timeval(ctx, 0 /*flags*/); /* -> [ timeval this ] */
- d = duk__timeclip(duk_to_number(ctx, 0));
- duk_push_number(ctx, d);
- duk_dup_top(ctx);
- duk_put_prop_stridx_short(ctx, -3, DUK_STRIDX_INT_VALUE); /* -> [ timeval this timeval ] */
+ (void) duk__push_this_get_timeval(thr, 0 /*flags*/); /* -> [ timeval this ] */
+ d = duk__timeclip(duk_to_number(thr, 0));
+ duk_push_number(thr, d);
+ duk_dup_top(thr);
+ duk_put_prop_stridx_short(thr, -3, DUK_STRIDX_INT_VALUE); /* -> [ timeval this timeval ] */
return 1;
}
@@ -29432,18 +30556,18 @@ DUK_INTERNAL duk_ret_t duk_bi_date_prototype_set_time(duk_context *ctx) {
#if defined(DUK_USE_DATE_NOW_GETTIMEOFDAY)
/* Get current Ecmascript time (= UNIX/Posix time, but in milliseconds). */
-DUK_INTERNAL duk_double_t duk_bi_date_get_now_gettimeofday(duk_context *ctx) {
- duk_hthread *thr = (duk_hthread *) ctx;
+DUK_INTERNAL duk_double_t duk_bi_date_get_now_gettimeofday(void) {
struct timeval tv;
duk_double_t d;
if (gettimeofday(&tv, NULL) != 0) {
- DUK_ERROR_INTERNAL(thr);
+ DUK_D(DUK_DPRINT("gettimeofday() failed"));
+ return 0.0;
}
+ /* As of Duktape 2.2.0 allow fractions. */
d = ((duk_double_t) tv.tv_sec) * 1000.0 +
- ((duk_double_t) (tv.tv_usec / 1000));
- DUK_ASSERT(DUK_FLOOR(d) == d); /* no fractions */
+ ((duk_double_t) tv.tv_usec) / 1000.0;
return d;
}
@@ -29451,11 +30575,14 @@ DUK_INTERNAL duk_double_t duk_bi_date_get_now_gettimeofday(duk_context *ctx) {
#if defined(DUK_USE_DATE_NOW_TIME)
/* Not a very good provider: only full seconds are available. */
-DUK_INTERNAL duk_double_t duk_bi_date_get_now_time(duk_context *ctx) {
+DUK_INTERNAL duk_double_t duk_bi_date_get_now_time(void) {
time_t t;
- DUK_UNREF(ctx);
t = time(NULL);
+ if (t == (time_t) -1) {
+ DUK_D(DUK_DPRINT("time() failed"));
+ return 0.0;
+ }
return ((duk_double_t) t) * 1000.0;
}
#endif /* DUK_USE_DATE_NOW_TIME */
@@ -29611,12 +30738,12 @@ DUK_INTERNAL duk_int_t duk_bi_date_get_local_tzoffset_gmtime(duk_double_t d) {
#endif /* DUK_USE_DATE_TZO_GMTIME */
#if defined(DUK_USE_DATE_PRS_STRPTIME)
-DUK_INTERNAL duk_bool_t duk_bi_date_parse_string_strptime(duk_context *ctx, const char *str) {
+DUK_INTERNAL duk_bool_t duk_bi_date_parse_string_strptime(duk_hthread *thr, const char *str) {
struct tm tm;
time_t t;
char buf[DUK__STRPTIME_BUF_SIZE];
- /* copy to buffer with spare to avoid Valgrind gripes from strptime */
+ /* Copy to buffer with slack to avoid Valgrind gripes from strptime. */
DUK_ASSERT(str != NULL);
DUK_MEMZERO(buf, sizeof(buf)); /* valgrind whine without this */
DUK_SNPRINTF(buf, sizeof(buf), "%s", (const char *) str);
@@ -29636,7 +30763,7 @@ DUK_INTERNAL duk_bool_t duk_bi_date_parse_string_strptime(duk_context *ctx, cons
t = mktime(&tm);
DUK_DDD(DUK_DDDPRINT("mktime() -> %ld", (long) t));
if (t >= 0) {
- duk_push_number(ctx, ((duk_double_t) t) * 1000.0);
+ duk_push_number(thr, ((duk_double_t) t) * 1000.0);
return 1;
}
}
@@ -29646,7 +30773,7 @@ DUK_INTERNAL duk_bool_t duk_bi_date_parse_string_strptime(duk_context *ctx, cons
#endif /* DUK_USE_DATE_PRS_STRPTIME */
#if defined(DUK_USE_DATE_PRS_GETDATE)
-DUK_INTERNAL duk_bool_t duk_bi_date_parse_string_getdate(duk_context *ctx, const char *str) {
+DUK_INTERNAL duk_bool_t duk_bi_date_parse_string_getdate(duk_hthread *thr, const char *str) {
struct tm tm;
duk_small_int_t rc;
time_t t;
@@ -29663,7 +30790,7 @@ DUK_INTERNAL duk_bool_t duk_bi_date_parse_string_getdate(duk_context *ctx, const
t = mktime(&tm);
DUK_DDD(DUK_DDDPRINT("mktime() -> %ld", (long) t));
if (t >= 0) {
- duk_push_number(ctx, (duk_double_t) t);
+ duk_push_number(thr, (duk_double_t) t);
return 1;
}
}
@@ -29673,7 +30800,7 @@ DUK_INTERNAL duk_bool_t duk_bi_date_parse_string_getdate(duk_context *ctx, const
#endif /* DUK_USE_DATE_PRS_GETDATE */
#if defined(DUK_USE_DATE_FMT_STRFTIME)
-DUK_INTERNAL duk_bool_t duk_bi_date_format_parts_strftime(duk_context *ctx, duk_int_t *parts, duk_int_t tzoffset, duk_small_uint_t flags) {
+DUK_INTERNAL duk_bool_t duk_bi_date_format_parts_strftime(duk_hthread *thr, duk_int_t *parts, duk_int_t tzoffset, duk_small_uint_t flags) {
char buf[DUK__STRFTIME_BUF_SIZE];
struct tm tm;
const char *fmt;
@@ -29719,11 +30846,24 @@ DUK_INTERNAL duk_bool_t duk_bi_date_format_parts_strftime(duk_context *ctx, duk_
(void) strftime(buf, sizeof(buf) - 1, fmt, &tm);
DUK_ASSERT(buf[sizeof(buf) - 1] == 0);
- duk_push_string(ctx, buf);
+ duk_push_string(thr, buf);
return 1;
}
#endif /* DUK_USE_DATE_FMT_STRFTIME */
+#if defined(DUK_USE_GET_MONOTONIC_TIME_CLOCK_GETTIME)
+DUK_INTERNAL duk_double_t duk_bi_date_get_monotonic_time_clock_gettime(void) {
+ struct timespec ts;
+
+ if (clock_gettime(CLOCK_MONOTONIC, &ts) == 0) {
+ return (duk_double_t) ts.tv_sec * 1000.0 + (duk_double_t) ts.tv_nsec / 1000000.0;
+ } else {
+ DUK_D(DUK_DPRINT("clock_gettime(CLOCK_MONOTONIC) failed"));
+ return 0.0;
+ }
+}
+#endif
+
/* automatic undefs */
#undef DUK__STRFTIME_BUF_SIZE
#undef DUK__STRPTIME_BUF_SIZE
@@ -29751,6 +30891,12 @@ DUK_LOCAL void duk__convert_systime_to_ularge(const SYSTEMTIME *st, ULARGE_INTEG
res->HighPart = ft.dwHighDateTime;
}
}
+
+DUK_LOCAL void duk__convert_filetime_to_ularge(const FILETIME *ft, ULARGE_INTEGER *res) {
+ res->LowPart = ft->dwLowDateTime;
+ res->HighPart = ft->dwHighDateTime;
+}
+
DUK_LOCAL void duk__set_systime_jan1970(SYSTEMTIME *st) {
DUK_MEMZERO((void *) st, sizeof(*st));
st->wYear = 1970;
@@ -29765,29 +30911,51 @@ DUK_LOCAL void duk__set_systime_jan1970(SYSTEMTIME *st) {
#endif /* defined(DUK_USE_DATE_NOW_WINDOWS) || defined(DUK_USE_DATE_TZO_WINDOWS) */
#if defined(DUK_USE_DATE_NOW_WINDOWS)
-DUK_INTERNAL duk_double_t duk_bi_date_get_now_windows(duk_context *ctx) {
+DUK_INTERNAL duk_double_t duk_bi_date_get_now_windows(void) {
/* Suggested step-by-step method from documentation of RtlTimeToSecondsSince1970:
* http://msdn.microsoft.com/en-us/library/windows/desktop/ms724928(v=vs.85).aspx
*/
SYSTEMTIME st1, st2;
ULARGE_INTEGER tmp1, tmp2;
- DUK_UNREF(ctx);
-
GetSystemTime(&st1);
duk__convert_systime_to_ularge((const SYSTEMTIME *) &st1, &tmp1);
duk__set_systime_jan1970(&st2);
duk__convert_systime_to_ularge((const SYSTEMTIME *) &st2, &tmp2);
- /* Difference is in 100ns units, convert to milliseconds w/o fractions */
- return (duk_double_t) ((tmp1.QuadPart - tmp2.QuadPart) / 10000LL);
+ /* Difference is in 100ns units, convert to milliseconds, keeping
+ * fractions since Duktape 2.2.0. This is only theoretical because
+ * SYSTEMTIME is limited to milliseconds.
+ */
+ return (duk_double_t) ((LONGLONG) tmp1.QuadPart - (LONGLONG) tmp2.QuadPart) / 10000.0;
}
#endif /* DUK_USE_DATE_NOW_WINDOWS */
+#if defined(DUK_USE_DATE_NOW_WINDOWS_SUBMS)
+DUK_INTERNAL duk_double_t duk_bi_date_get_now_windows_subms(void) {
+ /* Variant of the basic algorithm using GetSystemTimePreciseAsFileTime()
+ * for more accuracy.
+ */
+ FILETIME ft1;
+ SYSTEMTIME st2;
+ ULARGE_INTEGER tmp1, tmp2;
+
+ GetSystemTimePreciseAsFileTime(&ft1);
+ duk__convert_filetime_to_ularge((const FILETIME *) &ft1, &tmp1);
+
+ duk__set_systime_jan1970(&st2);
+ duk__convert_systime_to_ularge((const SYSTEMTIME *) &st2, &tmp2);
+
+ /* Difference is in 100ns units, convert to milliseconds, keeping
+ * fractions since Duktape 2.2.0.
+ */
+ return (duk_double_t) ((LONGLONG) tmp1.QuadPart - (LONGLONG) tmp2.QuadPart) / 10000.0;
+}
+#endif /* DUK_USE_DATE_NOW_WINDOWS */
#if defined(DUK_USE_DATE_TZO_WINDOWS)
-DUK_INTERNAL_DECL duk_int_t duk_bi_date_get_local_tzoffset_windows(duk_double_t d) {
+DUK_INTERNAL duk_int_t duk_bi_date_get_local_tzoffset_windows(duk_double_t d) {
SYSTEMTIME st1;
SYSTEMTIME st2;
SYSTEMTIME st3;
@@ -29822,12 +30990,12 @@ DUK_INTERNAL_DECL duk_int_t duk_bi_date_get_local_tzoffset_windows(duk_double_t
duk__convert_systime_to_ularge((const SYSTEMTIME *) &st3, &tmp3);
/* Positive if local time ahead of UTC. */
- return (duk_int_t) (((LONGLONG) tmp3.QuadPart - (LONGLONG) tmp2.QuadPart) / 10000000LL); /* seconds */
+ return (duk_int_t) (((LONGLONG) tmp3.QuadPart - (LONGLONG) tmp2.QuadPart) / DUK_I64_CONSTANT(10000000)); /* seconds */
}
#endif /* DUK_USE_DATE_TZO_WINDOWS */
#if defined(DUK_USE_DATE_TZO_WINDOWS_NO_DST)
-DUK_INTERNAL_DECL duk_int_t duk_bi_date_get_local_tzoffset_windows_no_dst(duk_double_t d) {
+DUK_INTERNAL duk_int_t duk_bi_date_get_local_tzoffset_windows_no_dst(duk_double_t d) {
SYSTEMTIME st1;
SYSTEMTIME st2;
FILETIME ft1;
@@ -29854,9 +31022,34 @@ DUK_INTERNAL_DECL duk_int_t duk_bi_date_get_local_tzoffset_windows_no_dst(duk_do
FileTimeToSystemTime((const FILETIME *) &ft2, &st2);
duk__convert_systime_to_ularge((const SYSTEMTIME *) &st2, &tmp2);
- return (duk_int_t) (((LONGLONG) tmp2.QuadPart - (LONGLONG) tmp1.QuadPart) / 10000000LL); /* seconds */
+ return (duk_int_t) (((LONGLONG) tmp2.QuadPart - (LONGLONG) tmp1.QuadPart) / DUK_I64_CONSTANT(10000000)); /* seconds */
}
#endif /* DUK_USE_DATE_TZO_WINDOWS_NO_DST */
+
+#if defined(DUK_USE_GET_MONOTONIC_TIME_WINDOWS_QPC)
+DUK_INTERNAL duk_double_t duk_bi_date_get_monotonic_time_windows_qpc(void) {
+ LARGE_INTEGER count, freq;
+
+ /* There are legacy issues with QueryPerformanceCounter():
+ * - Potential jumps: https://support.microsoft.com/en-us/help/274323/performance-counter-value-may-unexpectedly-leap-forward
+ * - Differences between cores (XP): https://msdn.microsoft.com/en-us/library/windows/desktop/dn553408(v=vs.85).aspx#qpc_support_in_windows_versions
+ *
+ * We avoid these by enabling QPC by default only for Vista or later.
+ */
+
+ if (QueryPerformanceCounter(&count) && QueryPerformanceFrequency(&freq)) {
+ /* XXX: QueryPerformanceFrequency() can be cached */
+ return (duk_double_t) count.QuadPart / (duk_double_t) freq.QuadPart * 1000.0;
+ } else {
+ /* MSDN: "On systems that run Windows XP or later, the function
+ * will always succeed and will thus never return zero."
+ * Provide minimal error path just in case user enables this
+ * feature in pre-XP Windows.
+ */
+ return 0.0;
+ }
+}
+#endif /* DUK_USE_GET_MONOTONIC_TIME_WINDOWS_QPC */
/*
* Duktape built-ins
*
@@ -29872,37 +31065,36 @@ DUK_INTERNAL_DECL duk_int_t duk_bi_date_get_local_tzoffset_windows_no_dst(duk_do
#if defined(DUK_USE_DUKTAPE_BUILTIN)
-DUK_INTERNAL duk_ret_t duk_bi_duktape_object_info(duk_context *ctx) {
- duk_inspect_value(ctx, -1);
+DUK_INTERNAL duk_ret_t duk_bi_duktape_object_info(duk_hthread *thr) {
+ duk_inspect_value(thr, -1);
return 1;
}
-DUK_INTERNAL duk_ret_t duk_bi_duktape_object_act(duk_context *ctx) {
+DUK_INTERNAL duk_ret_t duk_bi_duktape_object_act(duk_hthread *thr) {
duk_int_t level;
- level = duk_to_int(ctx, 0);
- duk_inspect_callstack_entry(ctx, level);
+ level = duk_to_int(thr, 0);
+ duk_inspect_callstack_entry(thr, level);
return 1;
}
-DUK_INTERNAL duk_ret_t duk_bi_duktape_object_gc(duk_context *ctx) {
- duk_hthread *thr = (duk_hthread *) ctx;
+DUK_INTERNAL duk_ret_t duk_bi_duktape_object_gc(duk_hthread *thr) {
duk_small_uint_t flags;
- flags = (duk_small_uint_t) duk_get_uint(ctx, 0);
+ flags = (duk_small_uint_t) duk_get_uint(thr, 0);
duk_heap_mark_and_sweep(thr->heap, flags);
/* XXX: Not sure what the best return value would be in the API.
* Return true for now.
*/
- duk_push_true(ctx);
+ duk_push_true(thr);
return 1;
}
#if defined(DUK_USE_FINALIZER_SUPPORT)
-DUK_INTERNAL duk_ret_t duk_bi_duktape_object_fin(duk_context *ctx) {
- (void) duk_require_hobject(ctx, 0);
- if (duk_get_top(ctx) >= 2) {
+DUK_INTERNAL duk_ret_t duk_bi_duktape_object_fin(duk_hthread *thr) {
+ (void) duk_require_hobject(thr, 0);
+ if (duk_get_top(thr) >= 2) {
/* Set: currently a finalizer is disabled by setting it to
* undefined; this does not remove the property at the moment.
* The value could be type checked to be either a function
@@ -29910,43 +31102,40 @@ DUK_INTERNAL duk_ret_t duk_bi_duktape_object_fin(duk_context *ctx) {
* be deleted. Must use duk_set_finalizer() to keep
* DUK_HOBJECT_FLAG_HAVE_FINALIZER in sync.
*/
- duk_set_top(ctx, 2);
- duk_set_finalizer(ctx, 0);
+ duk_set_top(thr, 2);
+ duk_set_finalizer(thr, 0);
return 0;
} else {
/* Get. */
- DUK_ASSERT(duk_get_top(ctx) == 1);
- duk_get_finalizer(ctx, 0);
+ DUK_ASSERT(duk_get_top(thr) == 1);
+ duk_get_finalizer(thr, 0);
return 1;
}
}
#endif /* DUK_USE_FINALIZER_SUPPORT */
-DUK_INTERNAL duk_ret_t duk_bi_duktape_object_enc(duk_context *ctx) {
- duk_hthread *thr = (duk_hthread *) ctx;
+DUK_INTERNAL duk_ret_t duk_bi_duktape_object_enc(duk_hthread *thr) {
duk_hstring *h_str;
- DUK_UNREF(thr);
-
/* Vararg function: must be careful to check/require arguments.
* The JSON helpers accept invalid indices and treat them like
* non-existent optional parameters.
*/
- h_str = duk_require_hstring(ctx, 0); /* Could reject symbols, but no point: won't match comparisons. */
- duk_require_valid_index(ctx, 1);
+ h_str = duk_require_hstring(thr, 0); /* Could reject symbols, but no point: won't match comparisons. */
+ duk_require_valid_index(thr, 1);
if (h_str == DUK_HTHREAD_STRING_HEX(thr)) {
- duk_set_top(ctx, 2);
- duk_hex_encode(ctx, 1);
- DUK_ASSERT_TOP(ctx, 2);
+ duk_set_top(thr, 2);
+ duk_hex_encode(thr, 1);
+ DUK_ASSERT_TOP(thr, 2);
} else if (h_str == DUK_HTHREAD_STRING_BASE64(thr)) {
- duk_set_top(ctx, 2);
- duk_base64_encode(ctx, 1);
- DUK_ASSERT_TOP(ctx, 2);
+ duk_set_top(thr, 2);
+ duk_base64_encode(thr, 1);
+ DUK_ASSERT_TOP(thr, 2);
#if defined(DUK_USE_JSON_SUPPORT) && defined(DUK_USE_JX)
} else if (h_str == DUK_HTHREAD_STRING_JX(thr)) {
- duk_bi_json_stringify_helper(ctx,
+ duk_bi_json_stringify_helper(thr,
1 /*idx_value*/,
2 /*idx_replacer*/,
3 /*idx_space*/,
@@ -29956,7 +31145,7 @@ DUK_INTERNAL duk_ret_t duk_bi_duktape_object_enc(duk_context *ctx) {
#endif
#if defined(DUK_USE_JSON_SUPPORT) && defined(DUK_USE_JC)
} else if (h_str == DUK_HTHREAD_STRING_JC(thr)) {
- duk_bi_json_stringify_helper(ctx,
+ duk_bi_json_stringify_helper(thr,
1 /*idx_value*/,
2 /*idx_replacer*/,
3 /*idx_space*/,
@@ -29969,38 +31158,35 @@ DUK_INTERNAL duk_ret_t duk_bi_duktape_object_enc(duk_context *ctx) {
return 1;
}
-DUK_INTERNAL duk_ret_t duk_bi_duktape_object_dec(duk_context *ctx) {
- duk_hthread *thr = (duk_hthread *) ctx;
+DUK_INTERNAL duk_ret_t duk_bi_duktape_object_dec(duk_hthread *thr) {
duk_hstring *h_str;
- DUK_UNREF(thr);
-
/* Vararg function: must be careful to check/require arguments.
* The JSON helpers accept invalid indices and treat them like
* non-existent optional parameters.
*/
- h_str = duk_require_hstring(ctx, 0); /* Could reject symbols, but no point: won't match comparisons */
- duk_require_valid_index(ctx, 1);
+ h_str = duk_require_hstring(thr, 0); /* Could reject symbols, but no point: won't match comparisons */
+ duk_require_valid_index(thr, 1);
if (h_str == DUK_HTHREAD_STRING_HEX(thr)) {
- duk_set_top(ctx, 2);
- duk_hex_decode(ctx, 1);
- DUK_ASSERT_TOP(ctx, 2);
+ duk_set_top(thr, 2);
+ duk_hex_decode(thr, 1);
+ DUK_ASSERT_TOP(thr, 2);
} else if (h_str == DUK_HTHREAD_STRING_BASE64(thr)) {
- duk_set_top(ctx, 2);
- duk_base64_decode(ctx, 1);
- DUK_ASSERT_TOP(ctx, 2);
+ duk_set_top(thr, 2);
+ duk_base64_decode(thr, 1);
+ DUK_ASSERT_TOP(thr, 2);
#if defined(DUK_USE_JSON_SUPPORT) && defined(DUK_USE_JX)
} else if (h_str == DUK_HTHREAD_STRING_JX(thr)) {
- duk_bi_json_parse_helper(ctx,
+ duk_bi_json_parse_helper(thr,
1 /*idx_value*/,
2 /*idx_replacer*/,
DUK_JSON_FLAG_EXT_CUSTOM /*flags*/);
#endif
#if defined(DUK_USE_JSON_SUPPORT) && defined(DUK_USE_JC)
} else if (h_str == DUK_HTHREAD_STRING_JC(thr)) {
- duk_bi_json_parse_helper(ctx,
+ duk_bi_json_parse_helper(thr,
1 /*idx_value*/,
2 /*idx_replacer*/,
DUK_JSON_FLAG_EXT_COMPATIBLE /*flags*/);
@@ -30015,9 +31201,9 @@ DUK_INTERNAL duk_ret_t duk_bi_duktape_object_dec(duk_context *ctx) {
* Compact an object
*/
-DUK_INTERNAL duk_ret_t duk_bi_duktape_object_compact(duk_context *ctx) {
- DUK_ASSERT_TOP(ctx, 1);
- duk_compact(ctx, 0);
+DUK_INTERNAL duk_ret_t duk_bi_duktape_object_compact(duk_hthread *thr) {
+ DUK_ASSERT_TOP(thr, 1);
+ duk_compact(thr, 0);
return 1; /* return the argument object */
}
@@ -30201,7 +31387,7 @@ DUK_LOCAL void duk__utf8_encode_char(void *udata, duk_codepoint_t codepoint) {
} else {
/* low surrogate */
if (enc_ctx->lead != 0x0000L) {
- codepoint = 0x010000L + ((enc_ctx->lead - 0xd800L) << 10) + (codepoint - 0xdc00L);
+ codepoint = (duk_codepoint_t) (0x010000L + ((enc_ctx->lead - 0xd800L) << 10) + (codepoint - 0xdc00L));
enc_ctx->lead = 0x0000L;
} else {
/* unpaired low surrogate */
@@ -30220,14 +31406,14 @@ DUK_LOCAL void duk__utf8_encode_char(void *udata, duk_codepoint_t codepoint) {
/* Codepoint may be original input, a decoded surrogate pair, or may
* have been replaced with U+FFFD.
*/
- enc_ctx->out += duk_unicode_encode_xutf8(codepoint, enc_ctx->out);
+ enc_ctx->out += duk_unicode_encode_xutf8((duk_ucodepoint_t) codepoint, enc_ctx->out);
}
#endif /* DUK_USE_ENCODING_BUILTINS */
/* Shared helper for buffer-to-string using a TextDecoder() compatible UTF-8
* decoder.
*/
-DUK_LOCAL duk_ret_t duk__decode_helper(duk_context *ctx, duk__decode_context *dec_ctx) {
+DUK_LOCAL duk_ret_t duk__decode_helper(duk_hthread *thr, duk__decode_context *dec_ctx) {
const duk_uint8_t *input;
duk_size_t len = 0;
duk_size_t len_tmp;
@@ -30247,24 +31433,24 @@ DUK_LOCAL duk_ret_t duk__decode_helper(duk_context *ctx, duk__decode_context *de
* required side effect order.
*/
- if (duk_is_undefined(ctx, 0)) {
- duk_push_fixed_buffer_nozero(ctx, 0);
- duk_replace(ctx, 0);
+ if (duk_is_undefined(thr, 0)) {
+ duk_push_fixed_buffer_nozero(thr, 0);
+ duk_replace(thr, 0);
}
- (void) duk_require_buffer_data(ctx, 0, &len); /* Need 'len', avoid pointer. */
+ (void) duk_require_buffer_data(thr, 0, &len); /* Need 'len', avoid pointer. */
- if (duk_check_type_mask(ctx, 1, DUK_TYPE_MASK_UNDEFINED |
+ if (duk_check_type_mask(thr, 1, DUK_TYPE_MASK_UNDEFINED |
DUK_TYPE_MASK_NULL |
DUK_TYPE_MASK_NONE)) {
/* Use defaults, treat missing value like undefined. */
} else {
- duk_require_type_mask(ctx, 1, DUK_TYPE_MASK_UNDEFINED |
+ duk_require_type_mask(thr, 1, DUK_TYPE_MASK_UNDEFINED |
DUK_TYPE_MASK_NULL |
DUK_TYPE_MASK_LIGHTFUNC |
DUK_TYPE_MASK_BUFFER |
DUK_TYPE_MASK_OBJECT);
- if (duk_get_prop_string(ctx, 1, "stream")) {
- stream = duk_to_boolean(ctx, -1);
+ if (duk_get_prop_string(thr, 1, "stream")) {
+ stream = duk_to_boolean(thr, -1);
}
}
@@ -30277,11 +31463,11 @@ DUK_LOCAL duk_ret_t duk__decode_helper(duk_context *ctx, duk__decode_context *de
* XXX: As with TextEncoder, need a better buffer allocation strategy here.
*/
if (len >= (DUK_HBUFFER_MAX_BYTELEN / 3) - 3) {
- DUK_ERROR_TYPE((duk_hthread *) ctx, DUK_STR_RESULT_TOO_LONG);
+ DUK_ERROR_TYPE(thr, DUK_STR_RESULT_TOO_LONG);
}
- output = (duk_uint8_t *) duk_push_fixed_buffer_nozero(ctx, 3 + (3 * len)); /* used parts will be always manually written over */
+ output = (duk_uint8_t *) duk_push_fixed_buffer_nozero(thr, 3 + (3 * len)); /* used parts will be always manually written over */
- input = (const duk_uint8_t *) duk_get_buffer_data(ctx, 0, &len_tmp);
+ input = (const duk_uint8_t *) duk_get_buffer_data(thr, 0, &len_tmp);
DUK_ASSERT(input != NULL || len == 0);
if (DUK_UNLIKELY(len != len_tmp)) {
/* Very unlikely but possible: source buffer was resized by
@@ -30330,7 +31516,7 @@ DUK_LOCAL duk_ret_t duk__decode_helper(duk_context *ctx, duk__decode_context *de
}
}
- out += duk_unicode_encode_cesu8(codepoint, out);
+ out += duk_unicode_encode_cesu8((duk_ucodepoint_t) codepoint, out);
DUK_ASSERT(out <= output + (3 + (3 * len)));
}
@@ -30350,11 +31536,11 @@ DUK_LOCAL duk_ret_t duk__decode_helper(duk_context *ctx, duk__decode_context *de
/* Output buffer is fixed and thus stable even if there had been
* side effects (which there shouldn't be).
*/
- duk_push_lstring(ctx, (const char *) output, (duk_size_t) (out - output));
+ duk_push_lstring(thr, (const char *) output, (duk_size_t) (out - output));
return 1;
fail_type:
- DUK_ERROR_TYPE((duk_hthread *) ctx, DUK_STR_DECODE_FAILED);
+ DUK_ERROR_TYPE(thr, DUK_STR_UTF8_DECODE_FAILED);
DUK_UNREACHABLE();
}
@@ -30363,38 +31549,38 @@ DUK_LOCAL duk_ret_t duk__decode_helper(duk_context *ctx, duk__decode_context *de
*/
#if defined(DUK_USE_ENCODING_BUILTINS)
-DUK_INTERNAL duk_ret_t duk_bi_textencoder_constructor(duk_context *ctx) {
+DUK_INTERNAL duk_ret_t duk_bi_textencoder_constructor(duk_hthread *thr) {
/* TextEncoder currently requires no persistent state, so the constructor
* does nothing on purpose.
*/
- duk_require_constructor_call(ctx);
+ duk_require_constructor_call(thr);
return 0;
}
-DUK_INTERNAL duk_ret_t duk_bi_textencoder_prototype_encoding_getter(duk_context *ctx) {
- duk_push_string(ctx, "utf-8");
+DUK_INTERNAL duk_ret_t duk_bi_textencoder_prototype_encoding_getter(duk_hthread *thr) {
+ duk_push_string(thr, "utf-8");
return 1;
}
-DUK_INTERNAL duk_ret_t duk_bi_textencoder_prototype_encode(duk_context *ctx) {
+DUK_INTERNAL duk_ret_t duk_bi_textencoder_prototype_encode(duk_hthread *thr) {
duk__encode_context enc_ctx;
duk_size_t len;
duk_size_t final_len;
duk_uint8_t *output;
- DUK_ASSERT_TOP(ctx, 1);
- if (duk_is_undefined(ctx, 0)) {
+ DUK_ASSERT_TOP(thr, 1);
+ if (duk_is_undefined(thr, 0)) {
len = 0;
} else {
duk_hstring *h_input;
- h_input = duk_to_hstring(ctx, 0);
+ h_input = duk_to_hstring(thr, 0);
DUK_ASSERT(h_input != NULL);
len = (duk_size_t) DUK_HSTRING_GET_CHARLEN(h_input);
if (len >= DUK_HBUFFER_MAX_BYTELEN / 3) {
- DUK_ERROR_TYPE((duk_hthread *) ctx, DUK_STR_RESULT_TOO_LONG);
+ DUK_ERROR_TYPE(thr, DUK_STR_RESULT_TOO_LONG);
}
}
@@ -30408,10 +31594,10 @@ DUK_INTERNAL duk_ret_t duk_bi_textencoder_prototype_encode(duk_context *ctx) {
* figure out the space needed ahead of time?
*/
DUK_ASSERT(3 * len >= len);
- output = (duk_uint8_t *) duk_push_dynamic_buffer(ctx, 3 * len);
+ output = (duk_uint8_t *) duk_push_dynamic_buffer(thr, 3 * len);
if (len > 0) {
- DUK_ASSERT(duk_is_string(ctx, 0)); /* True if len > 0. */
+ DUK_ASSERT(duk_is_string(thr, 0)); /* True if len > 0. */
/* XXX: duk_decode_string() is used to process the input
* string. For standard Ecmascript strings, represented
@@ -30427,7 +31613,7 @@ DUK_INTERNAL duk_ret_t duk_bi_textencoder_prototype_encode(duk_context *ctx) {
*/
enc_ctx.lead = 0x0000L;
enc_ctx.out = output;
- duk_decode_string(ctx, 0, duk__utf8_encode_char, (void *) &enc_ctx);
+ duk_decode_string(thr, 0, duk__utf8_encode_char, (void *) &enc_ctx);
if (enc_ctx.lead != 0x0000L) {
/* unpaired high surrogate at end of string */
enc_ctx.out = duk__utf8_emit_repl(enc_ctx.out);
@@ -30437,11 +31623,11 @@ DUK_INTERNAL duk_ret_t duk_bi_textencoder_prototype_encode(duk_context *ctx) {
/* The output buffer is usually very much oversized, so shrink it to
* actually needed size. Pointer stability assumed up to this point.
*/
- DUK_ASSERT_TOP(ctx, 2);
- DUK_ASSERT(output == (duk_uint8_t *) duk_get_buffer_data(ctx, -1, NULL));
+ DUK_ASSERT_TOP(thr, 2);
+ DUK_ASSERT(output == (duk_uint8_t *) duk_get_buffer_data(thr, -1, NULL));
final_len = (duk_size_t) (enc_ctx.out - output);
- duk_resize_buffer(ctx, -1, final_len);
+ duk_resize_buffer(thr, -1, final_len);
/* 'output' and 'enc_ctx.out' are potentially invalidated by the resize. */
} else {
final_len = 0;
@@ -30454,84 +31640,84 @@ DUK_INTERNAL duk_ret_t duk_bi_textencoder_prototype_encode(duk_context *ctx) {
* returns a plain dynamic buffer.
*/
#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)
- duk_push_buffer_object(ctx, -1, 0, final_len, DUK_BUFOBJ_UINT8ARRAY);
+ duk_push_buffer_object(thr, -1, 0, final_len, DUK_BUFOBJ_UINT8ARRAY);
#endif
return 1;
}
-DUK_INTERNAL duk_ret_t duk_bi_textdecoder_constructor(duk_context *ctx) {
+DUK_INTERNAL duk_ret_t duk_bi_textdecoder_constructor(duk_hthread *thr) {
duk__decode_context *dec_ctx;
duk_bool_t fatal = 0;
duk_bool_t ignore_bom = 0;
- DUK_ASSERT_TOP(ctx, 2);
- duk_require_constructor_call(ctx);
- if (!duk_is_undefined(ctx, 0)) {
+ DUK_ASSERT_TOP(thr, 2);
+ duk_require_constructor_call(thr);
+ if (!duk_is_undefined(thr, 0)) {
/* XXX: For now ignore 'label' (encoding identifier). */
- duk_to_string(ctx, 0);
+ duk_to_string(thr, 0);
}
- if (!duk_is_null_or_undefined(ctx, 1)) {
- if (duk_get_prop_string(ctx, 1, "fatal")) {
- fatal = duk_to_boolean(ctx, -1);
+ if (!duk_is_null_or_undefined(thr, 1)) {
+ if (duk_get_prop_string(thr, 1, "fatal")) {
+ fatal = duk_to_boolean(thr, -1);
}
- if (duk_get_prop_string(ctx, 1, "ignoreBOM")) {
- ignore_bom = duk_to_boolean(ctx, -1);
+ if (duk_get_prop_string(thr, 1, "ignoreBOM")) {
+ ignore_bom = duk_to_boolean(thr, -1);
}
}
- duk_push_this(ctx);
+ duk_push_this(thr);
/* The decode context is not assumed to be zeroed; all fields are
* initialized explicitly.
*/
- dec_ctx = (duk__decode_context *) duk_push_fixed_buffer(ctx, sizeof(duk__decode_context));
+ dec_ctx = (duk__decode_context *) duk_push_fixed_buffer(thr, sizeof(duk__decode_context));
dec_ctx->fatal = (duk_uint8_t) fatal;
dec_ctx->ignore_bom = (duk_uint8_t) ignore_bom;
duk__utf8_decode_init(dec_ctx); /* Initializes remaining fields. */
- duk_put_prop_string(ctx, -2, "\xff" "Context");
+ duk_put_prop_string(thr, -2, DUK_INTERNAL_SYMBOL("Context"));
return 0;
}
/* Get TextDecoder context from 'this'; leaves garbage on stack. */
-DUK_LOCAL duk__decode_context *duk__get_textdecoder_context(duk_context *ctx) {
+DUK_LOCAL duk__decode_context *duk__get_textdecoder_context(duk_hthread *thr) {
duk__decode_context *dec_ctx;
- duk_push_this(ctx);
- duk_get_prop_string(ctx, -1, "\xff" "Context");
- dec_ctx = (duk__decode_context *) duk_require_buffer(ctx, -1, NULL);
+ duk_push_this(thr);
+ duk_get_prop_string(thr, -1, DUK_INTERNAL_SYMBOL("Context"));
+ dec_ctx = (duk__decode_context *) duk_require_buffer(thr, -1, NULL);
DUK_ASSERT(dec_ctx != NULL);
return dec_ctx;
}
-DUK_INTERNAL duk_ret_t duk_bi_textdecoder_prototype_shared_getter(duk_context *ctx) {
+DUK_INTERNAL duk_ret_t duk_bi_textdecoder_prototype_shared_getter(duk_hthread *thr) {
duk__decode_context *dec_ctx;
duk_int_t magic;
- dec_ctx = duk__get_textdecoder_context(ctx);
- magic = duk_get_current_magic(ctx);
+ dec_ctx = duk__get_textdecoder_context(thr);
+ magic = duk_get_current_magic(thr);
switch (magic) {
case 0:
/* Encoding is now fixed, so _Context lookup is only needed to
* validate the 'this' binding (TypeError if not TextDecoder-like).
*/
- duk_push_string(ctx, "utf-8");
+ duk_push_string(thr, "utf-8");
break;
case 1:
- duk_push_boolean(ctx, dec_ctx->fatal);
+ duk_push_boolean(thr, dec_ctx->fatal);
break;
default:
- duk_push_boolean(ctx, dec_ctx->ignore_bom);
+ duk_push_boolean(thr, dec_ctx->ignore_bom);
break;
}
return 1;
}
-DUK_INTERNAL duk_ret_t duk_bi_textdecoder_prototype_decode(duk_context *ctx) {
+DUK_INTERNAL duk_ret_t duk_bi_textdecoder_prototype_decode(duk_hthread *thr) {
duk__decode_context *dec_ctx;
- dec_ctx = duk__get_textdecoder_context(ctx);
- return duk__decode_helper(ctx, dec_ctx);
+ dec_ctx = duk__get_textdecoder_context(thr);
+ return duk__decode_helper(thr, dec_ctx);
}
#endif /* DUK_USE_ENCODING_BUILTINS */
@@ -30544,14 +31730,14 @@ DUK_INTERNAL duk_ret_t duk_bi_textdecoder_prototype_decode(duk_context *ctx) {
* index 0, and decode options (not present for Buffer) at index 1. Return value
* is a Duktape/C function return value.
*/
-DUK_INTERNAL duk_ret_t duk_textdecoder_decode_utf8_nodejs(duk_context *ctx) {
+DUK_INTERNAL duk_ret_t duk_textdecoder_decode_utf8_nodejs(duk_hthread *thr) {
duk__decode_context dec_ctx;
dec_ctx.fatal = 0; /* use replacement chars */
dec_ctx.ignore_bom = 1; /* ignore BOMs (matches Node.js Buffer .toString()) */
duk__utf8_decode_init(&dec_ctx);
- return duk__decode_helper(ctx, &dec_ctx);
+ return duk__decode_helper(thr, &dec_ctx);
}
/* automatic undefs */
@@ -30564,7 +31750,7 @@ DUK_INTERNAL duk_ret_t duk_textdecoder_decode_utf8_nodejs(duk_context *ctx) {
/* #include duk_internal.h -> already included */
-DUK_INTERNAL duk_ret_t duk_bi_error_constructor_shared(duk_context *ctx) {
+DUK_INTERNAL duk_ret_t duk_bi_error_constructor_shared(duk_hthread *thr) {
/* Behavior for constructor and non-constructor call is
* the same except for augmenting the created error. When
* called as a constructor, the caller (duk_new()) will handle
@@ -30572,25 +31758,22 @@ DUK_INTERNAL duk_ret_t duk_bi_error_constructor_shared(duk_context *ctx) {
* it here.
*/
- duk_hthread *thr = (duk_hthread *) ctx;
- duk_small_int_t bidx_prototype = duk_get_current_magic(ctx);
+ duk_small_int_t bidx_prototype = duk_get_current_magic(thr);
/* same for both error and each subclass like TypeError */
duk_uint_t flags_and_class = DUK_HOBJECT_FLAG_EXTENSIBLE |
DUK_HOBJECT_FLAG_FASTREFS |
DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_ERROR);
- DUK_UNREF(thr);
-
- (void) duk_push_object_helper(ctx, flags_and_class, bidx_prototype);
+ (void) duk_push_object_helper(thr, flags_and_class, bidx_prototype);
/* If message is undefined, the own property 'message' is not set at
* all to save property space. An empty message is inherited anyway.
*/
- if (!duk_is_undefined(ctx, 0)) {
- duk_to_string(ctx, 0);
- duk_dup_0(ctx); /* [ message error message ] */
- duk_xdef_prop_stridx_short(ctx, -2, DUK_STRIDX_MESSAGE, DUK_PROPDESC_FLAGS_WC);
+ if (!duk_is_undefined(thr, 0)) {
+ duk_to_string(thr, 0);
+ duk_dup_0(thr); /* [ message error message ] */
+ duk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_MESSAGE, DUK_PROPDESC_FLAGS_WC);
}
/* Augment the error if called as a normal function. __FILE__ and __LINE__
@@ -30598,28 +31781,28 @@ DUK_INTERNAL duk_ret_t duk_bi_error_constructor_shared(duk_context *ctx) {
*/
#if defined(DUK_USE_AUGMENT_ERROR_CREATE)
- if (!duk_is_constructor_call(ctx)) {
- duk_err_augment_error_create(thr, thr, NULL, 0, 1 /*noblame_fileline*/);
+ if (!duk_is_constructor_call(thr)) {
+ duk_err_augment_error_create(thr, thr, NULL, 0, DUK_AUGMENT_FLAG_NOBLAME_FILELINE);
}
#endif
return 1;
}
-DUK_INTERNAL duk_ret_t duk_bi_error_prototype_to_string(duk_context *ctx) {
+DUK_INTERNAL duk_ret_t duk_bi_error_prototype_to_string(duk_hthread *thr) {
/* XXX: optimize with more direct internal access */
- duk_push_this(ctx);
- (void) duk_require_hobject_promote_mask(ctx, -1, DUK_TYPE_MASK_LIGHTFUNC | DUK_TYPE_MASK_BUFFER);
+ duk_push_this(thr);
+ (void) duk_require_hobject_promote_mask(thr, -1, DUK_TYPE_MASK_LIGHTFUNC | DUK_TYPE_MASK_BUFFER);
/* [ ... this ] */
- duk_get_prop_stridx_short(ctx, -1, DUK_STRIDX_NAME);
- if (duk_is_undefined(ctx, -1)) {
- duk_pop(ctx);
- duk_push_string(ctx, "Error");
+ duk_get_prop_stridx_short(thr, -1, DUK_STRIDX_NAME);
+ if (duk_is_undefined(thr, -1)) {
+ duk_pop(thr);
+ duk_push_string(thr, "Error");
} else {
- duk_to_string(ctx, -1);
+ duk_to_string(thr, -1);
}
/* [ ... this name ] */
@@ -30628,28 +31811,28 @@ DUK_INTERNAL duk_ret_t duk_bi_error_prototype_to_string(duk_context *ctx) {
* accident or are they actually needed? The first ToString()
* could conceivably return 'undefined'.
*/
- duk_get_prop_stridx_short(ctx, -2, DUK_STRIDX_MESSAGE);
- if (duk_is_undefined(ctx, -1)) {
- duk_pop(ctx);
- duk_push_hstring_empty(ctx);
+ duk_get_prop_stridx_short(thr, -2, DUK_STRIDX_MESSAGE);
+ if (duk_is_undefined(thr, -1)) {
+ duk_pop(thr);
+ duk_push_hstring_empty(thr);
} else {
- duk_to_string(ctx, -1);
+ duk_to_string(thr, -1);
}
/* [ ... this name message ] */
- if (duk_get_length(ctx, -2) == 0) {
+ if (duk_get_length(thr, -2) == 0) {
/* name is empty -> return message */
return 1;
}
- if (duk_get_length(ctx, -1) == 0) {
+ if (duk_get_length(thr, -1) == 0) {
/* message is empty -> return name */
- duk_pop(ctx);
+ duk_pop(thr);
return 1;
}
- duk_push_string(ctx, ": ");
- duk_insert(ctx, -2); /* ... name ': ' message */
- duk_concat(ctx, 3);
+ duk_push_string(thr, ": ");
+ duk_insert(thr, -2); /* ... name ': ' message */
+ duk_concat(thr, 3);
return 1;
}
@@ -30675,8 +31858,7 @@ DUK_INTERNAL duk_ret_t duk_bi_error_prototype_to_string(duk_context *ctx) {
#define DUK__OUTPUT_TYPE_FILENAME 0
#define DUK__OUTPUT_TYPE_LINENUMBER 1
-DUK_LOCAL duk_ret_t duk__error_getter_helper(duk_context *ctx, duk_small_int_t output_type) {
- duk_hthread *thr = (duk_hthread *) ctx;
+DUK_LOCAL duk_ret_t duk__error_getter_helper(duk_hthread *thr, duk_small_int_t output_type) {
duk_idx_t idx_td;
duk_small_int_t i; /* traceback depth fits into 16 bits */
duk_small_int_t t; /* stack type fits into 16 bits */
@@ -30688,39 +31870,38 @@ DUK_LOCAL duk_ret_t duk__error_getter_helper(duk_context *ctx, duk_small_int_t o
const char *str_directeval = " directeval";
const char *str_empty = "";
- DUK_ASSERT_TOP(ctx, 0); /* fixed arg count */
- DUK_UNREF(thr);
+ DUK_ASSERT_TOP(thr, 0); /* fixed arg count */
- duk_push_this(ctx);
- duk_get_prop_stridx_short(ctx, -1, DUK_STRIDX_INT_TRACEDATA);
- idx_td = duk_get_top_index(ctx);
+ duk_push_this(thr);
+ duk_get_prop_stridx_short(thr, -1, DUK_STRIDX_INT_TRACEDATA);
+ idx_td = duk_get_top_index(thr);
- duk_push_hstring_stridx(ctx, DUK_STRIDX_NEWLINE_4SPACE);
- duk_push_this(ctx);
+ duk_push_hstring_stridx(thr, DUK_STRIDX_NEWLINE_4SPACE);
+ duk_push_this(thr);
/* [ ... this tracedata sep this ] */
/* XXX: skip null filename? */
- if (duk_check_type(ctx, idx_td, DUK_TYPE_OBJECT)) {
+ if (duk_check_type(thr, idx_td, DUK_TYPE_OBJECT)) {
/* Current tracedata contains 2 entries per callstack entry. */
for (i = 0; ; i += 2) {
duk_int_t pc;
- duk_int_t line;
- duk_int_t flags;
+ duk_uint_t line;
+ duk_uint_t flags;
duk_double_t d;
const char *funcname;
const char *filename;
duk_hobject *h_func;
duk_hstring *h_name;
- duk_require_stack(ctx, 5);
- duk_get_prop_index(ctx, idx_td, i);
- duk_get_prop_index(ctx, idx_td, i + 1);
- d = duk_to_number_m1(ctx);
+ duk_require_stack(thr, 5);
+ duk_get_prop_index(thr, idx_td, (duk_uarridx_t) i);
+ duk_get_prop_index(thr, idx_td, (duk_uarridx_t) (i + 1));
+ d = duk_to_number_m1(thr);
pc = (duk_int_t) DUK_FMOD(d, DUK_DOUBLE_2TO32);
- flags = (duk_int_t) DUK_FLOOR(d / DUK_DOUBLE_2TO32);
- t = (duk_small_int_t) duk_get_type(ctx, -2);
+ flags = (duk_uint_t) DUK_FLOOR(d / DUK_DOUBLE_2TO32);
+ t = (duk_small_int_t) duk_get_type(thr, -2);
if (t == DUK_TYPE_OBJECT || t == DUK_TYPE_LIGHTFUNC) {
/*
@@ -30731,17 +31912,15 @@ DUK_LOCAL duk_ret_t duk__error_getter_helper(duk_context *ctx, duk_small_int_t o
/* [ ... v1(func) v2(pc+flags) ] */
- h_func = duk_get_hobject(ctx, -2); /* NULL for lightfunc */
-
/* These may be systematically omitted by Duktape
* with certain config options, but allow user to
* set them on a case-by-case basis.
*/
- duk_get_prop_stridx_short(ctx, -2, DUK_STRIDX_NAME);
- duk_get_prop_stridx_short(ctx, -3, DUK_STRIDX_FILE_NAME);
+ duk_get_prop_stridx_short(thr, -2, DUK_STRIDX_NAME);
+ duk_get_prop_stridx_short(thr, -3, DUK_STRIDX_FILE_NAME);
#if defined(DUK_USE_PC2LINE)
- line = duk_hobject_pc2line_query(ctx, -4, (duk_uint_fast32_t) pc);
+ line = (duk_uint_t) duk_hobject_pc2line_query(thr, -4, (duk_uint_fast32_t) pc);
#else
line = 0;
#endif
@@ -30751,27 +31930,29 @@ DUK_LOCAL duk_ret_t duk__error_getter_helper(duk_context *ctx, duk_small_int_t o
/* When looking for .fileName/.lineNumber, blame first
* function which has a .fileName.
*/
- if (duk_is_string_notsymbol(ctx, -1)) {
+ if (duk_is_string_notsymbol(thr, -1)) {
if (output_type == DUK__OUTPUT_TYPE_FILENAME) {
return 1;
} else if (output_type == DUK__OUTPUT_TYPE_LINENUMBER) {
- duk_push_int(ctx, line);
+ duk_push_uint(thr, line);
return 1;
}
}
/* XXX: Change 'anon' handling here too, to use empty string for anonymous functions? */
/* XXX: Could be improved by coercing to a readable duk_tval (especially string escaping) */
- h_name = duk_get_hstring_notsymbol(ctx, -2); /* may be NULL */
+ h_name = duk_get_hstring_notsymbol(thr, -2); /* may be NULL */
funcname = (h_name == NULL || h_name == DUK_HTHREAD_STRING_EMPTY_STRING(thr)) ?
"[anon]" : (const char *) DUK_HSTRING_GET_DATA(h_name);
- filename = duk_get_string_notsymbol(ctx, -1);
+ filename = duk_get_string_notsymbol(thr, -1);
filename = filename ? filename : "";
DUK_ASSERT(funcname != NULL);
DUK_ASSERT(filename != NULL);
+ h_func = duk_get_hobject(thr, -4); /* NULL for lightfunc */
+
if (h_func == NULL) {
- duk_push_sprintf(ctx, "at %s light%s%s%s%s%s",
+ duk_push_sprintf(thr, "at %s light%s%s%s%s%s",
(const char *) funcname,
(const char *) ((flags & DUK_ACT_FLAG_STRICT) ? str_strict : str_empty),
(const char *) ((flags & DUK_ACT_FLAG_TAILCALLED) ? str_tailcall : str_empty),
@@ -30779,7 +31960,7 @@ DUK_LOCAL duk_ret_t duk__error_getter_helper(duk_context *ctx, duk_small_int_t o
(const char *) ((flags & DUK_ACT_FLAG_DIRECT_EVAL) ? str_directeval : str_empty),
(const char *) ((flags & DUK_ACT_FLAG_PREVENT_YIELD) ? str_prevyield : str_empty));
} else if (DUK_HOBJECT_HAS_NATFUNC(h_func)) {
- duk_push_sprintf(ctx, "at %s (%s) native%s%s%s%s%s",
+ duk_push_sprintf(thr, "at %s (%s) native%s%s%s%s%s",
(const char *) funcname,
(const char *) filename,
(const char *) ((flags & DUK_ACT_FLAG_STRICT) ? str_strict : str_empty),
@@ -30788,18 +31969,18 @@ DUK_LOCAL duk_ret_t duk__error_getter_helper(duk_context *ctx, duk_small_int_t o
(const char *) ((flags & DUK_ACT_FLAG_DIRECT_EVAL) ? str_directeval : str_empty),
(const char *) ((flags & DUK_ACT_FLAG_PREVENT_YIELD) ? str_prevyield : str_empty));
} else {
- duk_push_sprintf(ctx, "at %s (%s:%ld)%s%s%s%s%s",
+ duk_push_sprintf(thr, "at %s (%s:%lu)%s%s%s%s%s",
(const char *) funcname,
(const char *) filename,
- (long) line,
+ (unsigned long) line,
(const char *) ((flags & DUK_ACT_FLAG_STRICT) ? str_strict : str_empty),
(const char *) ((flags & DUK_ACT_FLAG_TAILCALLED) ? str_tailcall : str_empty),
(const char *) ((flags & DUK_ACT_FLAG_CONSTRUCT) ? str_construct : str_empty),
(const char *) ((flags & DUK_ACT_FLAG_DIRECT_EVAL) ? str_directeval : str_empty),
(const char *) ((flags & DUK_ACT_FLAG_PREVENT_YIELD) ? str_prevyield : str_empty));
}
- duk_replace(ctx, -5); /* [ ... v1 v2 name filename str ] -> [ ... str v2 name filename ] */
- duk_pop_3(ctx); /* -> [ ... str ] */
+ duk_replace(thr, -5); /* [ ... v1 v2 name filename str ] -> [ ... str v2 name filename ] */
+ duk_pop_3(thr); /* -> [ ... str ] */
} else if (t == DUK_TYPE_STRING) {
const char *str_file;
@@ -30816,10 +31997,10 @@ DUK_LOCAL duk_ret_t duk__error_getter_helper(duk_context *ctx, duk_small_int_t o
*/
if (!(flags & DUK_TB_FLAG_NOBLAME_FILELINE)) {
if (output_type == DUK__OUTPUT_TYPE_FILENAME) {
- duk_pop(ctx);
+ duk_pop(thr);
return 1;
} else if (output_type == DUK__OUTPUT_TYPE_LINENUMBER) {
- duk_push_int(ctx, pc);
+ duk_push_int(thr, pc);
return 1;
}
}
@@ -30829,14 +32010,14 @@ DUK_LOCAL duk_ret_t duk__error_getter_helper(duk_context *ctx, duk_small_int_t o
* don't need to be explicitly rejected as they pose no memory
* safety issues.
*/
- str_file = (const char *) duk_get_string(ctx, -2);
- duk_push_sprintf(ctx, "at [anon] (%s:%ld) internal",
+ str_file = (const char *) duk_get_string(thr, -2);
+ duk_push_sprintf(thr, "at [anon] (%s:%ld) internal",
(const char *) (str_file ? str_file : "null"), (long) pc);
- duk_replace(ctx, -3); /* [ ... v1 v2 str ] -> [ ... str v2 ] */
- duk_pop(ctx); /* -> [ ... str ] */
+ duk_replace(thr, -3); /* [ ... v1 v2 str ] -> [ ... str v2 ] */
+ duk_pop(thr); /* -> [ ... str ] */
} else {
/* unknown, ignore */
- duk_pop_2(ctx);
+ duk_pop_2(thr);
break;
}
}
@@ -30846,7 +32027,7 @@ DUK_LOCAL duk_ret_t duk__error_getter_helper(duk_context *ctx, duk_small_int_t o
* marker so this is the best we can do.
*/
- duk_push_hstring_stridx(ctx, DUK_STRIDX_BRACKETED_ELLIPSIS);
+ duk_push_hstring_stridx(thr, DUK_STRIDX_BRACKETED_ELLIPSIS);
}
}
@@ -30859,7 +32040,7 @@ DUK_LOCAL duk_ret_t duk__error_getter_helper(duk_context *ctx, duk_small_int_t o
* duk_join() automatically. We don't want to do that
* coercion when providing .fileName or .lineNumber (GH-254).
*/
- duk_join(ctx, duk_get_top(ctx) - (idx_td + 2) /*count, not including sep*/);
+ duk_join(thr, duk_get_top(thr) - (idx_td + 2) /*count, not including sep*/);
return 1;
}
}
@@ -30868,16 +32049,16 @@ DUK_LOCAL duk_ret_t duk__error_getter_helper(duk_context *ctx, duk_small_int_t o
* save space. For setters the stridx could be encoded into 'magic'.
*/
-DUK_INTERNAL duk_ret_t duk_bi_error_prototype_stack_getter(duk_context *ctx) {
- return duk__error_getter_helper(ctx, DUK__OUTPUT_TYPE_TRACEBACK);
+DUK_INTERNAL duk_ret_t duk_bi_error_prototype_stack_getter(duk_hthread *thr) {
+ return duk__error_getter_helper(thr, DUK__OUTPUT_TYPE_TRACEBACK);
}
-DUK_INTERNAL duk_ret_t duk_bi_error_prototype_filename_getter(duk_context *ctx) {
- return duk__error_getter_helper(ctx, DUK__OUTPUT_TYPE_FILENAME);
+DUK_INTERNAL duk_ret_t duk_bi_error_prototype_filename_getter(duk_hthread *thr) {
+ return duk__error_getter_helper(thr, DUK__OUTPUT_TYPE_FILENAME);
}
-DUK_INTERNAL duk_ret_t duk_bi_error_prototype_linenumber_getter(duk_context *ctx) {
- return duk__error_getter_helper(ctx, DUK__OUTPUT_TYPE_LINENUMBER);
+DUK_INTERNAL duk_ret_t duk_bi_error_prototype_linenumber_getter(duk_hthread *thr) {
+ return duk__error_getter_helper(thr, DUK__OUTPUT_TYPE_LINENUMBER);
}
#else /* DUK_USE_TRACEBACKS */
@@ -30894,26 +32075,26 @@ DUK_INTERNAL duk_ret_t duk_bi_error_prototype_linenumber_getter(duk_context *ctx
* of the error so this makes sense.
*/
-DUK_INTERNAL duk_ret_t duk_bi_error_prototype_stack_getter(duk_context *ctx) {
+DUK_INTERNAL duk_ret_t duk_bi_error_prototype_stack_getter(duk_hthread *thr) {
/* XXX: remove this native function and map 'stack' accessor
* to the toString() implementation directly.
*/
- return duk_bi_error_prototype_to_string(ctx);
+ return duk_bi_error_prototype_to_string(thr);
}
-DUK_INTERNAL duk_ret_t duk_bi_error_prototype_filename_getter(duk_context *ctx) {
- DUK_UNREF(ctx);
+DUK_INTERNAL duk_ret_t duk_bi_error_prototype_filename_getter(duk_hthread *thr) {
+ DUK_UNREF(thr);
return 0;
}
-DUK_INTERNAL duk_ret_t duk_bi_error_prototype_linenumber_getter(duk_context *ctx) {
- DUK_UNREF(ctx);
+DUK_INTERNAL duk_ret_t duk_bi_error_prototype_linenumber_getter(duk_hthread *thr) {
+ DUK_UNREF(thr);
return 0;
}
#endif /* DUK_USE_TRACEBACKS */
-DUK_LOCAL duk_ret_t duk__error_setter_helper(duk_context *ctx, duk_small_uint_t stridx_key) {
+DUK_LOCAL duk_ret_t duk__error_setter_helper(duk_hthread *thr, duk_small_uint_t stridx_key) {
/* Attempt to write 'stack', 'fileName', 'lineNumber' works as if
* user code called Object.defineProperty() to create an overriding
* own property. This allows user code to overwrite .fileName etc
@@ -30921,34 +32102,34 @@ DUK_LOCAL duk_ret_t duk__error_setter_helper(duk_context *ctx, duk_small_uint_t
* See https://github.com/svaarala/duktape/issues/387.
*/
- DUK_ASSERT_TOP(ctx, 1); /* fixed arg count: value */
+ DUK_ASSERT_TOP(thr, 1); /* fixed arg count: value */
- duk_push_this(ctx);
- duk_push_hstring_stridx(ctx, (duk_small_int_t) stridx_key);
- duk_dup_0(ctx);
+ duk_push_this(thr);
+ duk_push_hstring_stridx(thr, stridx_key);
+ duk_dup_0(thr);
/* [ ... obj key value ] */
DUK_DD(DUK_DDPRINT("error setter: %!T %!T %!T",
- duk_get_tval(ctx, -3), duk_get_tval(ctx, -2), duk_get_tval(ctx, -1)));
+ duk_get_tval(thr, -3), duk_get_tval(thr, -2), duk_get_tval(thr, -1)));
- duk_def_prop(ctx, -3, DUK_DEFPROP_HAVE_VALUE |
+ duk_def_prop(thr, -3, DUK_DEFPROP_HAVE_VALUE |
DUK_DEFPROP_HAVE_WRITABLE | DUK_DEFPROP_WRITABLE |
DUK_DEFPROP_HAVE_ENUMERABLE | /*not enumerable*/
DUK_DEFPROP_HAVE_CONFIGURABLE | DUK_DEFPROP_CONFIGURABLE);
return 0;
}
-DUK_INTERNAL duk_ret_t duk_bi_error_prototype_stack_setter(duk_context *ctx) {
- return duk__error_setter_helper(ctx, DUK_STRIDX_STACK);
+DUK_INTERNAL duk_ret_t duk_bi_error_prototype_stack_setter(duk_hthread *thr) {
+ return duk__error_setter_helper(thr, DUK_STRIDX_STACK);
}
-DUK_INTERNAL duk_ret_t duk_bi_error_prototype_filename_setter(duk_context *ctx) {
- return duk__error_setter_helper(ctx, DUK_STRIDX_FILE_NAME);
+DUK_INTERNAL duk_ret_t duk_bi_error_prototype_filename_setter(duk_hthread *thr) {
+ return duk__error_setter_helper(thr, DUK_STRIDX_FILE_NAME);
}
-DUK_INTERNAL duk_ret_t duk_bi_error_prototype_linenumber_setter(duk_context *ctx) {
- return duk__error_setter_helper(ctx, DUK_STRIDX_LINE_NUMBER);
+DUK_INTERNAL duk_ret_t duk_bi_error_prototype_linenumber_setter(duk_hthread *thr) {
+ return duk__error_setter_helper(thr, DUK_STRIDX_LINE_NUMBER);
}
/* automatic undefs */
@@ -30962,15 +32143,14 @@ DUK_INTERNAL duk_ret_t duk_bi_error_prototype_linenumber_setter(duk_context *ctx
/* #include duk_internal.h -> already included */
/* Needed even when Function built-in is disabled. */
-DUK_INTERNAL duk_ret_t duk_bi_function_prototype(duk_context *ctx) {
+DUK_INTERNAL duk_ret_t duk_bi_function_prototype(duk_hthread *thr) {
/* ignore arguments, return undefined (E5 Section 15.3.4) */
- DUK_UNREF(ctx);
+ DUK_UNREF(thr);
return 0;
}
#if defined(DUK_USE_FUNCTION_BUILTIN)
-DUK_INTERNAL duk_ret_t duk_bi_function_constructor(duk_context *ctx) {
- duk_hthread *thr = (duk_hthread *) ctx;
+DUK_INTERNAL duk_ret_t duk_bi_function_constructor(duk_hthread *thr) {
duk_hstring *h_sourcecode;
duk_idx_t nargs;
duk_idx_t i;
@@ -30981,57 +32161,57 @@ DUK_INTERNAL duk_ret_t duk_bi_function_constructor(duk_context *ctx) {
/* normal and constructor calls have identical semantics */
- nargs = duk_get_top(ctx);
+ nargs = duk_get_top(thr);
for (i = 0; i < nargs; i++) {
- duk_to_string(ctx, i); /* Rejects Symbols during coercion. */
+ duk_to_string(thr, i); /* Rejects Symbols during coercion. */
}
if (nargs == 0) {
- duk_push_hstring_empty(ctx);
- duk_push_hstring_empty(ctx);
+ duk_push_hstring_empty(thr);
+ duk_push_hstring_empty(thr);
} else if (nargs == 1) {
/* XXX: cover this with the generic >1 case? */
- duk_push_hstring_empty(ctx);
+ duk_push_hstring_empty(thr);
} else {
- duk_insert(ctx, 0); /* [ arg1 ... argN-1 body] -> [body arg1 ... argN-1] */
- duk_push_string(ctx, ",");
- duk_insert(ctx, 1);
- duk_join(ctx, nargs - 1);
+ duk_insert(thr, 0); /* [ arg1 ... argN-1 body] -> [body arg1 ... argN-1] */
+ duk_push_string(thr, ",");
+ duk_insert(thr, 1);
+ duk_join(thr, nargs - 1);
}
/* [ body formals ], formals is comma separated list that needs to be parsed */
- DUK_ASSERT_TOP(ctx, 2);
+ DUK_ASSERT_TOP(thr, 2);
/* XXX: this placeholder is not always correct, but use for now.
* It will fail in corner cases; see test-dev-func-cons-args.js.
*/
- duk_push_string(ctx, "function(");
- duk_dup_1(ctx);
- duk_push_string(ctx, "){");
- duk_dup_0(ctx);
- duk_push_string(ctx, "}");
- duk_concat(ctx, 5);
+ duk_push_string(thr, "function(");
+ duk_dup_1(thr);
+ duk_push_string(thr, "){");
+ duk_dup_0(thr);
+ duk_push_string(thr, "}");
+ duk_concat(thr, 5);
/* [ body formals source ] */
- DUK_ASSERT_TOP(ctx, 3);
+ DUK_ASSERT_TOP(thr, 3);
/* strictness is not inherited, intentional */
comp_flags = DUK_COMPILE_FUNCEXPR;
- duk_push_hstring_stridx(ctx, DUK_STRIDX_COMPILE); /* XXX: copy from caller? */ /* XXX: ignored now */
- h_sourcecode = duk_require_hstring(ctx, -2); /* no symbol check needed; -2 is concat'd code */
+ duk_push_hstring_stridx(thr, DUK_STRIDX_COMPILE); /* XXX: copy from caller? */ /* XXX: ignored now */
+ h_sourcecode = duk_require_hstring(thr, -2); /* no symbol check needed; -2 is concat'd code */
duk_js_compile(thr,
(const duk_uint8_t *) DUK_HSTRING_GET_DATA(h_sourcecode),
(duk_size_t) DUK_HSTRING_GET_BYTELEN(h_sourcecode),
comp_flags);
/* Force .name to 'anonymous' (ES2015). */
- duk_push_string(ctx, "anonymous");
- duk_xdef_prop_stridx_short(ctx, -2, DUK_STRIDX_NAME, DUK_PROPDESC_FLAGS_C);
+ duk_push_string(thr, "anonymous");
+ duk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_NAME, DUK_PROPDESC_FLAGS_C);
- func = (duk_hcompfunc *) duk_known_hobject(ctx, -1);
+ func = (duk_hcompfunc *) duk_known_hobject(thr, -1);
DUK_ASSERT(DUK_HOBJECT_IS_COMPFUNC((duk_hobject *) func));
DUK_ASSERT(DUK_HOBJECT_HAS_CONSTRUCTABLE((duk_hobject *) func));
@@ -31053,7 +32233,7 @@ DUK_INTERNAL duk_ret_t duk_bi_function_constructor(duk_context *ctx) {
#endif /* DUK_USE_FUNCTION_BUILTIN */
#if defined(DUK_USE_FUNCTION_BUILTIN)
-DUK_INTERNAL duk_ret_t duk_bi_function_prototype_to_string(duk_context *ctx) {
+DUK_INTERNAL duk_ret_t duk_bi_function_prototype_to_string(duk_hthread *thr) {
duk_tval *tv;
/*
@@ -31076,8 +32256,8 @@ DUK_INTERNAL duk_ret_t duk_bi_function_prototype_to_string(duk_context *ctx) {
* [lightfunc code].
*/
- duk_push_this(ctx);
- tv = DUK_GET_TVAL_NEGIDX(ctx, -1);
+ duk_push_this(thr);
+ tv = DUK_GET_TVAL_NEGIDX(thr, -1);
DUK_ASSERT(tv != NULL);
if (DUK_TVAL_IS_OBJECT(tv)) {
@@ -31091,25 +32271,25 @@ DUK_INTERNAL duk_ret_t duk_bi_function_prototype_to_string(duk_context *ctx) {
* if the name contained a suitable prefix followed by '//' it
* might cause the result to parse without error.
*/
- duk_get_prop_stridx_short(ctx, -1, DUK_STRIDX_NAME);
- if (duk_is_undefined(ctx, -1)) {
+ duk_get_prop_stridx_short(thr, -1, DUK_STRIDX_NAME);
+ if (duk_is_undefined(thr, -1)) {
func_name = "";
} else {
- func_name = duk_to_string(ctx, -1);
+ func_name = duk_to_string(thr, -1);
DUK_ASSERT(func_name != NULL);
}
if (DUK_HOBJECT_IS_COMPFUNC(obj)) {
- duk_push_sprintf(ctx, "function %s() { [ecmascript code] }", (const char *) func_name);
+ duk_push_sprintf(thr, "function %s() { [ecmascript code] }", (const char *) func_name);
} else if (DUK_HOBJECT_IS_NATFUNC(obj)) {
- duk_push_sprintf(ctx, "function %s() { [native code] }", (const char *) func_name);
+ duk_push_sprintf(thr, "function %s() { [native code] }", (const char *) func_name);
} else if (DUK_HOBJECT_IS_BOUNDFUNC(obj)) {
- duk_push_sprintf(ctx, "function %s() { [bound code] }", (const char *) func_name);
+ duk_push_sprintf(thr, "function %s() { [bound code] }", (const char *) func_name);
} else {
goto type_error;
}
} else if (DUK_TVAL_IS_LIGHTFUNC(tv)) {
- duk_push_lightfunc_tostring(ctx, tv);
+ duk_push_lightfunc_tostring(thr, tv);
} else {
goto type_error;
}
@@ -31117,266 +32297,287 @@ DUK_INTERNAL duk_ret_t duk_bi_function_prototype_to_string(duk_context *ctx) {
return 1;
type_error:
- DUK_DCERROR_TYPE_INVALID_ARGS((duk_hthread *) ctx);
+ DUK_DCERROR_TYPE_INVALID_ARGS(thr);
}
#endif
-#if defined(DUK_USE_FUNCTION_BUILTIN) || defined(DUK_USE_REFLECT_BUILTIN)
-DUK_INTERNAL duk_ret_t duk_bi_function_prototype_apply(duk_context *ctx) {
- /*
- * magic = 0: Function.prototype.apply()
- * magic = 1: Reflect.apply()
- * magic = 2: Reflect.construct()
+/* Always present because the native function pointer is needed in call
+ * handling.
+ */
+DUK_INTERNAL duk_ret_t duk_bi_function_prototype_call(duk_hthread *thr) {
+ /* .call() is dealt with in call handling by simulating its
+ * effects so this function is actually never called.
*/
+ DUK_UNREF(thr);
+ return DUK_RET_TYPE_ERROR;
+}
- duk_idx_t idx_args;
- duk_idx_t len;
- duk_idx_t i;
- duk_int_t magic;
- duk_idx_t nargs;
- duk_uint_t mask;
-
- magic = duk_get_current_magic(ctx);
- switch (magic) {
- case 0: /* Function.prototype.apply() */
- DUK_ASSERT_TOP(ctx, 2); /* not a vararg function */
- duk_push_this(ctx);
- duk_insert(ctx, 0);
- /* Fall through intentionally for shared handling. */
- case 1: /* Reflect.apply(); Function.prototype.apply() after 'this' fixup. */
- DUK_ASSERT_TOP(ctx, 3); /* not a vararg function */
- idx_args = 2;
- duk_require_callable(ctx, 0);
- break;
- default: /* Reflect.construct() */
- DUK_ASSERT(magic == 2);
- duk_require_constructable(ctx, 0);
- nargs = duk_get_top(ctx);
- if (nargs < 2) {
- DUK_DCERROR_TYPE_INVALID_ARGS((duk_hthread *) ctx);
- }
- if (nargs >= 3 && !duk_strict_equals(ctx, 0, 2)) {
- /* XXX: [[Construct]] newTarget currently unsupported */
- DUK_ERROR_UNSUPPORTED((duk_hthread *) ctx);
- }
- idx_args = 1;
- break;
- }
-
- if (magic != 2) {
- DUK_DDD(DUK_DDDPRINT("func=%!iT, thisArg=%!iT, argArray=%!iT",
- (duk_tval *) duk_get_tval(ctx, 0),
- (duk_tval *) duk_get_tval(ctx, 1),
- (duk_tval *) duk_get_tval(ctx, 2)));
- } else {
- /* thisArg is not applicable for Reflect.construct(). */
- DUK_DDD(DUK_DDDPRINT("func=%!iT, argArray=%!iT",
- (duk_tval *) duk_get_tval(ctx, 0),
- (duk_tval *) duk_get_tval(ctx, 1)));
- }
-
- /* [ func thisArg? argArray ] */
-
- mask = duk_get_type_mask(ctx, idx_args);
- if (mask & (DUK_TYPE_MASK_NULL | DUK_TYPE_MASK_UNDEFINED)) {
- DUK_DDD(DUK_DDDPRINT("argArray is null/undefined, no args"));
- len = 0;
- } else if (mask & DUK_TYPE_MASK_OBJECT) {
- DUK_DDD(DUK_DDDPRINT("argArray is an object"));
-
- /* XXX: make this an internal helper */
- DUK_ASSERT(idx_args >= 0 && idx_args <= 0x7fffL); /* short variants would work, but avoid shifting */
- duk_get_prop_stridx(ctx, idx_args, DUK_STRIDX_LENGTH);
- len = (duk_idx_t) duk_to_uint32(ctx, -1); /* ToUint32() coercion required */
- duk_pop(ctx);
-
- duk_require_stack(ctx, len);
-
- DUK_DDD(DUK_DDDPRINT("argArray length is %ld", (long) len));
- for (i = 0; i < len; i++) {
- duk_get_prop_index(ctx, idx_args, i);
- }
- } else {
- goto type_error;
- }
- duk_remove(ctx, idx_args);
- DUK_ASSERT_TOP(ctx, idx_args + len);
-
- /* [ func thisArg? arg1 ... argN ] */
+DUK_INTERNAL duk_ret_t duk_bi_function_prototype_apply(duk_hthread *thr) {
+ /* Like .call(), never actually called. */
+ DUK_UNREF(thr);
+ return DUK_RET_TYPE_ERROR;
+}
- if (magic != 2) {
- /* Function.prototype.apply() or Reflect.apply() */
- DUK_DDD(DUK_DDDPRINT("apply, func=%!iT, thisArg=%!iT, len=%ld",
- (duk_tval *) duk_get_tval(ctx, 0),
- (duk_tval *) duk_get_tval(ctx, 1),
- (long) len));
- duk_call_method(ctx, len);
- } else {
- /* Reflect.construct() */
- DUK_DDD(DUK_DDDPRINT("construct, func=%!iT, len=%ld",
- (duk_tval *) duk_get_tval(ctx, 0),
- (long) len));
- duk_new(ctx, len);
- }
- return 1;
+DUK_INTERNAL duk_ret_t duk_bi_reflect_apply(duk_hthread *thr) {
+ /* Like .call(), never actually called. */
+ DUK_UNREF(thr);
+ return DUK_RET_TYPE_ERROR;
+}
- type_error:
- DUK_DCERROR_TYPE_INVALID_ARGS((duk_hthread *) ctx);
+DUK_INTERNAL duk_ret_t duk_bi_reflect_construct(duk_hthread *thr) {
+ /* Like .call(), never actually called. */
+ DUK_UNREF(thr);
+ return DUK_RET_TYPE_ERROR;
}
-#endif
#if defined(DUK_USE_FUNCTION_BUILTIN)
-DUK_INTERNAL duk_ret_t duk_bi_function_prototype_call(duk_context *ctx) {
- duk_idx_t nargs;
+/* Create a bound function which points to a target function which may
+ * be bound or non-bound. If the target is bound, the argument lists
+ * and 'this' binding of the functions are merged and the resulting
+ * function points directly to the non-bound target.
+ */
+DUK_INTERNAL duk_ret_t duk_bi_function_prototype_bind(duk_hthread *thr) {
+ duk_hboundfunc *h_bound;
+ duk_idx_t nargs; /* bound args, not counting 'this' binding */
+ duk_idx_t bound_nargs;
+ duk_int_t bound_len;
+ duk_tval *tv_prevbound;
+ duk_idx_t n_prevbound;
+ duk_tval *tv_res;
+ duk_tval *tv_tmp;
- /* Step 1 is not necessary because duk_call_method() will take
- * care of it.
- */
+ /* XXX: C API call, e.g. duk_push_bound_function(thr, target_idx, nargs); */
- /* vararg function, thisArg needs special handling */
- nargs = duk_get_top(ctx); /* = 1 + arg count */
- if (nargs == 0) {
- duk_push_undefined(ctx);
+ /* Vararg function, careful arg handling, e.g. thisArg may not
+ * be present.
+ */
+ nargs = duk_get_top(thr) - 1; /* actual args, not counting 'this' binding */
+ if (nargs < 0) {
nargs++;
+ duk_push_undefined(thr);
}
- DUK_ASSERT(nargs >= 1);
-
- /* [ thisArg arg1 ... argN ] */
+ DUK_ASSERT(nargs >= 0);
- duk_push_this(ctx); /* 'func' in the algorithm */
- duk_insert(ctx, 0);
+ /* Limit 'nargs' for bound functions to guarantee arithmetic
+ * below will never wrap.
+ */
+ if (nargs > (duk_idx_t) DUK_HBOUNDFUNC_MAX_ARGS) {
+ DUK_DCERROR_RANGE_INVALID_COUNT(thr);
+ }
- /* [ func thisArg arg1 ... argN ] */
+ duk_push_this(thr);
+ duk_require_callable(thr, -1);
- DUK_DDD(DUK_DDDPRINT("func=%!iT, thisArg=%!iT, argcount=%ld, top=%ld",
- (duk_tval *) duk_get_tval(ctx, 0),
- (duk_tval *) duk_get_tval(ctx, 1),
- (long) (nargs - 1),
- (long) duk_get_top(ctx)));
- duk_call_method(ctx, nargs - 1);
- return 1;
-}
-#endif /* DUK_USE_FUNCTION_BUILTIN */
+ /* [ thisArg arg1 ... argN func ] (thisArg+args == nargs+1 total) */
+ DUK_ASSERT_TOP(thr, nargs + 2);
-#if defined(DUK_USE_FUNCTION_BUILTIN)
-/* XXX: the implementation now assumes "chained" bound functions,
- * whereas "collapsed" bound functions (where there is ever only
- * one bound function which directly points to a non-bound, final
- * function) would require a "collapsing" implementation which
- * merges argument lists etc here.
- */
-DUK_INTERNAL duk_ret_t duk_bi_function_prototype_bind(duk_context *ctx) {
- duk_hthread *thr = (duk_hthread *) ctx;
- duk_hobject *h_bound;
- duk_hobject *h_target;
- duk_idx_t nargs;
- duk_idx_t i;
+ /* Create bound function object. */
+ h_bound = duk_push_hboundfunc(thr);
+ DUK_ASSERT(DUK_TVAL_IS_UNDEFINED(&h_bound->target));
+ DUK_ASSERT(DUK_TVAL_IS_UNDEFINED(&h_bound->this_binding));
+ DUK_ASSERT(h_bound->args == NULL);
+ DUK_ASSERT(h_bound->nargs == 0);
+ DUK_ASSERT(DUK_HOBJECT_GET_PROTOTYPE(thr->heap, (duk_hobject *) h_bound) == NULL);
- /* vararg function, careful arg handling (e.g. thisArg may not be present) */
- nargs = duk_get_top(ctx); /* = 1 + arg count */
- if (nargs == 0) {
- duk_push_undefined(ctx);
- nargs++;
- }
- DUK_ASSERT(nargs >= 1);
+ /* [ thisArg arg1 ... argN func boundFunc ] */
- duk_push_this(ctx);
- duk_require_callable(ctx, -1);
+ /* If the target is a bound function, argument lists must be
+ * merged. The 'this' binding closest to the target function
+ * wins because in call handling the 'this' gets replaced over
+ * and over again until we call the non-bound function.
+ */
+ tv_prevbound = NULL;
+ n_prevbound = 0;
+ tv_tmp = DUK_GET_TVAL_POSIDX(thr, 0);
+ DUK_TVAL_SET_TVAL(&h_bound->this_binding, tv_tmp);
+ tv_tmp = DUK_GET_TVAL_NEGIDX(thr, -2);
+ DUK_TVAL_SET_TVAL(&h_bound->target, tv_tmp);
- /* [ thisArg arg1 ... argN func ] (thisArg+args == nargs total) */
- DUK_ASSERT_TOP(ctx, nargs + 1);
+ if (DUK_TVAL_IS_OBJECT(tv_tmp)) {
+ duk_hobject *h_target;
+ duk_hobject *bound_proto;
- /* create bound function object */
- h_bound = duk_push_object_helper(ctx,
- DUK_HOBJECT_FLAG_EXTENSIBLE |
- DUK_HOBJECT_FLAG_FASTREFS |
- DUK_HOBJECT_FLAG_BOUNDFUNC |
- DUK_HOBJECT_FLAG_CONSTRUCTABLE |
- DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_FUNCTION),
- DUK_BIDX_FUNCTION_PROTOTYPE);
- DUK_ASSERT(h_bound != NULL);
+ h_target = DUK_TVAL_GET_OBJECT(tv_tmp);
+ DUK_ASSERT(DUK_HOBJECT_IS_CALLABLE(h_target));
- /* [ thisArg arg1 ... argN func boundFunc ] */
- duk_dup_m2(ctx); /* func */
- duk_xdef_prop_stridx_short(ctx, -2, DUK_STRIDX_INT_TARGET, DUK_PROPDESC_FLAGS_NONE);
+ /* Internal prototype must be copied from the target.
+ * For lightfuncs Function.prototype is used and is already
+ * in place.
+ */
+ bound_proto = DUK_HOBJECT_GET_PROTOTYPE(thr->heap, h_target);
+ DUK_HOBJECT_SET_PROTOTYPE_INIT_INCREF(thr, (duk_hobject *) h_bound, bound_proto);
- duk_dup_0(ctx); /* thisArg */
- duk_xdef_prop_stridx_short(ctx, -2, DUK_STRIDX_INT_THIS, DUK_PROPDESC_FLAGS_NONE);
+ /* The 'strict' flag is copied to get the special [[Get]] of E5.1
+ * Section 15.3.5.4 to apply when a 'caller' value is a strict bound
+ * function. Not sure if this is correct, because the specification
+ * is a bit ambiguous on this point but it would make sense.
+ */
+ /* Strictness is inherited from target. */
+ if (DUK_HOBJECT_HAS_STRICT(h_target)) {
+ DUK_HOBJECT_SET_STRICT((duk_hobject *) h_bound);
+ }
- duk_push_array(ctx);
+ if (DUK_HOBJECT_HAS_BOUNDFUNC(h_target)) {
+ duk_hboundfunc *h_boundtarget;
- /* [ thisArg arg1 ... argN func boundFunc argArray ] */
+ h_boundtarget = (duk_hboundfunc *) h_target;
- for (i = 0; i < nargs - 1; i++) {
- duk_dup(ctx, 1 + i);
- duk_put_prop_index(ctx, -2, i);
- }
- duk_xdef_prop_stridx_short(ctx, -2, DUK_STRIDX_INT_ARGS, DUK_PROPDESC_FLAGS_NONE);
+ /* The final function should always be non-bound, unless
+ * there's a bug in the internals. Assert for it.
+ */
+ DUK_ASSERT(DUK_TVAL_IS_LIGHTFUNC(&h_boundtarget->target) ||
+ (DUK_TVAL_IS_OBJECT(&h_boundtarget->target) &&
+ DUK_HOBJECT_IS_CALLABLE(DUK_TVAL_GET_OBJECT(&h_boundtarget->target)) &&
+ !DUK_HOBJECT_IS_BOUNDFUNC(DUK_TVAL_GET_OBJECT(&h_boundtarget->target))));
- /* [ thisArg arg1 ... argN func boundFunc ] */
+ DUK_TVAL_SET_TVAL(&h_bound->target, &h_boundtarget->target);
+ DUK_TVAL_SET_TVAL(&h_bound->this_binding, &h_boundtarget->this_binding);
- h_target = duk_get_hobject(ctx, -2);
+ tv_prevbound = h_boundtarget->args;
+ n_prevbound = h_boundtarget->nargs;
+ }
+ } else {
+ /* Lightfuncs are always strict. */
+ duk_hobject *bound_proto;
- /* internal prototype must be copied from the target */
- if (h_target != NULL) {
- /* For lightfuncs Function.prototype is used and is already in place. */
- DUK_HOBJECT_SET_PROTOTYPE_UPDREF(thr, h_bound, DUK_HOBJECT_GET_PROTOTYPE(thr->heap, h_target));
+ DUK_ASSERT(DUK_TVAL_IS_LIGHTFUNC(tv_tmp));
+ DUK_HOBJECT_SET_STRICT((duk_hobject *) h_bound);
+ bound_proto = thr->builtins[DUK_BIDX_FUNCTION_PROTOTYPE];
+ DUK_HOBJECT_SET_PROTOTYPE_INIT_INCREF(thr, (duk_hobject *) h_bound, bound_proto);
}
- /* bound function 'length' property is interesting */
- if (h_target == NULL || /* lightfunc */
- DUK_HOBJECT_GET_CLASS_NUMBER(h_target) == DUK_HOBJECT_CLASS_FUNCTION) {
- /* For lightfuncs, simply read the virtual property. */
- duk_int_t tmp;
- duk_get_prop_stridx_short(ctx, -2, DUK_STRIDX_LENGTH);
- tmp = duk_to_int(ctx, -1) - (nargs - 1); /* step 15.a */
- duk_pop(ctx);
- duk_push_int(ctx, (tmp < 0 ? 0 : tmp));
- } else {
- duk_push_int(ctx, 0);
+ DUK_TVAL_INCREF(thr, &h_bound->target); /* old values undefined, no decref needed */
+ DUK_TVAL_INCREF(thr, &h_bound->this_binding);
+
+ bound_nargs = n_prevbound + nargs;
+ if (bound_nargs > (duk_idx_t) DUK_HBOUNDFUNC_MAX_ARGS) {
+ DUK_DCERROR_RANGE_INVALID_COUNT(thr);
}
- duk_xdef_prop_stridx_short(ctx, -2, DUK_STRIDX_LENGTH, DUK_PROPDESC_FLAGS_C); /* attrs in E6 Section 9.2.4 */
+ tv_res = (duk_tval *) DUK_ALLOC_CHECKED(thr, ((duk_size_t) bound_nargs) * sizeof(duk_tval));
+ DUK_ASSERT(tv_res != NULL);
+ DUK_ASSERT(h_bound->args == NULL);
+ DUK_ASSERT(h_bound->nargs == 0);
+ h_bound->args = tv_res;
+ h_bound->nargs = bound_nargs;
- /* caller and arguments must use the same thrower, [[ThrowTypeError]] */
- duk_xdef_prop_stridx_thrower(ctx, -1, DUK_STRIDX_CALLER);
- duk_xdef_prop_stridx_thrower(ctx, -1, DUK_STRIDX_LC_ARGUMENTS);
+ DUK_ASSERT(n_prevbound >= 0);
+ duk_copy_tvals_incref(thr, tv_res, tv_prevbound, (duk_size_t) n_prevbound);
+ DUK_ASSERT(nargs >= 0);
+ duk_copy_tvals_incref(thr, tv_res + n_prevbound, DUK_GET_TVAL_POSIDX(thr, 1), (duk_size_t) nargs);
- /* XXX: 'copy properties' API call? */
-#if defined(DUK_USE_FUNC_NAME_PROPERTY)
- duk_push_string(ctx, "bound "); /* ES2015 19.2.3.2. */
- duk_get_prop_stridx_short(ctx, -3, DUK_STRIDX_NAME);
- if (!duk_is_string_notsymbol(ctx, -1)) {
+ /* [ thisArg arg1 ... argN func boundFunc ] */
+
+ /* Bound function 'length' property is interesting.
+ * For lightfuncs, simply read the virtual property.
+ */
+ duk_get_prop_stridx_short(thr, -2, DUK_STRIDX_LENGTH);
+ bound_len = duk_get_int(thr, -1); /* ES2015: no coercion */
+ if (bound_len < nargs) {
+ bound_len = 0;
+ } else {
+ bound_len -= nargs;
+ }
+ if (sizeof(duk_int_t) > 4 && bound_len > (duk_int_t) DUK_UINT32_MAX) {
+ bound_len = (duk_int_t) DUK_UINT32_MAX;
+ }
+ duk_pop(thr);
+ DUK_ASSERT(bound_len >= 0);
+ tv_tmp = thr->valstack_top++;
+ DUK_ASSERT(DUK_TVAL_IS_UNDEFINED(tv_tmp));
+ DUK_ASSERT(!DUK_TVAL_NEEDS_REFCOUNT_UPDATE(tv_tmp));
+ DUK_TVAL_SET_U32(tv_tmp, (duk_uint32_t) bound_len); /* in-place update, fastint */
+ duk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_LENGTH, DUK_PROPDESC_FLAGS_C); /* attrs in E6 Section 9.2.4 */
+
+ /* XXX: could these be virtual? */
+ /* Caller and arguments must use the same thrower, [[ThrowTypeError]]. */
+ duk_xdef_prop_stridx_thrower(thr, -1, DUK_STRIDX_CALLER);
+ duk_xdef_prop_stridx_thrower(thr, -1, DUK_STRIDX_LC_ARGUMENTS);
+
+ /* Function name and fileName (non-standard). */
+ duk_push_string(thr, "bound "); /* ES2015 19.2.3.2. */
+ duk_get_prop_stridx(thr, -3, DUK_STRIDX_NAME);
+ if (!duk_is_string_notsymbol(thr, -1)) {
/* ES2015 has requirement to check that .name of target is a string
* (also must check for Symbol); if not, targetName should be the
* empty string. ES2015 19.2.3.2.
*/
- duk_pop(ctx);
- duk_push_hstring_empty(ctx);
+ duk_pop(thr);
+ duk_push_hstring_empty(thr);
}
- duk_concat(ctx, 2);
- duk_xdef_prop_stridx_short(ctx, -2, DUK_STRIDX_NAME, DUK_PROPDESC_FLAGS_C);
-#endif
+ duk_concat(thr, 2);
+ duk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_NAME, DUK_PROPDESC_FLAGS_C);
#if defined(DUK_USE_FUNC_FILENAME_PROPERTY)
- duk_get_prop_stridx_short(ctx, -2, DUK_STRIDX_FILE_NAME);
- duk_xdef_prop_stridx_short(ctx, -2, DUK_STRIDX_FILE_NAME, DUK_PROPDESC_FLAGS_C);
+ duk_get_prop_stridx_short(thr, -2, DUK_STRIDX_FILE_NAME);
+ duk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_FILE_NAME, DUK_PROPDESC_FLAGS_C);
#endif
- /* The 'strict' flag is copied to get the special [[Get]] of E5.1
- * Section 15.3.5.4 to apply when a 'caller' value is a strict bound
- * function. Not sure if this is correct, because the specification
- * is a bit ambiguous on this point but it would make sense.
- */
- if (h_target == NULL) {
- /* Lightfuncs are always strict. */
- DUK_HOBJECT_SET_STRICT(h_bound);
- } else if (DUK_HOBJECT_HAS_STRICT(h_target)) {
- DUK_HOBJECT_SET_STRICT(h_bound);
- }
- DUK_DDD(DUK_DDDPRINT("created bound function: %!iT", (duk_tval *) duk_get_tval(ctx, -1)));
+ DUK_DDD(DUK_DDDPRINT("created bound function: %!iT", (duk_tval *) duk_get_tval(thr, -1)));
return 1;
}
#endif /* DUK_USE_FUNCTION_BUILTIN */
+
+/* %NativeFunctionPrototype% .length getter. */
+DUK_INTERNAL duk_ret_t duk_bi_native_function_length(duk_hthread *thr) {
+ duk_tval *tv;
+ duk_hnatfunc *h;
+ duk_int16_t func_nargs;
+
+ tv = duk_get_borrowed_this_tval(thr);
+ DUK_ASSERT(tv != NULL);
+
+ if (DUK_TVAL_IS_OBJECT(tv)) {
+ h = (duk_hnatfunc *) DUK_TVAL_GET_OBJECT(tv);
+ DUK_ASSERT(h != NULL);
+ if (!DUK_HOBJECT_IS_NATFUNC((duk_hobject *) h)) {
+ goto fail_type;
+ }
+ func_nargs = h->nargs;
+ duk_push_int(thr, func_nargs == DUK_HNATFUNC_NARGS_VARARGS ? 0 : func_nargs);
+ } else if (DUK_TVAL_IS_LIGHTFUNC(tv)) {
+ duk_small_uint_t lf_flags;
+ duk_small_uint_t lf_len;
+
+ lf_flags = DUK_TVAL_GET_LIGHTFUNC_FLAGS(tv);
+ lf_len = DUK_LFUNC_FLAGS_GET_LENGTH(lf_flags);
+ duk_push_uint(thr, lf_len);
+ } else {
+ goto fail_type;
+ }
+ return 1;
+
+ fail_type:
+ DUK_DCERROR_TYPE_INVALID_ARGS(thr);
+}
+
+/* %NativeFunctionPrototype% .name getter. */
+DUK_INTERNAL duk_ret_t duk_bi_native_function_name(duk_hthread *thr) {
+ duk_tval *tv;
+ duk_hnatfunc *h;
+
+ tv = duk_get_borrowed_this_tval(thr);
+ DUK_ASSERT(tv != NULL);
+
+ if (DUK_TVAL_IS_OBJECT(tv)) {
+ h = (duk_hnatfunc *) DUK_TVAL_GET_OBJECT(tv);
+ DUK_ASSERT(h != NULL);
+ if (!DUK_HOBJECT_IS_NATFUNC((duk_hobject *) h)) {
+ goto fail_type;
+ }
+#if 0
+ duk_push_hnatfunc_name(thr, h);
+#endif
+ duk_push_hstring_empty(thr);
+ } else if (DUK_TVAL_IS_LIGHTFUNC(tv)) {
+ duk_push_lightfunc_name(thr, tv);
+ } else {
+ goto fail_type;
+ }
+ return 1;
+
+ fail_type:
+ DUK_DCERROR_TYPE_INVALID_ARGS(thr);
+}
/*
* Global object built-ins
*/
@@ -31492,15 +32693,14 @@ DUK_LOCAL duk_small_int_t duk__decode_hex_escape(const duk_uint8_t *p, duk_small
return t;
}
-DUK_LOCAL int duk__transform_helper(duk_context *ctx, duk__transform_callback callback, const void *udata) {
- duk_hthread *thr = (duk_hthread *) ctx;
+DUK_LOCAL int duk__transform_helper(duk_hthread *thr, duk__transform_callback callback, const void *udata) {
duk__transform_context tfm_ctx_alloc;
duk__transform_context *tfm_ctx = &tfm_ctx_alloc;
duk_codepoint_t cp;
tfm_ctx->thr = thr;
- tfm_ctx->h_str = duk_to_hstring(ctx, 0);
+ tfm_ctx->h_str = duk_to_hstring(thr, 0);
DUK_ASSERT(tfm_ctx->h_str != NULL);
DUK_BW_INIT_PUSHBUF(thr, &tfm_ctx->bw, DUK_HSTRING_GET_BYTELEN(tfm_ctx->h_str)); /* initial size guess */
@@ -31516,7 +32716,7 @@ DUK_LOCAL int duk__transform_helper(duk_context *ctx, duk__transform_callback ca
DUK_BW_COMPACT(thr, &tfm_ctx->bw);
- (void) duk_buffer_to_string(ctx, -1); /* Safe if transform is safe. */
+ (void) duk_buffer_to_string(thr, -1); /* Safe if transform is safe. */
return 1;
}
@@ -31549,7 +32749,7 @@ DUK_LOCAL void duk__transform_callback_encode_uri(duk__transform_context *tfm_ct
goto uri_error;
}
cp1 = cp;
- cp = ((cp1 - 0xd800L) << 10) + (cp2 - 0xdc00L) + 0x10000L;
+ cp = (duk_codepoint_t) (((cp1 - 0xd800L) << 10) + (cp2 - 0xdc00L) + 0x10000L);
} else if (cp > 0x10ffffL) {
/* Although we can allow non-BMP characters (they'll decode
* back into surrogate pairs), we don't allow extended UTF-8
@@ -31707,7 +32907,7 @@ DUK_LOCAL void duk__transform_callback_decode_uri(duk__transform_context *tfm_ct
DUK_ASSERT(cp < 0x100000L);
DUK_BW_WRITE_RAW_XUTF8(tfm_ctx->thr, &tfm_ctx->bw, ((cp >> 10) + 0xd800L));
- DUK_BW_WRITE_RAW_XUTF8(tfm_ctx->thr, &tfm_ctx->bw, ((cp & 0x03ffUL) + 0xdc00L));
+ DUK_BW_WRITE_RAW_XUTF8(tfm_ctx->thr, &tfm_ctx->bw, ((cp & 0x03ffL) + 0xdc00L));
} else {
DUK_BW_WRITE_RAW_XUTF8(tfm_ctx->thr, &tfm_ctx->bw, cp);
}
@@ -31795,20 +32995,19 @@ DUK_LOCAL void duk__transform_callback_unescape(duk__transform_context *tfm_ctx,
* calling activation at all which needs careful handling.
*/
-DUK_INTERNAL duk_ret_t duk_bi_global_object_eval(duk_context *ctx) {
- duk_hthread *thr = (duk_hthread *) ctx;
+DUK_INTERNAL duk_ret_t duk_bi_global_object_eval(duk_hthread *thr) {
duk_hstring *h;
duk_activation *act_caller;
duk_activation *act_eval;
- duk_activation *act;
duk_hcompfunc *func;
duk_hobject *outer_lex_env;
duk_hobject *outer_var_env;
duk_bool_t this_to_global = 1;
duk_small_uint_t comp_flags;
duk_int_t level = -2;
+ duk_small_uint_t call_flags;
- DUK_ASSERT(duk_get_top(ctx) == 1 || duk_get_top(ctx) == 2); /* 2 when called by debugger */
+ DUK_ASSERT(duk_get_top(thr) == 1 || duk_get_top(thr) == 2); /* 2 when called by debugger */
DUK_ASSERT(thr->callstack_top >= 1); /* at least this function exists */
DUK_ASSERT(thr->callstack_curr != NULL);
DUK_ASSERT((thr->callstack_curr->flags & DUK_ACT_FLAG_DIRECT_EVAL) == 0 || /* indirect eval */
@@ -31822,7 +33021,7 @@ DUK_INTERNAL duk_ret_t duk_bi_global_object_eval(duk_context *ctx) {
* activation doesn't exist, call must be indirect.
*/
- h = duk_get_hstring_notsymbol(ctx, 0);
+ h = duk_get_hstring_notsymbol(thr, 0);
if (!h) {
/* Symbol must be returned as is, like any non-string values. */
return 1; /* return arg as-is */
@@ -31833,8 +33032,8 @@ DUK_INTERNAL duk_ret_t duk_bi_global_object_eval(duk_context *ctx) {
* for an Ecmascript eval().
*/
DUK_ASSERT(level == -2); /* by default, use caller's environment */
- if (duk_get_top(ctx) >= 2 && duk_is_number(ctx, 1)) {
- level = duk_get_int(ctx, 1);
+ if (duk_get_top(thr) >= 2 && duk_is_number(thr, 1)) {
+ level = duk_get_int(thr, 1);
}
DUK_ASSERT(level <= -2); /* This is guaranteed by debugger code. */
#endif
@@ -31844,11 +33043,11 @@ DUK_INTERNAL duk_ret_t duk_bi_global_object_eval(duk_context *ctx) {
comp_flags = DUK_COMPILE_EVAL;
act_eval = thr->callstack_curr; /* this function */
DUK_ASSERT(act_eval != NULL);
- if (thr->callstack_top >= (duk_size_t) -level) {
+ act_caller = duk_hthread_get_activation_for_level(thr, level);
+ if (act_caller != NULL) {
/* Have a calling activation, check for direct eval (otherwise
* assume indirect eval.
*/
- act_caller = thr->callstack + thr->callstack_top + level; /* caller */
if ((act_caller->flags & DUK_ACT_FLAG_STRICT) &&
(act_eval->flags & DUK_ACT_FLAG_DIRECT_EVAL)) {
/* Only direct eval inherits strictness from calling code
@@ -31859,35 +33058,31 @@ DUK_INTERNAL duk_ret_t duk_bi_global_object_eval(duk_context *ctx) {
} else {
DUK_ASSERT((act_eval->flags & DUK_ACT_FLAG_DIRECT_EVAL) == 0);
}
- act_caller = NULL; /* avoid dereference after potential callstack realloc */
- act_eval = NULL;
- duk_push_hstring_stridx(ctx, DUK_STRIDX_INPUT); /* XXX: copy from caller? */
+ duk_push_hstring_stridx(thr, DUK_STRIDX_INPUT); /* XXX: copy from caller? */
duk_js_compile(thr,
(const duk_uint8_t *) DUK_HSTRING_GET_DATA(h),
(duk_size_t) DUK_HSTRING_GET_BYTELEN(h),
comp_flags);
- func = (duk_hcompfunc *) duk_known_hobject(ctx, -1);
+ func = (duk_hcompfunc *) duk_known_hobject(thr, -1);
DUK_ASSERT(DUK_HOBJECT_IS_COMPFUNC((duk_hobject *) func));
/* [ source template ] */
/* E5 Section 10.4.2 */
- DUK_ASSERT(thr->callstack_top >= 1);
- act = thr->callstack_curr; /* this function */
- if (act->flags & DUK_ACT_FLAG_DIRECT_EVAL) {
+
+ if (act_eval->flags & DUK_ACT_FLAG_DIRECT_EVAL) {
DUK_ASSERT(thr->callstack_top >= 2);
- act = thr->callstack + thr->callstack_top + level; /* caller */
- if (act->lex_env == NULL) {
- DUK_ASSERT(act->var_env == NULL);
+ DUK_ASSERT(act_caller != NULL);
+ if (act_caller->lex_env == NULL) {
+ DUK_ASSERT(act_caller->var_env == NULL);
DUK_DDD(DUK_DDDPRINT("delayed environment initialization"));
/* this may have side effects, so re-lookup act */
- duk_js_init_activation_environment_records_delayed(thr, act);
- act = thr->callstack + thr->callstack_top + level;
+ duk_js_init_activation_environment_records_delayed(thr, act_caller);
}
- DUK_ASSERT(act->lex_env != NULL);
- DUK_ASSERT(act->var_env != NULL);
+ DUK_ASSERT(act_caller->lex_env != NULL);
+ DUK_ASSERT(act_caller->var_env != NULL);
this_to_global = 0;
@@ -31899,14 +33094,13 @@ DUK_INTERNAL duk_ret_t duk_bi_global_object_eval(duk_context *ctx) {
"var_env and lex_env to a fresh env, "
"this_binding to caller's this_binding"));
- act_lex_env = act->lex_env;
- act = NULL; /* invalidated */
+ act_lex_env = act_caller->lex_env;
new_env = duk_hdecenv_alloc(thr,
DUK_HOBJECT_FLAG_EXTENSIBLE |
DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_DECENV));
DUK_ASSERT(new_env != NULL);
- duk_push_hobject(ctx, (duk_hobject *) new_env);
+ duk_push_hobject(thr, (duk_hobject *) new_env);
DUK_ASSERT(DUK_HOBJECT_GET_PROTOTYPE(thr->heap, (duk_hobject *) new_env) == NULL);
DUK_HOBJECT_SET_PROTOTYPE(thr->heap, (duk_hobject *) new_env, act_lex_env);
@@ -31916,7 +33110,7 @@ DUK_INTERNAL duk_ret_t duk_bi_global_object_eval(duk_context *ctx) {
outer_lex_env = (duk_hobject *) new_env;
outer_var_env = (duk_hobject *) new_env;
- duk_insert(ctx, 0); /* stash to bottom of value stack to keep new_env reachable for duration of eval */
+ duk_insert(thr, 0); /* stash to bottom of value stack to keep new_env reachable for duration of eval */
/* compiler's responsibility */
DUK_ASSERT(DUK_HOBJECT_HAS_NEWENV((duk_hobject *) func));
@@ -31925,8 +33119,8 @@ DUK_INTERNAL duk_ret_t duk_bi_global_object_eval(duk_context *ctx) {
"var_env and lex_env to caller's envs, "
"this_binding to caller's this_binding"));
- outer_lex_env = act->lex_env;
- outer_var_env = act->var_env;
+ outer_lex_env = act_caller->lex_env;
+ outer_var_env = act_caller->var_env;
/* compiler's responsibility */
DUK_ASSERT(!DUK_HOBJECT_HAS_NEWENV((duk_hobject *) func));
@@ -31939,7 +33133,6 @@ DUK_INTERNAL duk_ret_t duk_bi_global_object_eval(duk_context *ctx) {
outer_lex_env = thr->builtins[DUK_BIDX_GLOBAL_ENV];
outer_var_env = thr->builtins[DUK_BIDX_GLOBAL_ENV];
}
- act = NULL;
/* Eval code doesn't need an automatic .prototype object. */
duk_js_push_closure(thr, func, outer_var_env, outer_lex_env, 0 /*add_auto_proto*/);
@@ -31948,24 +33141,34 @@ DUK_INTERNAL duk_ret_t duk_bi_global_object_eval(duk_context *ctx) {
if (this_to_global) {
DUK_ASSERT(thr->builtins[DUK_BIDX_GLOBAL] != NULL);
- duk_push_hobject_bidx(ctx, DUK_BIDX_GLOBAL);
+ duk_push_hobject_bidx(thr, DUK_BIDX_GLOBAL);
} else {
duk_tval *tv;
DUK_ASSERT(thr->callstack_top >= 2);
- act = thr->callstack + thr->callstack_top + level; /* caller */
- tv = thr->valstack + act->idx_bottom - 1; /* this is just beneath bottom */
+ DUK_ASSERT(act_caller != NULL);
+ tv = (duk_tval *) (void *) ((duk_uint8_t *) thr->valstack + act_caller->bottom_byteoff - sizeof(duk_tval)); /* this is just beneath bottom */
DUK_ASSERT(tv >= thr->valstack);
- duk_push_tval(ctx, tv);
+ duk_push_tval(thr, tv);
}
DUK_DDD(DUK_DDDPRINT("eval -> lex_env=%!iO, var_env=%!iO, this_binding=%!T",
(duk_heaphdr *) outer_lex_env,
(duk_heaphdr *) outer_var_env,
- duk_get_tval(ctx, -1)));
+ duk_get_tval(thr, -1)));
/* [ env? source template closure this ] */
- duk_call_method(ctx, 0);
+ call_flags = 0;
+ if (act_eval->flags & DUK_ACT_FLAG_DIRECT_EVAL) {
+ /* Set DIRECT_EVAL flag for the call; it's not strictly
+ * needed for the 'inner' eval call (the eval body) but
+ * current new.target implementation expects to find it
+ * so it can traverse direct eval chains up to the real
+ * calling function.
+ */
+ call_flags |= DUK_CALL_FLAG_DIRECT_EVAL;
+ }
+ duk_handle_call_unprotected_nargs(thr, 0, call_flags);
/* [ env? source template result ] */
@@ -31977,14 +33180,14 @@ DUK_INTERNAL duk_ret_t duk_bi_global_object_eval(duk_context *ctx) {
*/
#if defined(DUK_USE_GLOBAL_BUILTIN)
-DUK_INTERNAL duk_ret_t duk_bi_global_object_parse_int(duk_context *ctx) {
+DUK_INTERNAL duk_ret_t duk_bi_global_object_parse_int(duk_hthread *thr) {
duk_int32_t radix;
duk_small_uint_t s2n_flags;
- DUK_ASSERT_TOP(ctx, 2);
- duk_to_string(ctx, 0); /* Reject symbols. */
+ DUK_ASSERT_TOP(thr, 2);
+ duk_to_string(thr, 0); /* Reject symbols. */
- radix = duk_to_int32(ctx, 1);
+ radix = duk_to_int32(thr, 1);
/* While parseInt() recognizes 0xdeadbeef, it doesn't recognize
* ES2015 0o123 or 0b10001.
@@ -32014,25 +33217,22 @@ DUK_INTERNAL duk_ret_t duk_bi_global_object_parse_int(duk_context *ctx) {
radix = 10;
}
- duk_dup_0(ctx);
- duk_numconv_parse(ctx, radix, s2n_flags);
+ duk_dup_0(thr);
+ duk_numconv_parse(thr, (duk_small_int_t) radix, s2n_flags);
return 1;
ret_nan:
- duk_push_nan(ctx);
+ duk_push_nan(thr);
return 1;
}
#endif /* DUK_USE_GLOBAL_BUILTIN */
#if defined(DUK_USE_GLOBAL_BUILTIN)
-DUK_INTERNAL duk_ret_t duk_bi_global_object_parse_float(duk_context *ctx) {
+DUK_INTERNAL duk_ret_t duk_bi_global_object_parse_float(duk_hthread *thr) {
duk_small_uint_t s2n_flags;
- duk_int32_t radix;
-
- DUK_ASSERT_TOP(ctx, 1);
- duk_to_string(ctx, 0); /* Reject symbols. */
- radix = 10;
+ DUK_ASSERT_TOP(thr, 1);
+ duk_to_string(thr, 0); /* Reject symbols. */
/* XXX: check flags */
s2n_flags = DUK_S2N_FLAG_TRIM_WHITE |
@@ -32046,7 +33246,7 @@ DUK_INTERNAL duk_ret_t duk_bi_global_object_parse_float(duk_context *ctx) {
DUK_S2N_FLAG_ALLOW_EMPTY_FRAC |
DUK_S2N_FLAG_ALLOW_LEADING_ZERO;
- duk_numconv_parse(ctx, radix, s2n_flags);
+ duk_numconv_parse(thr, 10 /*radix*/, s2n_flags);
return 1;
}
#endif /* DUK_USE_GLOBAL_BUILTIN */
@@ -32056,17 +33256,17 @@ DUK_INTERNAL duk_ret_t duk_bi_global_object_parse_float(duk_context *ctx) {
*/
#if defined(DUK_USE_GLOBAL_BUILTIN)
-DUK_INTERNAL duk_ret_t duk_bi_global_object_is_nan(duk_context *ctx) {
- duk_double_t d = duk_to_number(ctx, 0);
- duk_push_boolean(ctx, DUK_ISNAN(d));
+DUK_INTERNAL duk_ret_t duk_bi_global_object_is_nan(duk_hthread *thr) {
+ duk_double_t d = duk_to_number(thr, 0);
+ duk_push_boolean(thr, (duk_bool_t) DUK_ISNAN(d));
return 1;
}
#endif /* DUK_USE_GLOBAL_BUILTIN */
#if defined(DUK_USE_GLOBAL_BUILTIN)
-DUK_INTERNAL duk_ret_t duk_bi_global_object_is_finite(duk_context *ctx) {
- duk_double_t d = duk_to_number(ctx, 0);
- duk_push_boolean(ctx, DUK_ISFINITE(d));
+DUK_INTERNAL duk_ret_t duk_bi_global_object_is_finite(duk_hthread *thr) {
+ duk_double_t d = duk_to_number(thr, 0);
+ duk_push_boolean(thr, (duk_bool_t) DUK_ISFINITE(d));
return 1;
}
#endif /* DUK_USE_GLOBAL_BUILTIN */
@@ -32076,29 +33276,29 @@ DUK_INTERNAL duk_ret_t duk_bi_global_object_is_finite(duk_context *ctx) {
*/
#if defined(DUK_USE_GLOBAL_BUILTIN)
-DUK_INTERNAL duk_ret_t duk_bi_global_object_decode_uri(duk_context *ctx) {
- return duk__transform_helper(ctx, duk__transform_callback_decode_uri, (const void *) duk__decode_uri_reserved_table);
+DUK_INTERNAL duk_ret_t duk_bi_global_object_decode_uri(duk_hthread *thr) {
+ return duk__transform_helper(thr, duk__transform_callback_decode_uri, (const void *) duk__decode_uri_reserved_table);
}
-DUK_INTERNAL duk_ret_t duk_bi_global_object_decode_uri_component(duk_context *ctx) {
- return duk__transform_helper(ctx, duk__transform_callback_decode_uri, (const void *) duk__decode_uri_component_reserved_table);
+DUK_INTERNAL duk_ret_t duk_bi_global_object_decode_uri_component(duk_hthread *thr) {
+ return duk__transform_helper(thr, duk__transform_callback_decode_uri, (const void *) duk__decode_uri_component_reserved_table);
}
-DUK_INTERNAL duk_ret_t duk_bi_global_object_encode_uri(duk_context *ctx) {
- return duk__transform_helper(ctx, duk__transform_callback_encode_uri, (const void *) duk__encode_uriunescaped_table);
+DUK_INTERNAL duk_ret_t duk_bi_global_object_encode_uri(duk_hthread *thr) {
+ return duk__transform_helper(thr, duk__transform_callback_encode_uri, (const void *) duk__encode_uriunescaped_table);
}
-DUK_INTERNAL duk_ret_t duk_bi_global_object_encode_uri_component(duk_context *ctx) {
- return duk__transform_helper(ctx, duk__transform_callback_encode_uri, (const void *) duk__encode_uricomponent_unescaped_table);
+DUK_INTERNAL duk_ret_t duk_bi_global_object_encode_uri_component(duk_hthread *thr) {
+ return duk__transform_helper(thr, duk__transform_callback_encode_uri, (const void *) duk__encode_uricomponent_unescaped_table);
}
#if defined(DUK_USE_SECTION_B)
-DUK_INTERNAL duk_ret_t duk_bi_global_object_escape(duk_context *ctx) {
- return duk__transform_helper(ctx, duk__transform_callback_escape, (const void *) NULL);
+DUK_INTERNAL duk_ret_t duk_bi_global_object_escape(duk_hthread *thr) {
+ return duk__transform_helper(thr, duk__transform_callback_escape, (const void *) NULL);
}
-DUK_INTERNAL duk_ret_t duk_bi_global_object_unescape(duk_context *ctx) {
- return duk__transform_helper(ctx, duk__transform_callback_unescape, (const void *) NULL);
+DUK_INTERNAL duk_ret_t duk_bi_global_object_unescape(duk_hthread *thr) {
+ return duk__transform_helper(thr, duk__transform_callback_unescape, (const void *) NULL);
}
#endif /* DUK_USE_SECTION_B */
#endif /* DUK_USE_GLOBAL_BUILTIN */
@@ -32190,7 +33390,7 @@ DUK_LOCAL_DECL void duk__enc_bufobj(duk_json_enc_ctx *js_ctx, duk_hbufobj *h_buf
#if defined(DUK_USE_JSON_STRINGIFY_FASTPATH)
DUK_LOCAL_DECL void duk__enc_buffer_json_fastpath(duk_json_enc_ctx *js_ctx, duk_hbuffer *h);
#endif
-DUK_LOCAL_DECL void duk__enc_newline_indent(duk_json_enc_ctx *js_ctx, duk_int_t depth);
+DUK_LOCAL_DECL void duk__enc_newline_indent(duk_json_enc_ctx *js_ctx, duk_uint_t depth);
/*
* Helper tables
@@ -32389,7 +33589,7 @@ DUK_LOCAL duk_uint_fast32_t duk__dec_decode_hex_escape(duk_json_dec_ctx *js_ctx,
DUK_ASSERT(duk_hex_dectab[0] == -1);
t = duk_hex_dectab[x & 0xff];
if (DUK_LIKELY(t >= 0)) {
- res = (res * 16) + t;
+ res = (res * 16) + (duk_uint_fast32_t) t;
} else {
/* catches EOF and invalid digits */
goto syntax_error;
@@ -32493,7 +33693,6 @@ DUK_LOCAL duk_small_int_t duk__dec_string_escape(duk_json_dec_ctx *js_ctx, duk_u
DUK_LOCAL void duk__dec_string(duk_json_dec_ctx *js_ctx) {
duk_hthread *thr = js_ctx->thr;
- duk_context *ctx = (duk_context *) thr;
duk_bufwriter_ctx bw_alloc;
duk_bufwriter_ctx *bw;
duk_uint8_t *q;
@@ -32586,7 +33785,7 @@ DUK_LOCAL void duk__dec_string(duk_json_dec_ctx *js_ctx) {
#endif /* DUK_USE_JSON_DECSTRING_FASTPATH */
DUK_BW_SETPTR_AND_COMPACT(js_ctx->thr, bw, q);
- (void) duk_buffer_to_string(ctx, -1); /* Safe if input string is safe. */
+ (void) duk_buffer_to_string(thr, -1); /* Safe if input string is safe. */
/* [ ... str ] */
@@ -32603,7 +33802,6 @@ DUK_LOCAL void duk__dec_string(duk_json_dec_ctx *js_ctx) {
*/
DUK_LOCAL void duk__dec_plain_string(duk_json_dec_ctx *js_ctx) {
duk_hthread *thr = js_ctx->thr;
- duk_context *ctx = (duk_context *) thr;
const duk_uint8_t *p;
duk_small_int_t x;
@@ -32636,7 +33834,7 @@ DUK_LOCAL void duk__dec_plain_string(duk_json_dec_ctx *js_ctx) {
p++;
}
- duk_push_lstring(ctx, (const char *) js_ctx->p, (duk_size_t) (p - js_ctx->p));
+ duk_push_lstring(thr, (const char *) js_ctx->p, (duk_size_t) (p - js_ctx->p));
js_ctx->p = p;
/* [ ... str ] */
@@ -32646,7 +33844,6 @@ DUK_LOCAL void duk__dec_plain_string(duk_json_dec_ctx *js_ctx) {
#if defined(DUK_USE_JX)
DUK_LOCAL void duk__dec_pointer(duk_json_dec_ctx *js_ctx) {
duk_hthread *thr = js_ctx->thr;
- duk_context *ctx = (duk_context *) thr;
const duk_uint8_t *p;
duk_small_int_t x;
void *voidptr;
@@ -32684,7 +33881,7 @@ DUK_LOCAL void duk__dec_pointer(duk_json_dec_ctx *js_ctx) {
voidptr = NULL;
(void) DUK_SSCANF((const char *) js_ctx->p, DUK_STR_FMT_PTR, &voidptr);
- duk_push_pointer(ctx, voidptr);
+ duk_push_pointer(thr, voidptr);
js_ctx->p = p + 1; /* skip ')' */
/* [ ... ptr ] */
@@ -32700,7 +33897,6 @@ DUK_LOCAL void duk__dec_pointer(duk_json_dec_ctx *js_ctx) {
#if defined(DUK_USE_JX)
DUK_LOCAL void duk__dec_buffer(duk_json_dec_ctx *js_ctx) {
duk_hthread *thr = js_ctx->thr;
- duk_context *ctx = (duk_context *) thr;
const duk_uint8_t *p;
duk_uint8_t *buf;
duk_size_t src_len;
@@ -32739,10 +33935,10 @@ DUK_LOCAL void duk__dec_buffer(duk_json_dec_ctx *js_ctx) {
/* XXX: this is not very nice; unnecessary copy is made. */
src_len = (duk_size_t) (p - js_ctx->p);
- buf = (duk_uint8_t *) duk_push_fixed_buffer_nozero(ctx, src_len);
+ buf = (duk_uint8_t *) duk_push_fixed_buffer_nozero(thr, src_len);
DUK_ASSERT(buf != NULL);
DUK_MEMCPY((void *) buf, (const void *) js_ctx->p, src_len);
- duk_hex_decode(ctx, -1);
+ duk_hex_decode(thr, -1);
js_ctx->p = p + 1; /* skip '|' */
@@ -32758,7 +33954,7 @@ DUK_LOCAL void duk__dec_buffer(duk_json_dec_ctx *js_ctx) {
/* Parse a number, other than NaN or +/- Infinity */
DUK_LOCAL void duk__dec_number(duk_json_dec_ctx *js_ctx) {
- duk_context *ctx = (duk_context *) js_ctx->thr;
+ duk_hthread *thr = js_ctx->thr;
const duk_uint8_t *p_start;
const duk_uint8_t *p;
duk_uint8_t x;
@@ -32803,35 +33999,35 @@ DUK_LOCAL void duk__dec_number(duk_json_dec_ctx *js_ctx) {
js_ctx->p = p;
DUK_ASSERT(js_ctx->p > p_start);
- duk_push_lstring(ctx, (const char *) p_start, (duk_size_t) (p - p_start));
+ duk_push_lstring(thr, (const char *) p_start, (duk_size_t) (p - p_start));
s2n_flags = DUK_S2N_FLAG_ALLOW_EXP |
DUK_S2N_FLAG_ALLOW_MINUS | /* but don't allow leading plus */
DUK_S2N_FLAG_ALLOW_FRAC;
DUK_DDD(DUK_DDDPRINT("parse_number: string before parsing: %!T",
- (duk_tval *) duk_get_tval(ctx, -1)));
- duk_numconv_parse(ctx, 10 /*radix*/, s2n_flags);
- if (duk_is_nan(ctx, -1)) {
+ (duk_tval *) duk_get_tval(thr, -1)));
+ duk_numconv_parse(thr, 10 /*radix*/, s2n_flags);
+ if (duk_is_nan(thr, -1)) {
duk__dec_syntax_error(js_ctx);
}
- DUK_ASSERT(duk_is_number(ctx, -1));
+ DUK_ASSERT(duk_is_number(thr, -1));
DUK_DDD(DUK_DDDPRINT("parse_number: final number: %!T",
- (duk_tval *) duk_get_tval(ctx, -1)));
+ (duk_tval *) duk_get_tval(thr, -1)));
/* [ ... num ] */
}
DUK_LOCAL void duk__dec_objarr_entry(duk_json_dec_ctx *js_ctx) {
- duk_context *ctx = (duk_context *) js_ctx->thr;
- duk_require_stack(ctx, DUK_JSON_DEC_REQSTACK);
+ duk_hthread *thr = js_ctx->thr;
+ duk_require_stack(thr, DUK_JSON_DEC_REQSTACK);
/* c recursion check */
- DUK_ASSERT(js_ctx->recursion_depth >= 0);
+ DUK_ASSERT_DISABLE(js_ctx->recursion_depth >= 0); /* unsigned */
DUK_ASSERT(js_ctx->recursion_depth <= js_ctx->recursion_limit);
if (js_ctx->recursion_depth >= js_ctx->recursion_limit) {
- DUK_ERROR_RANGE((duk_hthread *) ctx, DUK_STR_JSONDEC_RECLIMIT);
+ DUK_ERROR_RANGE(thr, DUK_STR_JSONDEC_RECLIMIT);
}
js_ctx->recursion_depth++;
}
@@ -32845,7 +34041,7 @@ DUK_LOCAL void duk__dec_objarr_exit(duk_json_dec_ctx *js_ctx) {
}
DUK_LOCAL void duk__dec_object(duk_json_dec_ctx *js_ctx) {
- duk_context *ctx = (duk_context *) js_ctx->thr;
+ duk_hthread *thr = js_ctx->thr;
duk_int_t key_count; /* XXX: a "first" flag would suffice */
duk_uint8_t x;
@@ -32853,7 +34049,7 @@ DUK_LOCAL void duk__dec_object(duk_json_dec_ctx *js_ctx) {
duk__dec_objarr_entry(js_ctx);
- duk_push_object(ctx);
+ duk_push_object(thr);
/* Initial '{' has been checked and eaten by caller. */
@@ -32862,7 +34058,7 @@ DUK_LOCAL void duk__dec_object(duk_json_dec_ctx *js_ctx) {
x = duk__dec_get_nonwhite(js_ctx);
DUK_DDD(DUK_DDDPRINT("parse_object: obj=%!T, x=%ld, key_count=%ld",
- (duk_tval *) duk_get_tval(ctx, -1),
+ (duk_tval *) duk_get_tval(thr, -1),
(long) x, (long) key_count));
/* handle comma and closing brace */
@@ -32907,7 +34103,7 @@ DUK_LOCAL void duk__dec_object(duk_json_dec_ctx *js_ctx) {
/* [ ... obj key val ] */
- duk_xdef_prop_wec(ctx, -3);
+ duk_xdef_prop_wec(thr, -3);
/* [ ... obj ] */
@@ -32917,7 +34113,7 @@ DUK_LOCAL void duk__dec_object(duk_json_dec_ctx *js_ctx) {
/* [ ... obj ] */
DUK_DDD(DUK_DDDPRINT("parse_object: final object is %!T",
- (duk_tval *) duk_get_tval(ctx, -1)));
+ (duk_tval *) duk_get_tval(thr, -1)));
duk__dec_objarr_exit(js_ctx);
return;
@@ -32928,7 +34124,7 @@ DUK_LOCAL void duk__dec_object(duk_json_dec_ctx *js_ctx) {
}
DUK_LOCAL void duk__dec_array(duk_json_dec_ctx *js_ctx) {
- duk_context *ctx = (duk_context *) js_ctx->thr;
+ duk_hthread *thr = js_ctx->thr;
duk_uarridx_t arr_idx;
duk_uint8_t x;
@@ -32936,7 +34132,7 @@ DUK_LOCAL void duk__dec_array(duk_json_dec_ctx *js_ctx) {
duk__dec_objarr_entry(js_ctx);
- duk_push_array(ctx);
+ duk_push_array(thr);
/* Initial '[' has been checked and eaten by caller. */
@@ -32945,7 +34141,7 @@ DUK_LOCAL void duk__dec_array(duk_json_dec_ctx *js_ctx) {
x = duk__dec_get_nonwhite(js_ctx);
DUK_DDD(DUK_DDDPRINT("parse_array: arr=%!T, x=%ld, arr_idx=%ld",
- (duk_tval *) duk_get_tval(ctx, -1),
+ (duk_tval *) duk_get_tval(thr, -1),
(long) x, (long) arr_idx));
/* handle comma and closing bracket */
@@ -32972,7 +34168,7 @@ DUK_LOCAL void duk__dec_array(duk_json_dec_ctx *js_ctx) {
/* [ ... arr val ] */
- duk_xdef_prop_index_wec(ctx, -2, arr_idx);
+ duk_xdef_prop_index_wec(thr, -2, arr_idx);
arr_idx++;
}
@@ -32980,12 +34176,12 @@ DUK_LOCAL void duk__dec_array(duk_json_dec_ctx *js_ctx) {
* set the values.
*/
- duk_set_length(ctx, -1, arr_idx);
+ duk_set_length(thr, -1, arr_idx);
/* [ ... arr ] */
DUK_DDD(DUK_DDDPRINT("parse_array: final array is %!T",
- (duk_tval *) duk_get_tval(ctx, -1)));
+ (duk_tval *) duk_get_tval(thr, -1)));
duk__dec_objarr_exit(js_ctx);
return;
@@ -32996,7 +34192,7 @@ DUK_LOCAL void duk__dec_array(duk_json_dec_ctx *js_ctx) {
}
DUK_LOCAL void duk__dec_value(duk_json_dec_ctx *js_ctx) {
- duk_context *ctx = (duk_context *) js_ctx->thr;
+ duk_hthread *thr = js_ctx->thr;
duk_uint8_t x;
x = duk__dec_get_nonwhite(js_ctx);
@@ -33011,7 +34207,7 @@ DUK_LOCAL void duk__dec_value(duk_json_dec_ctx *js_ctx) {
#if defined(DUK_USE_JX)
if (js_ctx->flag_ext_custom && x == DUK_ASC_MINUS && duk__dec_peek(js_ctx) == DUK_ASC_UC_I) {
duk__dec_req_stridx(js_ctx, DUK_STRIDX_MINUS_INFINITY); /* "-Infinity", '-' has been eaten */
- duk_push_number(ctx, -DUK_DOUBLE_INFINITY);
+ duk_push_number(thr, -DUK_DOUBLE_INFINITY);
} else {
#else
{ /* unconditional block */
@@ -33022,23 +34218,23 @@ DUK_LOCAL void duk__dec_value(duk_json_dec_ctx *js_ctx) {
}
} else if (x == DUK_ASC_LC_T) {
duk__dec_req_stridx(js_ctx, DUK_STRIDX_TRUE);
- duk_push_true(ctx);
+ duk_push_true(thr);
} else if (x == DUK_ASC_LC_F) {
duk__dec_req_stridx(js_ctx, DUK_STRIDX_FALSE);
- duk_push_false(ctx);
+ duk_push_false(thr);
} else if (x == DUK_ASC_LC_N) {
duk__dec_req_stridx(js_ctx, DUK_STRIDX_LC_NULL);
- duk_push_null(ctx);
+ duk_push_null(thr);
#if defined(DUK_USE_JX)
} else if (js_ctx->flag_ext_custom && x == DUK_ASC_LC_U) {
duk__dec_req_stridx(js_ctx, DUK_STRIDX_LC_UNDEFINED);
- duk_push_undefined(ctx);
+ duk_push_undefined(thr);
} else if (js_ctx->flag_ext_custom && x == DUK_ASC_UC_N) {
duk__dec_req_stridx(js_ctx, DUK_STRIDX_NAN);
- duk_push_nan(ctx);
+ duk_push_nan(thr);
} else if (js_ctx->flag_ext_custom && x == DUK_ASC_UC_I) {
duk__dec_req_stridx(js_ctx, DUK_STRIDX_INFINITY);
- duk_push_number(ctx, DUK_DOUBLE_INFINITY);
+ duk_push_number(thr, DUK_DOUBLE_INFINITY);
} else if (js_ctx->flag_ext_custom && x == DUK_ASC_LPAREN) {
duk__dec_pointer(js_ctx);
} else if (js_ctx->flag_ext_custom && x == DUK_ASC_PIPE) {
@@ -33068,65 +34264,65 @@ DUK_LOCAL void duk__dec_value(duk_json_dec_ctx *js_ctx) {
* there is a reasonable limit on C recursion depth and hence object depth.
*/
DUK_LOCAL void duk__dec_reviver_walk(duk_json_dec_ctx *js_ctx) {
- duk_context *ctx = (duk_context *) js_ctx->thr;
+ duk_hthread *thr = js_ctx->thr;
duk_hobject *h;
duk_uarridx_t i, arr_len;
DUK_DDD(DUK_DDDPRINT("walk: top=%ld, holder=%!T, name=%!T",
- (long) duk_get_top(ctx),
- (duk_tval *) duk_get_tval(ctx, -2),
- (duk_tval *) duk_get_tval(ctx, -1)));
+ (long) duk_get_top(thr),
+ (duk_tval *) duk_get_tval(thr, -2),
+ (duk_tval *) duk_get_tval(thr, -1)));
- duk_dup_top(ctx);
- duk_get_prop(ctx, -3); /* -> [ ... holder name val ] */
+ duk_dup_top(thr);
+ duk_get_prop(thr, -3); /* -> [ ... holder name val ] */
- h = duk_get_hobject(ctx, -1);
+ h = duk_get_hobject(thr, -1);
if (h != NULL) {
if (DUK_HOBJECT_GET_CLASS_NUMBER(h) == DUK_HOBJECT_CLASS_ARRAY) {
- arr_len = (duk_uarridx_t) duk_get_length(ctx, -1);
+ arr_len = (duk_uarridx_t) duk_get_length(thr, -1);
for (i = 0; i < arr_len; i++) {
/* [ ... holder name val ] */
DUK_DDD(DUK_DDDPRINT("walk: array, top=%ld, i=%ld, arr_len=%ld, holder=%!T, name=%!T, val=%!T",
- (long) duk_get_top(ctx), (long) i, (long) arr_len,
- (duk_tval *) duk_get_tval(ctx, -3), (duk_tval *) duk_get_tval(ctx, -2),
- (duk_tval *) duk_get_tval(ctx, -1)));
+ (long) duk_get_top(thr), (long) i, (long) arr_len,
+ (duk_tval *) duk_get_tval(thr, -3), (duk_tval *) duk_get_tval(thr, -2),
+ (duk_tval *) duk_get_tval(thr, -1)));
- duk_dup_top(ctx);
- (void) duk_push_uint_to_hstring(ctx, (duk_uint_t) i); /* -> [ ... holder name val val ToString(i) ] */
+ duk_dup_top(thr);
+ (void) duk_push_uint_to_hstring(thr, (duk_uint_t) i); /* -> [ ... holder name val val ToString(i) ] */
duk__dec_reviver_walk(js_ctx); /* -> [ ... holder name val new_elem ] */
- if (duk_is_undefined(ctx, -1)) {
- duk_pop(ctx);
- duk_del_prop_index(ctx, -1, i);
+ if (duk_is_undefined(thr, -1)) {
+ duk_pop(thr);
+ duk_del_prop_index(thr, -1, i);
} else {
/* XXX: duk_xdef_prop_index_wec() would be more appropriate
* here but it currently makes some assumptions that might
* not hold (e.g. that previous property is not an accessor).
*/
- duk_put_prop_index(ctx, -2, i);
+ duk_put_prop_index(thr, -2, i);
}
}
} else {
/* [ ... holder name val ] */
- duk_enum(ctx, -1, DUK_ENUM_OWN_PROPERTIES_ONLY /*flags*/);
- while (duk_next(ctx, -1 /*enum_index*/, 0 /*get_value*/)) {
+ duk_enum(thr, -1, DUK_ENUM_OWN_PROPERTIES_ONLY /*flags*/);
+ while (duk_next(thr, -1 /*enum_index*/, 0 /*get_value*/)) {
DUK_DDD(DUK_DDDPRINT("walk: object, top=%ld, holder=%!T, name=%!T, val=%!T, enum=%!iT, obj_key=%!T",
- (long) duk_get_top(ctx), (duk_tval *) duk_get_tval(ctx, -5),
- (duk_tval *) duk_get_tval(ctx, -4), (duk_tval *) duk_get_tval(ctx, -3),
- (duk_tval *) duk_get_tval(ctx, -2), (duk_tval *) duk_get_tval(ctx, -1)));
+ (long) duk_get_top(thr), (duk_tval *) duk_get_tval(thr, -5),
+ (duk_tval *) duk_get_tval(thr, -4), (duk_tval *) duk_get_tval(thr, -3),
+ (duk_tval *) duk_get_tval(thr, -2), (duk_tval *) duk_get_tval(thr, -1)));
/* [ ... holder name val enum obj_key ] */
- duk_dup_m3(ctx);
- duk_dup_m2(ctx);
+ duk_dup_m3(thr);
+ duk_dup_m2(thr);
/* [ ... holder name val enum obj_key val obj_key ] */
duk__dec_reviver_walk(js_ctx);
/* [ ... holder name val enum obj_key new_elem ] */
- if (duk_is_undefined(ctx, -1)) {
- duk_pop(ctx);
- duk_del_prop(ctx, -3);
+ if (duk_is_undefined(thr, -1)) {
+ duk_pop(thr);
+ duk_del_prop(thr, -3);
} else {
/* XXX: duk_xdef_prop_index_wec() would be more appropriate
* here but it currently makes some assumptions that might
@@ -33137,21 +34333,21 @@ DUK_LOCAL void duk__dec_reviver_walk(duk_json_dec_ctx *js_ctx) {
* does not happen normally, but a clever reviver can trigger
* that, see complex reviver case in: test-bug-json-parse-__proto__.js.
*/
- duk_put_prop(ctx, -4);
+ duk_put_prop(thr, -4);
}
}
- duk_pop(ctx); /* pop enum */
+ duk_pop(thr); /* pop enum */
}
}
/* [ ... holder name val ] */
- duk_dup(ctx, js_ctx->idx_reviver);
- duk_insert(ctx, -4); /* -> [ ... reviver holder name val ] */
- duk_call_method(ctx, 2); /* -> [ ... res ] */
+ duk_dup(thr, js_ctx->idx_reviver);
+ duk_insert(thr, -4); /* -> [ ... reviver holder name val ] */
+ duk_call_method(thr, 2); /* -> [ ... res ] */
DUK_DDD(DUK_DDDPRINT("walk: top=%ld, result=%!T",
- (long) duk_get_top(ctx), (duk_tval *) duk_get_tval(ctx, -1)));
+ (long) duk_get_top(thr), (duk_tval *) duk_get_tval(thr, -1)));
}
/*
@@ -33221,7 +34417,7 @@ DUK_LOCAL duk_uint8_t *duk__emit_esc_auto_fast(duk_json_enc_ctx *js_ctx, duk_uin
#if defined(DUK_USE_JX)
if (DUK_LIKELY(cp < 0x100UL)) {
- if (DUK_UNLIKELY(js_ctx->flag_ext_custom)) {
+ if (DUK_UNLIKELY(js_ctx->flag_ext_custom != 0U)) {
tmp = DUK__MKESC(2, DUK_ASC_BACKSLASH, DUK_ASC_LC_X);
} else {
tmp = DUK__MKESC(4, DUK_ASC_BACKSLASH, DUK_ASC_LC_U);
@@ -33232,7 +34428,7 @@ DUK_LOCAL duk_uint8_t *duk__emit_esc_auto_fast(duk_json_enc_ctx *js_ctx, duk_uin
tmp = DUK__MKESC(4, DUK_ASC_BACKSLASH, DUK_ASC_LC_U);
} else {
#if defined(DUK_USE_JX)
- if (DUK_LIKELY(js_ctx->flag_ext_custom)) {
+ if (DUK_LIKELY(js_ctx->flag_ext_custom != 0U)) {
tmp = DUK__MKESC(8, DUK_ASC_BACKSLASH, DUK_ASC_UC_U);
} else
#endif
@@ -33449,7 +34645,6 @@ DUK_LOCAL void duk__enc_quote_string(duk_json_enc_ctx *js_ctx, duk_hstring *h_st
*/
DUK_LOCAL void duk__enc_double(duk_json_enc_ctx *js_ctx) {
duk_hthread *thr;
- duk_context *ctx;
duk_tval *tv;
duk_double_t d;
duk_small_int_t c;
@@ -33461,10 +34656,9 @@ DUK_LOCAL void duk__enc_double(duk_json_enc_ctx *js_ctx) {
DUK_ASSERT(js_ctx != NULL);
thr = js_ctx->thr;
DUK_ASSERT(thr != NULL);
- ctx = (duk_context *) thr;
/* Caller must ensure 'tv' is indeed a double and not a fastint! */
- tv = DUK_GET_TVAL_NEGIDX(ctx, -1);
+ tv = DUK_GET_TVAL_NEGIDX(thr, -1);
DUK_ASSERT(DUK_TVAL_IS_DOUBLE(tv));
d = DUK_TVAL_GET_DOUBLE(tv);
@@ -33481,15 +34675,15 @@ DUK_LOCAL void duk__enc_double(duk_json_enc_ctx *js_ctx) {
*/
if (DUK_UNLIKELY(c == DUK_FP_ZERO && s != 0 &&
(js_ctx->flag_ext_custom_or_compatible))) {
- duk_push_hstring_stridx(ctx, DUK_STRIDX_MINUS_ZERO); /* '-0' */
+ duk_push_hstring_stridx(thr, DUK_STRIDX_MINUS_ZERO); /* '-0' */
} else
#endif /* DUK_USE_JX || DUK_USE_JC */
{
n2s_flags = 0;
/* [ ... number ] -> [ ... string ] */
- duk_numconv_stringify(ctx, 10 /*radix*/, 0 /*digits*/, n2s_flags);
+ duk_numconv_stringify(thr, 10 /*radix*/, 0 /*digits*/, n2s_flags);
}
- h_str = duk_known_hstring(ctx, -1);
+ h_str = duk_known_hstring(thr, -1);
DUK__EMIT_HSTR(js_ctx, h_str);
return;
}
@@ -33691,7 +34885,7 @@ DUK_LOCAL void duk__enc_buffer_json_fastpath(duk_json_enc_ctx *js_ctx, duk_hbuff
DUK__EMIT_1(js_ctx, DUK_ASC_LCURLY);
/* Maximum encoded length with 32-bit index: 1 + 10 + 2 + 3 + 1 + 1 = 18,
- * with 64-bit index: 1 + 20 + 2 + 3 + 1 + 1 = 28. 32 has some spare.
+ * with 64-bit index: 1 + 20 + 2 + 3 + 1 + 1 = 28. 32 has some slack.
*
* Note that because the output buffer is reallocated from time to time,
* side effects (such as finalizers) affecting the buffer 'h' must be
@@ -33781,7 +34975,7 @@ DUK_LOCAL void duk__enc_bufobj(duk_json_enc_ctx *js_ctx, duk_hbufobj *h_bufobj)
* directly related to indent depth.
*/
#if defined(DUK_USE_PREFER_SIZE)
-DUK_LOCAL void duk__enc_newline_indent(duk_json_enc_ctx *js_ctx, duk_int_t depth) {
+DUK_LOCAL void duk__enc_newline_indent(duk_json_enc_ctx *js_ctx, duk_uint_t depth) {
DUK_ASSERT(js_ctx->h_gap != NULL);
DUK_ASSERT(DUK_HSTRING_GET_BYTELEN(js_ctx->h_gap) > 0); /* caller guarantees */
@@ -33791,7 +34985,7 @@ DUK_LOCAL void duk__enc_newline_indent(duk_json_enc_ctx *js_ctx, duk_int_t depth
}
}
#else /* DUK_USE_PREFER_SIZE */
-DUK_LOCAL void duk__enc_newline_indent(duk_json_enc_ctx *js_ctx, duk_int_t depth) {
+DUK_LOCAL void duk__enc_newline_indent(duk_json_enc_ctx *js_ctx, duk_uint_t depth) {
const duk_uint8_t *gap_data;
duk_size_t gap_len;
duk_size_t avail_bytes; /* bytes of indent available for copying */
@@ -33845,19 +35039,19 @@ DUK_LOCAL void duk__enc_newline_indent(duk_json_enc_ctx *js_ctx, duk_int_t depth
/* Shared entry handling for object/array serialization. */
DUK_LOCAL void duk__enc_objarr_entry(duk_json_enc_ctx *js_ctx, duk_idx_t *entry_top) {
- duk_context *ctx = (duk_context *) js_ctx->thr;
+ duk_hthread *thr = js_ctx->thr;
duk_hobject *h_target;
duk_uint_fast32_t i, n;
- *entry_top = duk_get_top(ctx);
+ *entry_top = duk_get_top(thr);
- duk_require_stack(ctx, DUK_JSON_ENC_REQSTACK);
+ duk_require_stack(thr, DUK_JSON_ENC_REQSTACK);
/* Loop check using a hybrid approach: a fixed-size visited[] array
* with overflow in a loop check object.
*/
- h_target = duk_known_hobject(ctx, -1); /* object or array */
+ h_target = duk_known_hobject(thr, -1); /* object or array */
n = js_ctx->recursion_depth;
if (DUK_UNLIKELY(n > DUK_JSON_ENC_LOOPARRAY)) {
@@ -33866,37 +35060,37 @@ DUK_LOCAL void duk__enc_objarr_entry(duk_json_enc_ctx *js_ctx, duk_idx_t *entry_
for (i = 0; i < n; i++) {
if (DUK_UNLIKELY(js_ctx->visiting[i] == h_target)) {
DUK_DD(DUK_DDPRINT("slow path loop detect"));
- DUK_ERROR_TYPE((duk_hthread *) ctx, DUK_STR_CYCLIC_INPUT);
+ DUK_ERROR_TYPE(thr, DUK_STR_CYCLIC_INPUT);
}
}
if (js_ctx->recursion_depth < DUK_JSON_ENC_LOOPARRAY) {
js_ctx->visiting[js_ctx->recursion_depth] = h_target;
} else {
- duk_push_sprintf(ctx, DUK_STR_FMT_PTR, (void *) h_target);
- duk_dup_top(ctx); /* -> [ ... voidp voidp ] */
- if (duk_has_prop(ctx, js_ctx->idx_loop)) {
- DUK_ERROR_TYPE((duk_hthread *) ctx, DUK_STR_CYCLIC_INPUT);
+ duk_push_sprintf(thr, DUK_STR_FMT_PTR, (void *) h_target);
+ duk_dup_top(thr); /* -> [ ... voidp voidp ] */
+ if (duk_has_prop(thr, js_ctx->idx_loop)) {
+ DUK_ERROR_TYPE(thr, DUK_STR_CYCLIC_INPUT);
}
- duk_push_true(ctx); /* -> [ ... voidp true ] */
- duk_put_prop(ctx, js_ctx->idx_loop); /* -> [ ... ] */
+ duk_push_true(thr); /* -> [ ... voidp true ] */
+ duk_put_prop(thr, js_ctx->idx_loop); /* -> [ ... ] */
}
/* C recursion check. */
- DUK_ASSERT(js_ctx->recursion_depth >= 0);
+ DUK_ASSERT_DISABLE(js_ctx->recursion_depth >= 0); /* unsigned */
DUK_ASSERT(js_ctx->recursion_depth <= js_ctx->recursion_limit);
if (js_ctx->recursion_depth >= js_ctx->recursion_limit) {
- DUK_ERROR_RANGE((duk_hthread *) ctx, DUK_STR_JSONENC_RECLIMIT);
+ DUK_ERROR_RANGE(thr, DUK_STR_JSONENC_RECLIMIT);
}
js_ctx->recursion_depth++;
DUK_DDD(DUK_DDDPRINT("shared entry finished: top=%ld, loop=%!T",
- (long) duk_get_top(ctx), (duk_tval *) duk_get_tval(ctx, js_ctx->idx_loop)));
+ (long) duk_get_top(thr), (duk_tval *) duk_get_tval(thr, js_ctx->idx_loop)));
}
/* Shared exit handling for object/array serialization. */
DUK_LOCAL void duk__enc_objarr_exit(duk_json_enc_ctx *js_ctx, duk_idx_t *entry_top) {
- duk_context *ctx = (duk_context *) js_ctx->thr;
+ duk_hthread *thr = js_ctx->thr;
duk_hobject *h_target;
/* C recursion check. */
@@ -33907,20 +35101,20 @@ DUK_LOCAL void duk__enc_objarr_exit(duk_json_enc_ctx *js_ctx, duk_idx_t *entry_t
/* Loop check. */
- h_target = duk_known_hobject(ctx, *entry_top - 1); /* original target at entry_top - 1 */
+ h_target = duk_known_hobject(thr, *entry_top - 1); /* original target at entry_top - 1 */
if (js_ctx->recursion_depth < DUK_JSON_ENC_LOOPARRAY) {
/* Previous entry was inside visited[], nothing to do. */
} else {
- duk_push_sprintf(ctx, DUK_STR_FMT_PTR, (void *) h_target);
- duk_del_prop(ctx, js_ctx->idx_loop); /* -> [ ... ] */
+ duk_push_sprintf(thr, DUK_STR_FMT_PTR, (void *) h_target);
+ duk_del_prop(thr, js_ctx->idx_loop); /* -> [ ... ] */
}
/* Restore stack top after unbalanced code paths. */
- duk_set_top(ctx, *entry_top);
+ duk_set_top(thr, *entry_top);
DUK_DDD(DUK_DDDPRINT("shared entry finished: top=%ld, loop=%!T",
- (long) duk_get_top(ctx), (duk_tval *) duk_get_tval(ctx, js_ctx->idx_loop)));
+ (long) duk_get_top(thr), (duk_tval *) duk_get_tval(thr, js_ctx->idx_loop)));
}
/* The JO(value) operation: encode object.
@@ -33928,7 +35122,7 @@ DUK_LOCAL void duk__enc_objarr_exit(duk_json_enc_ctx *js_ctx, duk_idx_t *entry_t
* Stack policy: [ object ] -> [ object ].
*/
DUK_LOCAL void duk__enc_object(duk_json_enc_ctx *js_ctx) {
- duk_context *ctx = (duk_context *) js_ctx->thr;
+ duk_hthread *thr = js_ctx->thr;
duk_hstring *h_key;
duk_idx_t entry_top;
duk_idx_t idx_obj;
@@ -33937,7 +35131,7 @@ DUK_LOCAL void duk__enc_object(duk_json_enc_ctx *js_ctx) {
duk_uarridx_t arr_len, i;
duk_size_t prev_size;
- DUK_DDD(DUK_DDDPRINT("duk__enc_object: obj=%!T", (duk_tval *) duk_get_tval(ctx, -1)));
+ DUK_DDD(DUK_DDDPRINT("duk__enc_object: obj=%!T", (duk_tval *) duk_get_tval(thr, -1)));
duk__enc_objarr_entry(js_ctx, &entry_top);
@@ -33947,14 +35141,14 @@ DUK_LOCAL void duk__enc_object(duk_json_enc_ctx *js_ctx) {
idx_keys = js_ctx->idx_proplist;
} else {
/* XXX: would be nice to enumerate an object at specified index */
- duk_dup(ctx, idx_obj);
- (void) duk_hobject_get_enumerated_keys(ctx, DUK_ENUM_OWN_PROPERTIES_ONLY /*flags*/); /* [ ... target ] -> [ ... target keys ] */
- idx_keys = duk_require_normalize_index(ctx, -1);
+ duk_dup(thr, idx_obj);
+ (void) duk_hobject_get_enumerated_keys(thr, DUK_ENUM_OWN_PROPERTIES_ONLY /*flags*/); /* [ ... target ] -> [ ... target keys ] */
+ idx_keys = duk_require_normalize_index(thr, -1);
/* leave stack unbalanced on purpose */
}
DUK_DDD(DUK_DDDPRINT("idx_keys=%ld, h_keys=%!T",
- (long) idx_keys, (duk_tval *) duk_get_tval(ctx, idx_keys)));
+ (long) idx_keys, (duk_tval *) duk_get_tval(thr, idx_keys)));
/* Steps 8-10 have been merged to avoid a "partial" variable. */
@@ -33966,16 +35160,16 @@ DUK_LOCAL void duk__enc_object(duk_json_enc_ctx *js_ctx) {
* that it can be reallocated).
*/
- arr_len = (duk_uarridx_t) duk_get_length(ctx, idx_keys);
+ arr_len = (duk_uarridx_t) duk_get_length(thr, idx_keys);
emitted = 0;
for (i = 0; i < arr_len; i++) {
- duk_get_prop_index(ctx, idx_keys, i); /* -> [ ... key ] */
+ duk_get_prop_index(thr, idx_keys, i); /* -> [ ... key ] */
DUK_DDD(DUK_DDDPRINT("object property loop: holder=%!T, key=%!T",
- (duk_tval *) duk_get_tval(ctx, idx_obj),
- (duk_tval *) duk_get_tval(ctx, -1)));
+ (duk_tval *) duk_get_tval(thr, idx_obj),
+ (duk_tval *) duk_get_tval(thr, -1)));
- h_key = duk_known_hstring(ctx, -1);
+ h_key = duk_known_hstring(thr, -1);
DUK_ASSERT(h_key != NULL);
DUK_ASSERT(!DUK_HSTRING_HAS_SYMBOL(h_key)); /* proplist filtering; enum options */
@@ -34009,14 +35203,14 @@ DUK_LOCAL void duk__enc_object(duk_json_enc_ctx *js_ctx) {
DUK__UNEMIT_1(js_ctx); /* eat trailing comma */
if (DUK_UNLIKELY(js_ctx->h_gap != NULL)) {
DUK_ASSERT(js_ctx->recursion_depth >= 1);
- duk__enc_newline_indent(js_ctx, js_ctx->recursion_depth - 1);
+ duk__enc_newline_indent(js_ctx, js_ctx->recursion_depth - 1U);
}
}
DUK__EMIT_1(js_ctx, DUK_ASC_RCURLY);
duk__enc_objarr_exit(js_ctx, &entry_top);
- DUK_ASSERT_TOP(ctx, entry_top);
+ DUK_ASSERT_TOP(thr, entry_top);
}
/* The JA(value) operation: encode array.
@@ -34024,14 +35218,14 @@ DUK_LOCAL void duk__enc_object(duk_json_enc_ctx *js_ctx) {
* Stack policy: [ array ] -> [ array ].
*/
DUK_LOCAL void duk__enc_array(duk_json_enc_ctx *js_ctx) {
- duk_context *ctx = (duk_context *) js_ctx->thr;
+ duk_hthread *thr = js_ctx->thr;
duk_idx_t entry_top;
duk_idx_t idx_arr;
duk_bool_t emitted;
duk_uarridx_t i, arr_len;
DUK_DDD(DUK_DDDPRINT("duk__enc_array: array=%!T",
- (duk_tval *) duk_get_tval(ctx, -1)));
+ (duk_tval *) duk_get_tval(thr, -1)));
duk__enc_objarr_entry(js_ctx, &entry_top);
@@ -34041,11 +35235,11 @@ DUK_LOCAL void duk__enc_array(duk_json_enc_ctx *js_ctx) {
DUK__EMIT_1(js_ctx, DUK_ASC_LBRACKET);
- arr_len = (duk_uarridx_t) duk_get_length(ctx, idx_arr);
+ arr_len = (duk_uarridx_t) duk_get_length(thr, idx_arr);
emitted = 0;
for (i = 0; i < arr_len; i++) {
DUK_DDD(DUK_DDDPRINT("array entry loop: array=%!T, index=%ld, arr_len=%ld",
- (duk_tval *) duk_get_tval(ctx, idx_arr),
+ (duk_tval *) duk_get_tval(thr, idx_arr),
(long) i, (long) arr_len));
if (DUK_UNLIKELY(js_ctx->h_gap != NULL)) {
@@ -34053,7 +35247,7 @@ DUK_LOCAL void duk__enc_array(duk_json_enc_ctx *js_ctx) {
duk__enc_newline_indent(js_ctx, js_ctx->recursion_depth);
}
- (void) duk_push_uint_to_hstring(ctx, (duk_uint_t) i); /* -> [ ... key ] */
+ (void) duk_push_uint_to_hstring(thr, (duk_uint_t) i); /* -> [ ... key ] */
/* [ ... key ] */
@@ -34075,14 +35269,14 @@ DUK_LOCAL void duk__enc_array(duk_json_enc_ctx *js_ctx) {
DUK__UNEMIT_1(js_ctx); /* eat trailing comma */
if (DUK_UNLIKELY(js_ctx->h_gap != NULL)) {
DUK_ASSERT(js_ctx->recursion_depth >= 1);
- duk__enc_newline_indent(js_ctx, js_ctx->recursion_depth - 1);
+ duk__enc_newline_indent(js_ctx, js_ctx->recursion_depth - 1U);
}
}
DUK__EMIT_1(js_ctx, DUK_ASC_RBRACKET);
duk__enc_objarr_exit(js_ctx, &entry_top);
- DUK_ASSERT_TOP(ctx, entry_top);
+ DUK_ASSERT_TOP(thr, entry_top);
}
/* The Str(key, holder) operation.
@@ -34090,71 +35284,68 @@ DUK_LOCAL void duk__enc_array(duk_json_enc_ctx *js_ctx) {
* Stack policy: [ ... key ] -> [ ... ]
*/
DUK_LOCAL duk_bool_t duk__enc_value(duk_json_enc_ctx *js_ctx, duk_idx_t idx_holder) {
- duk_context *ctx = (duk_context *) js_ctx->thr;
- duk_hthread *thr = (duk_hthread *) ctx;
+ duk_hthread *thr = js_ctx->thr;
duk_tval *tv;
duk_tval *tv_holder;
duk_tval *tv_key;
duk_small_int_t c;
DUK_DDD(DUK_DDDPRINT("duk__enc_value: idx_holder=%ld, holder=%!T, key=%!T",
- (long) idx_holder, (duk_tval *) duk_get_tval(ctx, idx_holder),
- (duk_tval *) duk_get_tval(ctx, -1)));
+ (long) idx_holder, (duk_tval *) duk_get_tval(thr, idx_holder),
+ (duk_tval *) duk_get_tval(thr, -1)));
- DUK_UNREF(thr);
-
- tv_holder = DUK_GET_TVAL_POSIDX(ctx, idx_holder);
+ tv_holder = DUK_GET_TVAL_POSIDX(thr, idx_holder);
DUK_ASSERT(DUK_TVAL_IS_OBJECT(tv_holder));
- tv_key = DUK_GET_TVAL_NEGIDX(ctx, -1);
+ tv_key = DUK_GET_TVAL_NEGIDX(thr, -1);
DUK_ASSERT(DUK_TVAL_IS_STRING(tv_key));
DUK_ASSERT(!DUK_HSTRING_HAS_SYMBOL(DUK_TVAL_GET_STRING(tv_key))); /* Caller responsible. */
(void) duk_hobject_getprop(thr, tv_holder, tv_key);
/* -> [ ... key val ] */
- DUK_DDD(DUK_DDDPRINT("value=%!T", (duk_tval *) duk_get_tval(ctx, -1)));
+ DUK_DDD(DUK_DDDPRINT("value=%!T", (duk_tval *) duk_get_tval(thr, -1)));
/* Standard JSON checks for .toJSON() only for actual objects; for
* example, setting Number.prototype.toJSON and then serializing a
* number won't invoke the .toJSON() method. However, lightfuncs and
* plain buffers mimic objects so we check for their .toJSON() method.
*/
- if (duk_check_type_mask(ctx, -1, DUK_TYPE_MASK_OBJECT |
+ if (duk_check_type_mask(thr, -1, DUK_TYPE_MASK_OBJECT |
DUK_TYPE_MASK_LIGHTFUNC |
DUK_TYPE_MASK_BUFFER)) {
- duk_get_prop_stridx_short(ctx, -1, DUK_STRIDX_TO_JSON);
- if (duk_is_callable(ctx, -1)) { /* toJSON() can also be a lightfunc */
+ duk_get_prop_stridx_short(thr, -1, DUK_STRIDX_TO_JSON);
+ if (duk_is_callable(thr, -1)) { /* toJSON() can also be a lightfunc */
DUK_DDD(DUK_DDDPRINT("value is object, has callable toJSON() -> call it"));
- /* XXX: duk_dup_unvalidated(ctx, -2) etc. */
- duk_dup_m2(ctx); /* -> [ ... key val toJSON val ] */
- duk_dup_m4(ctx); /* -> [ ... key val toJSON val key ] */
- duk_call_method(ctx, 1); /* -> [ ... key val val' ] */
- duk_remove_m2(ctx); /* -> [ ... key val' ] */
+ /* XXX: duk_dup_unvalidated(thr, -2) etc. */
+ duk_dup_m2(thr); /* -> [ ... key val toJSON val ] */
+ duk_dup_m4(thr); /* -> [ ... key val toJSON val key ] */
+ duk_call_method(thr, 1); /* -> [ ... key val val' ] */
+ duk_remove_m2(thr); /* -> [ ... key val' ] */
} else {
- duk_pop(ctx); /* -> [ ... key val ] */
+ duk_pop(thr); /* -> [ ... key val ] */
}
}
/* [ ... key val ] */
- DUK_DDD(DUK_DDDPRINT("value=%!T", (duk_tval *) duk_get_tval(ctx, -1)));
+ DUK_DDD(DUK_DDDPRINT("value=%!T", (duk_tval *) duk_get_tval(thr, -1)));
if (js_ctx->h_replacer) {
/* XXX: Here a "slice copy" would be useful. */
DUK_DDD(DUK_DDDPRINT("replacer is set, call replacer"));
- duk_push_hobject(ctx, js_ctx->h_replacer); /* -> [ ... key val replacer ] */
- duk_dup(ctx, idx_holder); /* -> [ ... key val replacer holder ] */
- duk_dup_m4(ctx); /* -> [ ... key val replacer holder key ] */
- duk_dup_m4(ctx); /* -> [ ... key val replacer holder key val ] */
- duk_call_method(ctx, 2); /* -> [ ... key val val' ] */
- duk_remove_m2(ctx); /* -> [ ... key val' ] */
+ duk_push_hobject(thr, js_ctx->h_replacer); /* -> [ ... key val replacer ] */
+ duk_dup(thr, idx_holder); /* -> [ ... key val replacer holder ] */
+ duk_dup_m4(thr); /* -> [ ... key val replacer holder key ] */
+ duk_dup_m4(thr); /* -> [ ... key val replacer holder key val ] */
+ duk_call_method(thr, 2); /* -> [ ... key val val' ] */
+ duk_remove_m2(thr); /* -> [ ... key val' ] */
}
/* [ ... key val ] */
- DUK_DDD(DUK_DDDPRINT("value=%!T", (duk_tval *) duk_get_tval(ctx, -1)));
+ DUK_DDD(DUK_DDDPRINT("value=%!T", (duk_tval *) duk_get_tval(thr, -1)));
- tv = DUK_GET_TVAL_NEGIDX(ctx, -1);
+ tv = DUK_GET_TVAL_NEGIDX(thr, -1);
if (DUK_TVAL_IS_OBJECT(tv)) {
duk_hobject *h;
@@ -34179,19 +35370,19 @@ DUK_LOCAL duk_bool_t duk__enc_value(duk_json_enc_ctx *js_ctx, duk_idx_t idx_hold
switch (c) {
case DUK_HOBJECT_CLASS_NUMBER: {
DUK_DDD(DUK_DDDPRINT("value is a Number object -> coerce with ToNumber()"));
- duk_to_number_m1(ctx);
+ duk_to_number_m1(thr);
/* The coercion potentially invokes user .valueOf() and .toString()
* but can't result in a function value because ToPrimitive() would
* reject such a result: test-dev-json-stringify-coercion-1.js.
*/
- DUK_ASSERT(!duk_is_callable(ctx, -1));
+ DUK_ASSERT(!duk_is_callable(thr, -1));
break;
}
case DUK_HOBJECT_CLASS_STRING: {
DUK_DDD(DUK_DDDPRINT("value is a String object -> coerce with ToString()"));
- duk_to_string(ctx, -1);
+ duk_to_string(thr, -1);
/* Same coercion behavior as for Number. */
- DUK_ASSERT(!duk_is_callable(ctx, -1));
+ DUK_ASSERT(!duk_is_callable(thr, -1));
break;
}
#if defined(DUK_USE_JX) || defined(DUK_USE_JC)
@@ -34199,8 +35390,8 @@ DUK_LOCAL duk_bool_t duk__enc_value(duk_json_enc_ctx *js_ctx, duk_idx_t idx_hold
#endif
case DUK_HOBJECT_CLASS_BOOLEAN: {
DUK_DDD(DUK_DDDPRINT("value is a Boolean/Buffer/Pointer object -> get internal value"));
- duk_get_prop_stridx_short(ctx, -1, DUK_STRIDX_INT_VALUE);
- duk_remove_m2(ctx);
+ duk_get_prop_stridx_short(thr, -1, DUK_STRIDX_INT_VALUE);
+ duk_remove_m2(thr);
break;
}
default: {
@@ -34236,14 +35427,14 @@ DUK_LOCAL duk_bool_t duk__enc_value(duk_json_enc_ctx *js_ctx, duk_idx_t idx_hold
/* [ ... key val ] */
- DUK_DDD(DUK_DDDPRINT("value=%!T", (duk_tval *) duk_get_tval(ctx, -1)));
+ DUK_DDD(DUK_DDDPRINT("value=%!T", (duk_tval *) duk_get_tval(thr, -1)));
- if (duk_check_type_mask(ctx, -1, js_ctx->mask_for_undefined)) {
+ if (duk_check_type_mask(thr, -1, js_ctx->mask_for_undefined)) {
/* will result in undefined */
DUK_DDD(DUK_DDDPRINT("-> will result in undefined (type mask check)"));
goto pop2_undef;
}
- tv = DUK_GET_TVAL_NEGIDX(ctx, -1);
+ tv = DUK_GET_TVAL_NEGIDX(thr, -1);
switch (DUK_TVAL_GET_TAG(tv)) {
#if defined(DUK_USE_JX) || defined(DUK_USE_JC)
@@ -34311,7 +35502,7 @@ DUK_LOCAL duk_bool_t duk__enc_value(duk_json_enc_ctx *js_ctx, duk_idx_t idx_hold
/* Could implement a fastpath, but the fast path would need
* to handle realloc side effects correctly.
*/
- duk_to_object(ctx, -1);
+ duk_to_object(thr, -1);
duk__enc_object(js_ctx);
break;
}
@@ -34349,11 +35540,11 @@ DUK_LOCAL duk_bool_t duk__enc_value(duk_json_enc_ctx *js_ctx, duk_idx_t idx_hold
#if defined(DUK_USE_JX) || defined(DUK_USE_JC)
pop2_emitted:
#endif
- duk_pop_2(ctx); /* [ ... key val ] -> [ ... ] */
+ duk_pop_2(thr); /* [ ... key val ] -> [ ... ] */
return 1; /* emitted */
pop2_undef:
- duk_pop_2(ctx); /* [ ... key val ] -> [ ... ] */
+ duk_pop_2(thr); /* [ ... key val ] -> [ ... ] */
return 0; /* not emitted */
}
@@ -34482,7 +35673,7 @@ DUK_LOCAL duk_bool_t duk__json_stringify_fast_value(duk_json_enc_ctx *js_ctx, du
* it (though it's OK to abort the fast path).
*/
- DUK_ASSERT(js_ctx->recursion_depth >= 0);
+ DUK_ASSERT_DISABLE(js_ctx->recursion_depth >= 0); /* unsigned */
DUK_ASSERT(js_ctx->recursion_depth <= js_ctx->recursion_limit);
if (js_ctx->recursion_depth >= js_ctx->recursion_limit) {
DUK_DD(DUK_DDPRINT("fast path recursion limit"));
@@ -34514,7 +35705,7 @@ DUK_LOCAL duk_bool_t duk__json_stringify_fast_value(duk_json_enc_ctx *js_ctx, du
* but does at the moment, probably not worth fixing.
*/
if (duk_hobject_hasprop_raw(js_ctx->thr, obj, DUK_HTHREAD_STRING_TO_JSON(js_ctx->thr)) ||
- DUK_HOBJECT_HAS_EXOTIC_PROXYOBJ(obj)) {
+ DUK_HOBJECT_IS_PROXY(obj)) {
DUK_DD(DUK_DDPRINT("object has a .toJSON property or object is a Proxy, abort fast path"));
goto abort_fastpath;
}
@@ -34562,7 +35753,7 @@ DUK_LOCAL duk_bool_t duk__json_stringify_fast_value(duk_json_enc_ctx *js_ctx, du
c_object = c_all & ~(c_array | c_unbox | c_func | c_bufobj | c_undef | c_abort);
}
- c_bit = DUK_HOBJECT_GET_CLASS_MASK(obj);
+ c_bit = (duk_uint32_t) DUK_HOBJECT_GET_CLASS_MASK(obj);
if (c_bit & c_object) {
/* All other object types. */
DUK__EMIT_1(js_ctx, DUK_ASC_LCURLY);
@@ -34638,7 +35829,7 @@ DUK_LOCAL duk_bool_t duk__json_stringify_fast_value(duk_json_enc_ctx *js_ctx, du
DUK__UNEMIT_1(js_ctx); /* eat trailing comma */
if (DUK_UNLIKELY(js_ctx->h_gap != NULL)) {
DUK_ASSERT(js_ctx->recursion_depth >= 1);
- duk__enc_newline_indent(js_ctx, js_ctx->recursion_depth - 1);
+ duk__enc_newline_indent(js_ctx, js_ctx->recursion_depth - 1U);
}
}
DUK__EMIT_1(js_ctx, DUK_ASC_RCURLY);
@@ -34685,9 +35876,9 @@ DUK_LOCAL duk_bool_t duk__json_stringify_fast_value(duk_json_enc_ctx *js_ctx, du
* to support gappy arrays for all practical code.
*/
- h_tmp = duk_push_uint_to_hstring((duk_context *) js_ctx->thr, (duk_uint_t) i);
+ h_tmp = duk_push_uint_to_hstring(js_ctx->thr, (duk_uint_t) i);
has_inherited = duk_hobject_hasprop_raw(js_ctx->thr, obj, h_tmp);
- duk_pop((duk_context *) js_ctx->thr);
+ duk_pop(js_ctx->thr);
if (has_inherited) {
DUK_D(DUK_DPRINT("gap in array, conflicting inherited property, abort fast path"));
goto abort_fastpath;
@@ -34715,7 +35906,7 @@ DUK_LOCAL duk_bool_t duk__json_stringify_fast_value(duk_json_enc_ctx *js_ctx, du
DUK__UNEMIT_1(js_ctx); /* eat trailing comma */
if (DUK_UNLIKELY(js_ctx->h_gap != NULL)) {
DUK_ASSERT(js_ctx->recursion_depth >= 1);
- duk__enc_newline_indent(js_ctx, js_ctx->recursion_depth - 1);
+ duk__enc_newline_indent(js_ctx, js_ctx->recursion_depth - 1U);
}
}
DUK__EMIT_1(js_ctx, DUK_ASC_RBRACKET);
@@ -34845,9 +36036,9 @@ DUK_LOCAL duk_bool_t duk__json_stringify_fast_value(duk_json_enc_ctx *js_ctx, du
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_push_tval(js_ctx->thr, tv);
duk__enc_double(js_ctx);
- duk_pop((duk_context *) js_ctx->thr);
+ duk_pop(js_ctx->thr);
#if 0
/* Could also rely on native sprintf(), but it will handle
@@ -34876,20 +36067,20 @@ DUK_LOCAL duk_bool_t duk__json_stringify_fast_value(duk_json_enc_ctx *js_ctx, du
return 0; /* unreachable */
}
-DUK_LOCAL duk_ret_t duk__json_stringify_fast(duk_context *ctx, void *udata) {
+DUK_LOCAL duk_ret_t duk__json_stringify_fast(duk_hthread *thr, void *udata) {
duk_json_enc_ctx *js_ctx;
duk_tval *tv;
- DUK_ASSERT(ctx != NULL);
+ DUK_ASSERT(thr != NULL);
DUK_ASSERT(udata != NULL);
js_ctx = (duk_json_enc_ctx *) udata;
DUK_ASSERT(js_ctx != NULL);
- tv = DUK_GET_TVAL_NEGIDX(ctx, -1);
+ tv = DUK_GET_TVAL_NEGIDX(thr, -1);
if (duk__json_stringify_fast_value(js_ctx, tv) == 0) {
DUK_DD(DUK_DDPRINT("top level value not supported, fail fast path"));
- DUK_DCERROR_TYPE_INVALID_ARGS((duk_hthread *) ctx); /* Error message is ignored, so doesn't matter. */
+ DUK_DCERROR_TYPE_INVALID_ARGS(thr); /* Error message is ignored, so doesn't matter. */
}
return 0;
@@ -34901,16 +36092,15 @@ DUK_LOCAL duk_ret_t duk__json_stringify_fast(duk_context *ctx, void *udata) {
*/
DUK_INTERNAL
-void duk_bi_json_parse_helper(duk_context *ctx,
+void duk_bi_json_parse_helper(duk_hthread *thr,
duk_idx_t idx_value,
duk_idx_t idx_reviver,
duk_small_uint_t flags) {
- duk_hthread *thr = (duk_hthread *) ctx;
duk_json_dec_ctx js_ctx_alloc;
duk_json_dec_ctx *js_ctx = &js_ctx_alloc;
duk_hstring *h_text;
#if defined(DUK_USE_ASSERTIONS)
- duk_idx_t entry_top = duk_get_top(ctx);
+ duk_idx_t entry_top = duk_get_top(thr);
#endif
/* negative top-relative indices not allowed now */
@@ -34918,10 +36108,10 @@ void duk_bi_json_parse_helper(duk_context *ctx,
DUK_ASSERT(idx_reviver == DUK_INVALID_INDEX || idx_reviver >= 0);
DUK_DDD(DUK_DDDPRINT("JSON parse start: text=%!T, reviver=%!T, flags=0x%08lx, stack_top=%ld",
- (duk_tval *) duk_get_tval(ctx, idx_value),
- (duk_tval *) duk_get_tval(ctx, idx_reviver),
+ (duk_tval *) duk_get_tval(thr, idx_value),
+ (duk_tval *) duk_get_tval(thr, idx_reviver),
(unsigned long) flags,
- (long) duk_get_top(ctx)));
+ (long) duk_get_top(thr)));
DUK_MEMZERO(&js_ctx_alloc, sizeof(js_ctx_alloc));
js_ctx->thr = thr;
@@ -34946,7 +36136,7 @@ void duk_bi_json_parse_helper(duk_context *ctx,
js_ctx->flag_ext_custom_or_compatible = flags & (DUK_JSON_FLAG_EXT_CUSTOM | DUK_JSON_FLAG_EXT_COMPATIBLE);
#endif
- h_text = duk_to_hstring(ctx, idx_value); /* coerce in-place; rejects Symbols */
+ h_text = duk_to_hstring(thr, idx_value); /* coerce in-place; rejects Symbols */
DUK_ASSERT(h_text != NULL);
/* JSON parsing code is allowed to read [p_start,p_end]: p_end is
@@ -34969,47 +36159,46 @@ void duk_bi_json_parse_helper(duk_context *ctx,
duk__dec_syntax_error(js_ctx);
}
- if (duk_is_callable(ctx, idx_reviver)) {
+ if (duk_is_callable(thr, idx_reviver)) {
DUK_DDD(DUK_DDDPRINT("applying reviver: %!T",
- (duk_tval *) duk_get_tval(ctx, idx_reviver)));
+ (duk_tval *) duk_get_tval(thr, idx_reviver)));
js_ctx->idx_reviver = idx_reviver;
- duk_push_object(ctx);
- duk_dup_m2(ctx); /* -> [ ... val root val ] */
- duk_put_prop_stridx_short(ctx, -2, DUK_STRIDX_EMPTY_STRING); /* default attrs ok */
- duk_push_hstring_stridx(ctx, DUK_STRIDX_EMPTY_STRING); /* -> [ ... val root "" ] */
+ duk_push_object(thr);
+ duk_dup_m2(thr); /* -> [ ... val root val ] */
+ duk_put_prop_stridx_short(thr, -2, DUK_STRIDX_EMPTY_STRING); /* default attrs ok */
+ duk_push_hstring_stridx(thr, DUK_STRIDX_EMPTY_STRING); /* -> [ ... val root "" ] */
DUK_DDD(DUK_DDDPRINT("start reviver walk, root=%!T, name=%!T",
- (duk_tval *) duk_get_tval(ctx, -2),
- (duk_tval *) duk_get_tval(ctx, -1)));
+ (duk_tval *) duk_get_tval(thr, -2),
+ (duk_tval *) duk_get_tval(thr, -1)));
duk__dec_reviver_walk(js_ctx); /* [ ... val root "" ] -> [ ... val val' ] */
- duk_remove_m2(ctx); /* -> [ ... val' ] */
+ duk_remove_m2(thr); /* -> [ ... val' ] */
} else {
DUK_DDD(DUK_DDDPRINT("reviver does not exist or is not callable: %!T",
- (duk_tval *) duk_get_tval(ctx, idx_reviver)));
+ (duk_tval *) duk_get_tval(thr, idx_reviver)));
}
/* Final result is at stack top. */
DUK_DDD(DUK_DDDPRINT("JSON parse end: text=%!T, reviver=%!T, flags=0x%08lx, result=%!T, stack_top=%ld",
- (duk_tval *) duk_get_tval(ctx, idx_value),
- (duk_tval *) duk_get_tval(ctx, idx_reviver),
+ (duk_tval *) duk_get_tval(thr, idx_value),
+ (duk_tval *) duk_get_tval(thr, idx_reviver),
(unsigned long) flags,
- (duk_tval *) duk_get_tval(ctx, -1),
- (long) duk_get_top(ctx)));
+ (duk_tval *) duk_get_tval(thr, -1),
+ (long) duk_get_top(thr)));
- DUK_ASSERT(duk_get_top(ctx) == entry_top + 1);
+ DUK_ASSERT(duk_get_top(thr) == entry_top + 1);
}
DUK_INTERNAL
-void duk_bi_json_stringify_helper(duk_context *ctx,
+void duk_bi_json_stringify_helper(duk_hthread *thr,
duk_idx_t idx_value,
duk_idx_t idx_replacer,
duk_idx_t idx_space,
duk_small_uint_t flags) {
- duk_hthread *thr = (duk_hthread *) ctx;
duk_json_enc_ctx js_ctx_alloc;
duk_json_enc_ctx *js_ctx = &js_ctx_alloc;
duk_hobject *h;
@@ -35022,13 +36211,13 @@ void duk_bi_json_stringify_helper(duk_context *ctx,
DUK_ASSERT(idx_space == DUK_INVALID_INDEX || idx_space >= 0);
DUK_DDD(DUK_DDDPRINT("JSON stringify start: value=%!T, replacer=%!T, space=%!T, flags=0x%08lx, stack_top=%ld",
- (duk_tval *) duk_get_tval(ctx, idx_value),
- (duk_tval *) duk_get_tval(ctx, idx_replacer),
- (duk_tval *) duk_get_tval(ctx, idx_space),
+ (duk_tval *) duk_get_tval(thr, idx_value),
+ (duk_tval *) duk_get_tval(thr, idx_replacer),
+ (duk_tval *) duk_get_tval(thr, idx_space),
(unsigned long) flags,
- (long) duk_get_top(ctx)));
+ (long) duk_get_top(thr)));
- entry_top = duk_get_top(ctx);
+ entry_top = duk_get_top(thr);
/*
* Context init
@@ -35110,7 +36299,7 @@ void duk_bi_json_stringify_helper(duk_context *ctx,
DUK_BW_INIT_PUSHBUF(thr, &js_ctx->bw, DUK__JSON_STRINGIFY_BUFSIZE);
- js_ctx->idx_loop = duk_push_bare_object(ctx);
+ js_ctx->idx_loop = duk_push_bare_object(thr);
DUK_ASSERT(js_ctx->idx_loop >= 0);
/* [ ... buf loop ] */
@@ -35119,7 +36308,7 @@ void duk_bi_json_stringify_helper(duk_context *ctx,
* Process replacer/proplist (2nd argument to JSON.stringify)
*/
- h = duk_get_hobject(ctx, idx_replacer);
+ h = duk_get_hobject(thr, idx_replacer);
if (h != NULL) {
if (DUK_HOBJECT_IS_CALLABLE(h)) {
js_ctx->h_replacer = h;
@@ -35133,30 +36322,30 @@ void duk_bi_json_stringify_helper(duk_context *ctx,
duk_uarridx_t plist_idx = 0;
duk_small_uint_t enum_flags;
- js_ctx->idx_proplist = duk_push_array(ctx); /* XXX: array internal? */
+ js_ctx->idx_proplist = duk_push_array(thr); /* XXX: array internal? */
enum_flags = DUK_ENUM_ARRAY_INDICES_ONLY |
DUK_ENUM_SORT_ARRAY_INDICES; /* expensive flag */
- duk_enum(ctx, idx_replacer, enum_flags);
- while (duk_next(ctx, -1 /*enum_index*/, 1 /*get_value*/)) {
+ duk_enum(thr, idx_replacer, enum_flags);
+ while (duk_next(thr, -1 /*enum_index*/, 1 /*get_value*/)) {
/* [ ... proplist enum_obj key val ] */
- if (duk__enc_allow_into_proplist(duk_get_tval(ctx, -1))) {
+ if (duk__enc_allow_into_proplist(duk_get_tval(thr, -1))) {
/* XXX: duplicates should be eliminated here */
DUK_DDD(DUK_DDDPRINT("proplist enum: key=%!T, val=%!T --> accept",
- (duk_tval *) duk_get_tval(ctx, -2),
- (duk_tval *) duk_get_tval(ctx, -1)));
- duk_to_string(ctx, -1); /* extra coercion of strings is OK */
- duk_put_prop_index(ctx, -4, plist_idx); /* -> [ ... proplist enum_obj key ] */
+ (duk_tval *) duk_get_tval(thr, -2),
+ (duk_tval *) duk_get_tval(thr, -1)));
+ duk_to_string(thr, -1); /* extra coercion of strings is OK */
+ duk_put_prop_index(thr, -4, plist_idx); /* -> [ ... proplist enum_obj key ] */
plist_idx++;
- duk_pop(ctx);
+ duk_pop(thr);
} else {
DUK_DDD(DUK_DDDPRINT("proplist enum: key=%!T, val=%!T --> reject",
- (duk_tval *) duk_get_tval(ctx, -2),
- (duk_tval *) duk_get_tval(ctx, -1)));
- duk_pop_2(ctx);
+ (duk_tval *) duk_get_tval(thr, -2),
+ (duk_tval *) duk_get_tval(thr, -1)));
+ duk_pop_2(thr);
}
}
- duk_pop(ctx); /* pop enum */
+ duk_pop(thr); /* pop enum */
/* [ ... proplist ] */
}
@@ -35168,17 +36357,17 @@ void duk_bi_json_stringify_helper(duk_context *ctx,
* Process space (3rd argument to JSON.stringify)
*/
- h = duk_get_hobject(ctx, idx_space);
+ h = duk_get_hobject(thr, idx_space);
if (h != NULL) {
- int c = DUK_HOBJECT_GET_CLASS_NUMBER(h);
+ duk_small_uint_t c = DUK_HOBJECT_GET_CLASS_NUMBER(h);
if (c == DUK_HOBJECT_CLASS_NUMBER) {
- duk_to_number(ctx, idx_space);
+ duk_to_number(thr, idx_space);
} else if (c == DUK_HOBJECT_CLASS_STRING) {
- duk_to_string(ctx, idx_space);
+ duk_to_string(thr, idx_space);
}
}
- if (duk_is_number(ctx, idx_space)) {
+ if (duk_is_number(thr, idx_space)) {
duk_small_int_t nspace;
/* spaces[] must be static to allow initializer with old compilers like BCC */
static const char spaces[10] = {
@@ -35188,16 +36377,16 @@ void duk_bi_json_stringify_helper(duk_context *ctx,
}; /* XXX: helper */
/* ToInteger() coercion; NaN -> 0, infinities are clamped to 0 and 10 */
- nspace = (duk_small_int_t) duk_to_int_clamped(ctx, idx_space, 0 /*minval*/, 10 /*maxval*/);
+ nspace = (duk_small_int_t) duk_to_int_clamped(thr, idx_space, 0 /*minval*/, 10 /*maxval*/);
DUK_ASSERT(nspace >= 0 && nspace <= 10);
- duk_push_lstring(ctx, spaces, (duk_size_t) nspace);
- js_ctx->h_gap = duk_known_hstring(ctx, -1);
+ duk_push_lstring(thr, spaces, (duk_size_t) nspace);
+ js_ctx->h_gap = duk_known_hstring(thr, -1);
DUK_ASSERT(js_ctx->h_gap != NULL);
- } else if (duk_is_string_notsymbol(ctx, idx_space)) {
- duk_dup(ctx, idx_space);
- duk_substring(ctx, -1, 0, 10); /* clamp to 10 chars */
- js_ctx->h_gap = duk_known_hstring(ctx, -1);
+ } else if (duk_is_string_notsymbol(thr, idx_space)) {
+ duk_dup(thr, idx_space);
+ duk_substring(thr, -1, 0, 10); /* clamp to 10 chars */
+ js_ctx->h_gap = duk_known_hstring(thr, -1);
} else {
/* nop */
}
@@ -35242,7 +36431,7 @@ void duk_bi_json_stringify_helper(duk_context *ctx,
* limited loop detection).
*/
- duk_dup(ctx, idx_value);
+ duk_dup(thr, idx_value);
/* Must prevent finalizers which may have arbitrary side effects. */
prev_ms_base_flags = thr->heap->ms_base_flags;
@@ -35251,7 +36440,7 @@ void duk_bi_json_stringify_helper(duk_context *ctx,
thr->heap->pf_prevent_count++; /* Prevent finalizers. */
DUK_ASSERT(thr->heap->pf_prevent_count != 0); /* Wrap. */
- pcall_rc = duk_safe_call(ctx, duk__json_stringify_fast, (void *) js_ctx /*udata*/, 1 /*nargs*/, 0 /*nret*/);
+ pcall_rc = duk_safe_call(thr, duk__json_stringify_fast, (void *) js_ctx /*udata*/, 1 /*nargs*/, 0 /*nret*/);
DUK_ASSERT(thr->heap->pf_prevent_count > 0);
thr->heap->pf_prevent_count--;
@@ -35278,22 +36467,22 @@ void duk_bi_json_stringify_helper(duk_context *ctx,
* Create wrapper object and serialize
*/
- idx_holder = duk_push_object(ctx);
- duk_dup(ctx, idx_value);
- duk_put_prop_stridx_short(ctx, -2, DUK_STRIDX_EMPTY_STRING);
+ idx_holder = duk_push_object(thr);
+ duk_dup(thr, idx_value);
+ duk_put_prop_stridx_short(thr, -2, DUK_STRIDX_EMPTY_STRING);
DUK_DDD(DUK_DDDPRINT("before: flags=0x%08lx, loop=%!T, replacer=%!O, "
"proplist=%!T, gap=%!O, holder=%!T",
(unsigned long) js_ctx->flags,
- (duk_tval *) duk_get_tval(ctx, js_ctx->idx_loop),
+ (duk_tval *) duk_get_tval(thr, js_ctx->idx_loop),
(duk_heaphdr *) js_ctx->h_replacer,
- (duk_tval *) (js_ctx->idx_proplist >= 0 ? duk_get_tval(ctx, js_ctx->idx_proplist) : NULL),
+ (duk_tval *) (js_ctx->idx_proplist >= 0 ? duk_get_tval(thr, js_ctx->idx_proplist) : NULL),
(duk_heaphdr *) js_ctx->h_gap,
- (duk_tval *) duk_get_tval(ctx, -1)));
+ (duk_tval *) duk_get_tval(thr, -1)));
/* serialize the wrapper with empty string key */
- duk_push_hstring_empty(ctx);
+ duk_push_hstring_empty(thr);
/* [ ... buf loop (proplist) (gap) holder "" ] */
@@ -35302,7 +36491,7 @@ void duk_bi_json_stringify_helper(duk_context *ctx,
if (DUK_UNLIKELY(duk__enc_value(js_ctx, idx_holder) == 0)) { /* [ ... holder key ] -> [ ... holder ] */
/* Result is undefined. */
- duk_push_undefined(ctx);
+ duk_push_undefined(thr);
} else {
/* Convert buffer to result string. */
DUK_BW_PUSH_AS_STRING(thr, &js_ctx->bw);
@@ -35311,11 +36500,11 @@ void duk_bi_json_stringify_helper(duk_context *ctx,
DUK_DDD(DUK_DDDPRINT("after: flags=0x%08lx, loop=%!T, replacer=%!O, "
"proplist=%!T, gap=%!O, holder=%!T",
(unsigned long) js_ctx->flags,
- (duk_tval *) duk_get_tval(ctx, js_ctx->idx_loop),
+ (duk_tval *) duk_get_tval(thr, js_ctx->idx_loop),
(duk_heaphdr *) js_ctx->h_replacer,
- (duk_tval *) (js_ctx->idx_proplist >= 0 ? duk_get_tval(ctx, js_ctx->idx_proplist) : NULL),
+ (duk_tval *) (js_ctx->idx_proplist >= 0 ? duk_get_tval(thr, js_ctx->idx_proplist) : NULL),
(duk_heaphdr *) js_ctx->h_gap,
- (duk_tval *) duk_get_tval(ctx, idx_holder)));
+ (duk_tval *) duk_get_tval(thr, idx_holder)));
/* The stack has a variable shape here, so force it to the
* desired one explicitly.
@@ -35324,19 +36513,19 @@ void duk_bi_json_stringify_helper(duk_context *ctx,
#if defined(DUK_USE_JSON_STRINGIFY_FASTPATH)
replace_finished:
#endif
- duk_replace(ctx, entry_top);
- duk_set_top(ctx, entry_top + 1);
+ duk_replace(thr, entry_top);
+ duk_set_top(thr, entry_top + 1);
DUK_DDD(DUK_DDDPRINT("JSON stringify end: value=%!T, replacer=%!T, space=%!T, "
"flags=0x%08lx, result=%!T, stack_top=%ld",
- (duk_tval *) duk_get_tval(ctx, idx_value),
- (duk_tval *) duk_get_tval(ctx, idx_replacer),
- (duk_tval *) duk_get_tval(ctx, idx_space),
+ (duk_tval *) duk_get_tval(thr, idx_value),
+ (duk_tval *) duk_get_tval(thr, idx_replacer),
+ (duk_tval *) duk_get_tval(thr, idx_space),
(unsigned long) flags,
- (duk_tval *) duk_get_tval(ctx, -1),
- (long) duk_get_top(ctx)));
+ (duk_tval *) duk_get_tval(thr, -1),
+ (long) duk_get_top(thr)));
- DUK_ASSERT(duk_get_top(ctx) == entry_top + 1);
+ DUK_ASSERT(duk_get_top(thr) == entry_top + 1);
}
#if defined(DUK_USE_JSON_BUILTIN)
@@ -35345,16 +36534,16 @@ void duk_bi_json_stringify_helper(duk_context *ctx,
* Entry points
*/
-DUK_INTERNAL duk_ret_t duk_bi_json_object_parse(duk_context *ctx) {
- duk_bi_json_parse_helper(ctx,
+DUK_INTERNAL duk_ret_t duk_bi_json_object_parse(duk_hthread *thr) {
+ duk_bi_json_parse_helper(thr,
0 /*idx_value*/,
1 /*idx_replacer*/,
0 /*flags*/);
return 1;
}
-DUK_INTERNAL duk_ret_t duk_bi_json_object_stringify(duk_context *ctx) {
- duk_bi_json_stringify_helper(ctx,
+DUK_INTERNAL duk_ret_t duk_bi_json_object_stringify(duk_hthread *thr) {
+ duk_bi_json_stringify_helper(thr,
0 /*idx_value*/,
1 /*idx_replacer*/,
2 /*idx_space*/,
@@ -35399,8 +36588,8 @@ DUK_INTERNAL duk_ret_t duk_bi_json_object_stringify(duk_context *ctx) {
typedef double (*duk__one_arg_func)(double);
typedef double (*duk__two_arg_func)(double, double);
-DUK_LOCAL duk_ret_t duk__math_minmax(duk_context *ctx, duk_double_t initial, duk__two_arg_func min_max) {
- duk_idx_t n = duk_get_top(ctx);
+DUK_LOCAL duk_ret_t duk__math_minmax(duk_hthread *thr, duk_double_t initial, duk__two_arg_func min_max) {
+ duk_idx_t n = duk_get_top(thr);
duk_idx_t i;
duk_double_t res = initial;
duk_double_t t;
@@ -35417,7 +36606,7 @@ DUK_LOCAL duk_ret_t duk__math_minmax(duk_context *ctx, duk_double_t initial, duk
*/
for (i = 0; i < n; i++) {
- t = duk_to_number(ctx, i);
+ t = duk_to_number(thr, i);
if (DUK_FPCLASSIFY(t) == DUK_FP_NAN || DUK_FPCLASSIFY(res) == DUK_FP_NAN) {
/* Note: not normalized, but duk_push_number() will normalize */
res = (duk_double_t) DUK_DOUBLE_NAN;
@@ -35426,7 +36615,7 @@ DUK_LOCAL duk_ret_t duk__math_minmax(duk_context *ctx, duk_double_t initial, duk
}
}
- duk_push_number(ctx, res);
+ duk_push_number(thr, res);
return 1;
}
@@ -35694,49 +36883,49 @@ DUK_LOCAL const duk__two_arg_func duk__two_arg_funcs[] = {
#endif
};
-DUK_INTERNAL duk_ret_t duk_bi_math_object_onearg_shared(duk_context *ctx) {
- duk_small_int_t fun_idx = duk_get_current_magic(ctx);
+DUK_INTERNAL duk_ret_t duk_bi_math_object_onearg_shared(duk_hthread *thr) {
+ duk_small_int_t fun_idx = duk_get_current_magic(thr);
duk__one_arg_func fun;
duk_double_t arg1;
DUK_ASSERT(fun_idx >= 0);
DUK_ASSERT(fun_idx < (duk_small_int_t) (sizeof(duk__one_arg_funcs) / sizeof(duk__one_arg_func)));
- arg1 = duk_to_number(ctx, 0);
+ arg1 = duk_to_number(thr, 0);
fun = duk__one_arg_funcs[fun_idx];
- duk_push_number(ctx, (duk_double_t) fun((double) arg1));
+ duk_push_number(thr, (duk_double_t) fun((double) arg1));
return 1;
}
-DUK_INTERNAL duk_ret_t duk_bi_math_object_twoarg_shared(duk_context *ctx) {
- duk_small_int_t fun_idx = duk_get_current_magic(ctx);
+DUK_INTERNAL duk_ret_t duk_bi_math_object_twoarg_shared(duk_hthread *thr) {
+ duk_small_int_t fun_idx = duk_get_current_magic(thr);
duk__two_arg_func fun;
duk_double_t arg1;
duk_double_t arg2;
DUK_ASSERT(fun_idx >= 0);
DUK_ASSERT(fun_idx < (duk_small_int_t) (sizeof(duk__two_arg_funcs) / sizeof(duk__two_arg_func)));
- arg1 = duk_to_number(ctx, 0); /* explicit ordered evaluation to match coercion semantics */
- arg2 = duk_to_number(ctx, 1);
+ arg1 = duk_to_number(thr, 0); /* explicit ordered evaluation to match coercion semantics */
+ arg2 = duk_to_number(thr, 1);
fun = duk__two_arg_funcs[fun_idx];
- duk_push_number(ctx, (duk_double_t) fun((double) arg1, (double) arg2));
+ duk_push_number(thr, (duk_double_t) fun((double) arg1, (double) arg2));
return 1;
}
-DUK_INTERNAL duk_ret_t duk_bi_math_object_max(duk_context *ctx) {
- return duk__math_minmax(ctx, -DUK_DOUBLE_INFINITY, duk__fmax_fixed);
+DUK_INTERNAL duk_ret_t duk_bi_math_object_max(duk_hthread *thr) {
+ return duk__math_minmax(thr, -DUK_DOUBLE_INFINITY, duk__fmax_fixed);
}
-DUK_INTERNAL duk_ret_t duk_bi_math_object_min(duk_context *ctx) {
- return duk__math_minmax(ctx, DUK_DOUBLE_INFINITY, duk__fmin_fixed);
+DUK_INTERNAL duk_ret_t duk_bi_math_object_min(duk_hthread *thr) {
+ return duk__math_minmax(thr, DUK_DOUBLE_INFINITY, duk__fmin_fixed);
}
-DUK_INTERNAL duk_ret_t duk_bi_math_object_random(duk_context *ctx) {
- duk_push_number(ctx, (duk_double_t) DUK_UTIL_GET_RANDOM_DOUBLE((duk_hthread *) ctx));
+DUK_INTERNAL duk_ret_t duk_bi_math_object_random(duk_hthread *thr) {
+ duk_push_number(thr, (duk_double_t) DUK_UTIL_GET_RANDOM_DOUBLE(thr));
return 1;
}
#if defined(DUK_USE_ES6)
-DUK_INTERNAL duk_ret_t duk_bi_math_object_hypot(duk_context *ctx) {
+DUK_INTERNAL duk_ret_t duk_bi_math_object_hypot(duk_hthread *thr) {
/*
* E6 Section 20.2.2.18: Math.hypot
*
@@ -35756,13 +36945,13 @@ DUK_INTERNAL duk_ret_t duk_bi_math_object_hypot(duk_context *ctx) {
duk_double_t comp, prelim;
duk_double_t t;
- nargs = duk_get_top(ctx);
+ nargs = duk_get_top(thr);
/* Find the highest value. Also ToNumber() coerces. */
max = 0.0;
found_nan = 0;
for (i = 0; i < nargs; i++) {
- t = DUK_FABS(duk_to_number(ctx, i));
+ t = DUK_FABS(duk_to_number(thr, i));
if (DUK_FPCLASSIFY(t) == DUK_FP_NAN) {
found_nan = 1;
} else {
@@ -35772,13 +36961,13 @@ DUK_INTERNAL duk_ret_t duk_bi_math_object_hypot(duk_context *ctx) {
/* Early return cases. */
if (max == DUK_DOUBLE_INFINITY) {
- duk_push_number(ctx, DUK_DOUBLE_INFINITY);
+ duk_push_number(thr, DUK_DOUBLE_INFINITY);
return 1;
} else if (found_nan) {
- duk_push_number(ctx, DUK_DOUBLE_NAN);
+ duk_push_number(thr, DUK_DOUBLE_NAN);
return 1;
} else if (max == 0.0) {
- duk_push_number(ctx, 0.0);
+ duk_push_number(thr, 0.0);
/* Otherwise we'd divide by zero. */
return 1;
}
@@ -35791,14 +36980,107 @@ DUK_INTERNAL duk_ret_t duk_bi_math_object_hypot(duk_context *ctx) {
sum = 0.0;
comp = 0.0;
for (i = 0; i < nargs; i++) {
- t = DUK_FABS(duk_get_number(ctx, i)) / max;
+ t = DUK_FABS(duk_get_number(thr, i)) / max;
summand = (t * t) - comp;
prelim = sum + summand;
comp = (prelim - sum) - summand;
sum = prelim;
}
- duk_push_number(ctx, (duk_double_t) DUK_SQRT(sum) * max);
+ duk_push_number(thr, (duk_double_t) DUK_SQRT(sum) * max);
+ return 1;
+}
+#endif /* DUK_USE_ES6 */
+
+#if defined(DUK_USE_ES6)
+DUK_INTERNAL duk_ret_t duk_bi_math_object_sign(duk_hthread *thr) {
+ duk_double_t d;
+
+ d = duk_to_number(thr, 0);
+ if (duk_double_is_nan(d)) {
+ DUK_ASSERT(duk_is_nan(thr, -1));
+ return 1; /* NaN input -> return NaN */
+ }
+ if (d == 0.0) {
+ /* Zero sign kept, i.e. -0 -> -0, +0 -> +0. */
+ return 1;
+ }
+ duk_push_int(thr, (d > 0.0 ? 1 : -1));
+ return 1;
+}
+#endif /* DUK_USE_ES6 */
+
+#if defined(DUK_USE_ES6)
+DUK_INTERNAL duk_ret_t duk_bi_math_object_clz32(duk_hthread *thr) {
+ duk_uint32_t x;
+ duk_small_uint_t i;
+
+#if defined(DUK_USE_PREFER_SIZE)
+ duk_uint32_t mask;
+
+ x = duk_to_uint32(thr, 0);
+ for (i = 0, mask = 0x80000000UL; mask != 0; mask >>= 1) {
+ if (x & mask) {
+ break;
+ }
+ i++;
+ }
+ DUK_ASSERT(i <= 32);
+ duk_push_uint(thr, i);
+ return 1;
+#else /* DUK_USE_PREFER_SIZE */
+ i = 0;
+ x = duk_to_uint32(thr, 0);
+ if (x & 0xffff0000UL) {
+ x >>= 16;
+ } else {
+ i += 16;
+ }
+ if (x & 0x0000ff00UL) {
+ x >>= 8;
+ } else {
+ i += 8;
+ }
+ if (x & 0x000000f0UL) {
+ x >>= 4;
+ } else {
+ i += 4;
+ }
+ if (x & 0x0000000cUL) {
+ x >>= 2;
+ } else {
+ i += 2;
+ }
+ if (x & 0x00000002UL) {
+ x >>= 1;
+ } else {
+ i += 1;
+ }
+ if (x & 0x00000001UL) {
+ ;
+ } else {
+ i += 1;
+ }
+ DUK_ASSERT(i <= 32);
+ duk_push_uint(thr, i);
+ return 1;
+#endif /* DUK_USE_PREFER_SIZE */
+}
+#endif /* DUK_USE_ES6 */
+
+#if defined(DUK_USE_ES6)
+DUK_INTERNAL duk_ret_t duk_bi_math_object_imul(duk_hthread *thr) {
+ duk_uint32_t x, y, z;
+
+ x = duk_to_uint32(thr, 0);
+ y = duk_to_uint32(thr, 1);
+ z = x * y;
+
+ /* While arguments are ToUint32() coerced and the multiplication
+ * is unsigned as such, the final result is curiously interpreted
+ * as a signed 32-bit value.
+ */
+ duk_push_i32(thr, (duk_int32_t) z);
return 1;
}
#endif /* DUK_USE_ES6 */
@@ -35812,41 +37094,38 @@ DUK_INTERNAL duk_ret_t duk_bi_math_object_hypot(duk_context *ctx) {
#if defined(DUK_USE_NUMBER_BUILTIN)
-DUK_LOCAL duk_double_t duk__push_this_number_plain(duk_context *ctx) {
+DUK_LOCAL duk_double_t duk__push_this_number_plain(duk_hthread *thr) {
duk_hobject *h;
/* Number built-in accepts a plain number or a Number object (whose
* internal value is operated on). Other types cause TypeError.
*/
- duk_push_this(ctx);
- if (duk_is_number(ctx, -1)) {
- DUK_DDD(DUK_DDDPRINT("plain number value: %!T", (duk_tval *) duk_get_tval(ctx, -1)));
+ duk_push_this(thr);
+ if (duk_is_number(thr, -1)) {
+ DUK_DDD(DUK_DDDPRINT("plain number value: %!T", (duk_tval *) duk_get_tval(thr, -1)));
goto done;
}
- h = duk_get_hobject(ctx, -1);
+ h = duk_get_hobject(thr, -1);
if (!h ||
(DUK_HOBJECT_GET_CLASS_NUMBER(h) != DUK_HOBJECT_CLASS_NUMBER)) {
- DUK_DDD(DUK_DDDPRINT("unacceptable this value: %!T", (duk_tval *) duk_get_tval(ctx, -1)));
- DUK_ERROR_TYPE((duk_hthread *) ctx, "number expected");
+ DUK_DDD(DUK_DDDPRINT("unacceptable this value: %!T", (duk_tval *) duk_get_tval(thr, -1)));
+ DUK_ERROR_TYPE(thr, "number expected");
}
- duk_get_prop_stridx_short(ctx, -1, DUK_STRIDX_INT_VALUE);
- DUK_ASSERT(duk_is_number(ctx, -1));
+ duk_get_prop_stridx_short(thr, -1, DUK_STRIDX_INT_VALUE);
+ DUK_ASSERT(duk_is_number(thr, -1));
DUK_DDD(DUK_DDDPRINT("number object: %!T, internal value: %!T",
- (duk_tval *) duk_get_tval(ctx, -2), (duk_tval *) duk_get_tval(ctx, -1)));
- duk_remove_m2(ctx);
+ (duk_tval *) duk_get_tval(thr, -2), (duk_tval *) duk_get_tval(thr, -1)));
+ duk_remove_m2(thr);
done:
- return duk_get_number(ctx, -1);
+ return duk_get_number(thr, -1);
}
-DUK_INTERNAL duk_ret_t duk_bi_number_constructor(duk_context *ctx) {
- duk_hthread *thr = (duk_hthread *) ctx;
+DUK_INTERNAL duk_ret_t duk_bi_number_constructor(duk_hthread *thr) {
duk_idx_t nargs;
duk_hobject *h_this;
- DUK_UNREF(thr);
-
/*
* The Number constructor uses ToNumber(arg) for number coercion
* (coercing an undefined argument to NaN). However, if the
@@ -35854,15 +37133,15 @@ DUK_INTERNAL duk_ret_t duk_bi_number_constructor(duk_context *ctx) {
* this, a vararg function is used.
*/
- nargs = duk_get_top(ctx);
+ nargs = duk_get_top(thr);
if (nargs == 0) {
- duk_push_int(ctx, 0);
+ duk_push_int(thr, 0);
}
- duk_to_number(ctx, 0);
- duk_set_top(ctx, 1);
- DUK_ASSERT_TOP(ctx, 1);
+ duk_to_number(thr, 0);
+ duk_set_top(thr, 1);
+ DUK_ASSERT_TOP(thr, 1);
- if (!duk_is_constructor_call(ctx)) {
+ if (!duk_is_constructor_call(thr)) {
return 1;
}
@@ -35880,50 +37159,50 @@ DUK_INTERNAL duk_ret_t duk_bi_number_constructor(duk_context *ctx) {
*/
/* XXX: helper */
- duk_push_this(ctx);
- h_this = duk_known_hobject(ctx, -1);
+ duk_push_this(thr);
+ h_this = duk_known_hobject(thr, -1);
DUK_HOBJECT_SET_CLASS_NUMBER(h_this, DUK_HOBJECT_CLASS_NUMBER);
DUK_ASSERT(DUK_HOBJECT_GET_PROTOTYPE(thr->heap, h_this) == thr->builtins[DUK_BIDX_NUMBER_PROTOTYPE]);
DUK_ASSERT(DUK_HOBJECT_GET_CLASS_NUMBER(h_this) == DUK_HOBJECT_CLASS_NUMBER);
DUK_ASSERT(DUK_HOBJECT_HAS_EXTENSIBLE(h_this));
- duk_dup_0(ctx); /* -> [ val obj val ] */
- duk_xdef_prop_stridx_short(ctx, -2, DUK_STRIDX_INT_VALUE, DUK_PROPDESC_FLAGS_NONE);
+ duk_dup_0(thr); /* -> [ val obj val ] */
+ duk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_INT_VALUE, DUK_PROPDESC_FLAGS_NONE);
return 0; /* no return value -> don't replace created value */
}
-DUK_INTERNAL duk_ret_t duk_bi_number_prototype_value_of(duk_context *ctx) {
- (void) duk__push_this_number_plain(ctx);
+DUK_INTERNAL duk_ret_t duk_bi_number_prototype_value_of(duk_hthread *thr) {
+ (void) duk__push_this_number_plain(thr);
return 1;
}
-DUK_INTERNAL duk_ret_t duk_bi_number_prototype_to_string(duk_context *ctx) {
+DUK_INTERNAL duk_ret_t duk_bi_number_prototype_to_string(duk_hthread *thr) {
duk_small_int_t radix;
duk_small_uint_t n2s_flags;
- (void) duk__push_this_number_plain(ctx);
- if (duk_is_undefined(ctx, 0)) {
+ (void) duk__push_this_number_plain(thr);
+ if (duk_is_undefined(thr, 0)) {
radix = 10;
} else {
- radix = (duk_small_int_t) duk_to_int_check_range(ctx, 0, 2, 36);
+ radix = (duk_small_int_t) duk_to_int_check_range(thr, 0, 2, 36);
}
DUK_DDD(DUK_DDDPRINT("radix=%ld", (long) radix));
n2s_flags = 0;
- duk_numconv_stringify(ctx,
+ duk_numconv_stringify(thr,
radix /*radix*/,
0 /*digits*/,
n2s_flags /*flags*/);
return 1;
}
-DUK_INTERNAL duk_ret_t duk_bi_number_prototype_to_locale_string(duk_context *ctx) {
+DUK_INTERNAL duk_ret_t duk_bi_number_prototype_to_locale_string(duk_hthread *thr) {
/* XXX: just use toString() for now; permitted although not recommended.
* nargs==1, so radix is passed to toString().
*/
- return duk_bi_number_prototype_to_string(ctx);
+ return duk_bi_number_prototype_to_string(thr);
}
/*
@@ -35932,14 +37211,14 @@ DUK_INTERNAL duk_ret_t duk_bi_number_prototype_to_locale_string(duk_context *ctx
/* XXX: shared helper for toFixed(), toExponential(), toPrecision()? */
-DUK_INTERNAL duk_ret_t duk_bi_number_prototype_to_fixed(duk_context *ctx) {
+DUK_INTERNAL duk_ret_t duk_bi_number_prototype_to_fixed(duk_hthread *thr) {
duk_small_int_t frac_digits;
duk_double_t d;
duk_small_int_t c;
duk_small_uint_t n2s_flags;
- frac_digits = (duk_small_int_t) duk_to_int_check_range(ctx, 0, 0, 20);
- d = duk__push_this_number_plain(ctx);
+ frac_digits = (duk_small_int_t) duk_to_int_check_range(thr, 0, 0, 20);
+ d = duk__push_this_number_plain(thr);
c = (duk_small_int_t) DUK_FPCLASSIFY(d);
if (c == DUK_FP_NAN || c == DUK_FP_INFINITE) {
@@ -35953,53 +37232,53 @@ DUK_INTERNAL duk_ret_t duk_bi_number_prototype_to_fixed(duk_context *ctx) {
n2s_flags = DUK_N2S_FLAG_FIXED_FORMAT |
DUK_N2S_FLAG_FRACTION_DIGITS;
- duk_numconv_stringify(ctx,
+ duk_numconv_stringify(thr,
10 /*radix*/,
frac_digits /*digits*/,
n2s_flags /*flags*/);
return 1;
use_to_string:
- DUK_ASSERT_TOP(ctx, 2);
- duk_to_string(ctx, -1);
+ DUK_ASSERT_TOP(thr, 2);
+ duk_to_string(thr, -1);
return 1;
}
-DUK_INTERNAL duk_ret_t duk_bi_number_prototype_to_exponential(duk_context *ctx) {
+DUK_INTERNAL duk_ret_t duk_bi_number_prototype_to_exponential(duk_hthread *thr) {
duk_bool_t frac_undefined;
duk_small_int_t frac_digits;
duk_double_t d;
duk_small_int_t c;
duk_small_uint_t n2s_flags;
- d = duk__push_this_number_plain(ctx);
+ d = duk__push_this_number_plain(thr);
- frac_undefined = duk_is_undefined(ctx, 0);
- duk_to_int(ctx, 0); /* for side effects */
+ frac_undefined = duk_is_undefined(thr, 0);
+ duk_to_int(thr, 0); /* for side effects */
c = (duk_small_int_t) DUK_FPCLASSIFY(d);
if (c == DUK_FP_NAN || c == DUK_FP_INFINITE) {
goto use_to_string;
}
- frac_digits = (duk_small_int_t) duk_to_int_check_range(ctx, 0, 0, 20);
+ frac_digits = (duk_small_int_t) duk_to_int_check_range(thr, 0, 0, 20);
n2s_flags = DUK_N2S_FLAG_FORCE_EXP |
(frac_undefined ? 0 : DUK_N2S_FLAG_FIXED_FORMAT);
- duk_numconv_stringify(ctx,
+ duk_numconv_stringify(thr,
10 /*radix*/,
frac_digits + 1 /*leading digit + fractions*/,
n2s_flags /*flags*/);
return 1;
use_to_string:
- DUK_ASSERT_TOP(ctx, 2);
- duk_to_string(ctx, -1);
+ DUK_ASSERT_TOP(thr, 2);
+ duk_to_string(thr, -1);
return 1;
}
-DUK_INTERNAL duk_ret_t duk_bi_number_prototype_to_precision(duk_context *ctx) {
+DUK_INTERNAL duk_ret_t duk_bi_number_prototype_to_precision(duk_hthread *thr) {
/* The specification has quite awkward order of coercion and
* checks for toPrecision(). The operations below are a bit
* reordered, within constraints of observable side effects.
@@ -36010,27 +37289,27 @@ DUK_INTERNAL duk_ret_t duk_bi_number_prototype_to_precision(duk_context *ctx) {
duk_small_int_t c;
duk_small_uint_t n2s_flags;
- DUK_ASSERT_TOP(ctx, 1);
+ DUK_ASSERT_TOP(thr, 1);
- d = duk__push_this_number_plain(ctx);
- if (duk_is_undefined(ctx, 0)) {
+ d = duk__push_this_number_plain(thr);
+ if (duk_is_undefined(thr, 0)) {
goto use_to_string;
}
- DUK_ASSERT_TOP(ctx, 2);
+ DUK_ASSERT_TOP(thr, 2);
- duk_to_int(ctx, 0); /* for side effects */
+ duk_to_int(thr, 0); /* for side effects */
c = (duk_small_int_t) DUK_FPCLASSIFY(d);
if (c == DUK_FP_NAN || c == DUK_FP_INFINITE) {
goto use_to_string;
}
- prec = (duk_small_int_t) duk_to_int_check_range(ctx, 0, 1, 21);
+ prec = (duk_small_int_t) duk_to_int_check_range(thr, 0, 1, 21);
n2s_flags = DUK_N2S_FLAG_FIXED_FORMAT |
DUK_N2S_FLAG_NO_ZERO_PAD;
- duk_numconv_stringify(ctx,
+ duk_numconv_stringify(thr,
10 /*radix*/,
prec /*digits*/,
n2s_flags /*flags*/);
@@ -36041,8 +37320,8 @@ DUK_INTERNAL duk_ret_t duk_bi_number_prototype_to_precision(duk_context *ctx) {
* and +/- infinity (-> "Infinity", "-Infinity").
*/
- DUK_ASSERT_TOP(ctx, 2);
- duk_to_string(ctx, -1);
+ DUK_ASSERT_TOP(thr, 2);
+ duk_to_string(thr, -1);
return 1;
}
@@ -36054,26 +37333,26 @@ DUK_INTERNAL duk_ret_t duk_bi_number_prototype_to_precision(duk_context *ctx) {
/* #include duk_internal.h -> already included */
/* Needed even when Object built-in disabled. */
-DUK_INTERNAL duk_ret_t duk_bi_object_prototype_to_string(duk_context *ctx) {
+DUK_INTERNAL duk_ret_t duk_bi_object_prototype_to_string(duk_hthread *thr) {
duk_tval *tv;
- tv = DUK_HTHREAD_THIS_PTR((duk_hthread *) ctx);
+ tv = DUK_HTHREAD_THIS_PTR(thr);
/* XXX: This is not entirely correct anymore; in ES2015 the
* default lookup should use @@toStringTag to come up with
* e.g. [object Symbol].
*/
- duk_push_class_string_tval(ctx, tv);
+ duk_push_class_string_tval(thr, tv);
return 1;
}
#if defined(DUK_USE_OBJECT_BUILTIN)
-DUK_INTERNAL duk_ret_t duk_bi_object_constructor(duk_context *ctx) {
+DUK_INTERNAL duk_ret_t duk_bi_object_constructor(duk_hthread *thr) {
duk_uint_t arg_mask;
- arg_mask = duk_get_type_mask(ctx, 0);
+ arg_mask = duk_get_type_mask(thr, 0);
- if (!duk_is_constructor_call(ctx) && /* not a constructor call */
+ if (!duk_is_constructor_call(thr) && /* not a constructor call */
((arg_mask & (DUK_TYPE_MASK_NULL | DUK_TYPE_MASK_UNDEFINED)) == 0)) { /* and argument not null or undefined */
- duk_to_object(ctx, 0);
+ duk_to_object(thr, 0);
return 1;
}
@@ -36093,11 +37372,11 @@ DUK_INTERNAL duk_ret_t duk_bi_object_constructor(duk_context *ctx) {
* be checked for explicitly, but Object(obj) calls are
* not very common so opt for minimal footprint.
*/
- duk_to_object(ctx, 0);
+ duk_to_object(thr, 0);
return 1;
}
- (void) duk_push_object_helper(ctx,
+ (void) duk_push_object_helper(thr,
DUK_HOBJECT_FLAG_EXTENSIBLE |
DUK_HOBJECT_FLAG_FASTREFS |
DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_OBJECT),
@@ -36107,27 +37386,27 @@ DUK_INTERNAL duk_ret_t duk_bi_object_constructor(duk_context *ctx) {
#endif /* DUK_USE_OBJECT_BUILTIN */
#if defined(DUK_USE_OBJECT_BUILTIN) && defined(DUK_USE_ES6)
-DUK_INTERNAL duk_ret_t duk_bi_object_constructor_assign(duk_context *ctx) {
+DUK_INTERNAL duk_ret_t duk_bi_object_constructor_assign(duk_hthread *thr) {
duk_idx_t nargs;
duk_int_t idx;
- nargs = duk_get_top_require_min(ctx, 1 /*min_top*/);
+ nargs = duk_get_top_require_min(thr, 1 /*min_top*/);
- duk_to_object(ctx, 0);
+ duk_to_object(thr, 0);
for (idx = 1; idx < nargs; idx++) {
/* E7 19.1.2.1 (step 4a) */
- if (duk_is_null_or_undefined(ctx, idx)) {
+ if (duk_is_null_or_undefined(thr, idx)) {
continue;
}
/* duk_enum() respects ES2015+ [[OwnPropertyKeys]] ordering, which is
* convenient here.
*/
- duk_to_object(ctx, idx);
- duk_enum(ctx, idx, DUK_ENUM_OWN_PROPERTIES_ONLY);
- while (duk_next(ctx, -1, 1 /*get_value*/)) {
+ duk_to_object(thr, idx);
+ duk_enum(thr, idx, DUK_ENUM_OWN_PROPERTIES_ONLY);
+ while (duk_next(thr, -1, 1 /*get_value*/)) {
/* [ target ... enum key value ] */
- duk_put_prop(ctx, 0);
+ duk_put_prop(thr, 0);
/* [ target ... enum ] */
}
/* Could pop enumerator, but unnecessary because of duk_set_top()
@@ -36135,41 +37414,41 @@ DUK_INTERNAL duk_ret_t duk_bi_object_constructor_assign(duk_context *ctx) {
*/
}
- duk_set_top(ctx, 1);
+ duk_set_top(thr, 1);
return 1;
}
#endif
#if defined(DUK_USE_OBJECT_BUILTIN) && defined(DUK_USE_ES6)
-DUK_INTERNAL duk_ret_t duk_bi_object_constructor_is(duk_context *ctx) {
- DUK_ASSERT_TOP(ctx, 2);
- duk_push_boolean(ctx, duk_samevalue(ctx, 0, 1));
+DUK_INTERNAL duk_ret_t duk_bi_object_constructor_is(duk_hthread *thr) {
+ DUK_ASSERT_TOP(thr, 2);
+ duk_push_boolean(thr, duk_samevalue(thr, 0, 1));
return 1;
}
#endif
#if defined(DUK_USE_OBJECT_BUILTIN)
-DUK_INTERNAL duk_ret_t duk_bi_object_constructor_create(duk_context *ctx) {
+DUK_INTERNAL duk_ret_t duk_bi_object_constructor_create(duk_hthread *thr) {
duk_hobject *proto;
- DUK_ASSERT_TOP(ctx, 2);
+ DUK_ASSERT_TOP(thr, 2);
#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)
- duk_hbufobj_promote_plain(ctx, 0);
+ duk_hbufobj_promote_plain(thr, 0);
#endif
- proto = duk_require_hobject_accept_mask(ctx, 0, DUK_TYPE_MASK_NULL);
- DUK_ASSERT(proto != NULL || duk_is_null(ctx, 0));
+ proto = duk_require_hobject_accept_mask(thr, 0, DUK_TYPE_MASK_NULL);
+ DUK_ASSERT(proto != NULL || duk_is_null(thr, 0));
- (void) duk_push_object_helper_proto(ctx,
+ (void) duk_push_object_helper_proto(thr,
DUK_HOBJECT_FLAG_EXTENSIBLE |
DUK_HOBJECT_FLAG_FASTREFS |
DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_OBJECT),
proto);
- if (!duk_is_undefined(ctx, 1)) {
+ if (!duk_is_undefined(thr, 1)) {
/* [ O Properties obj ] */
- duk_replace(ctx, 0);
+ duk_replace(thr, 0);
/* [ obj Properties ] */
@@ -36177,7 +37456,7 @@ DUK_INTERNAL duk_ret_t duk_bi_object_constructor_create(duk_context *ctx) {
* finish up.
*/
- return duk_bi_object_constructor_define_properties(ctx);
+ return duk_bi_object_constructor_define_properties(thr);
}
/* [ O Properties obj ] */
@@ -36187,7 +37466,7 @@ DUK_INTERNAL duk_ret_t duk_bi_object_constructor_create(duk_context *ctx) {
#endif /* DUK_USE_OBJECT_BUILTIN */
#if defined(DUK_USE_OBJECT_BUILTIN)
-DUK_INTERNAL duk_ret_t duk_bi_object_constructor_define_properties(duk_context *ctx) {
+DUK_INTERNAL duk_ret_t duk_bi_object_constructor_define_properties(duk_hthread *thr) {
duk_small_uint_t pass;
duk_uint_t defprop_flags;
duk_hobject *obj;
@@ -36196,14 +37475,14 @@ DUK_INTERNAL duk_ret_t duk_bi_object_constructor_define_properties(duk_context *
duk_hobject *set;
/* Lightfunc and plain buffer handling by ToObject() coercion. */
- obj = duk_require_hobject_promote_mask(ctx, 0, DUK_TYPE_MASK_LIGHTFUNC | DUK_TYPE_MASK_BUFFER);
+ obj = duk_require_hobject_promote_mask(thr, 0, DUK_TYPE_MASK_LIGHTFUNC | DUK_TYPE_MASK_BUFFER);
DUK_ASSERT(obj != NULL);
- duk_to_object(ctx, 1); /* properties object */
+ duk_to_object(thr, 1); /* properties object */
DUK_DDD(DUK_DDDPRINT("target=%!iT, properties=%!iT",
- (duk_tval *) duk_get_tval(ctx, 0),
- (duk_tval *) duk_get_tval(ctx, 1)));
+ (duk_tval *) duk_get_tval(thr, 0),
+ (duk_tval *) duk_get_tval(thr, 1)));
/*
* Two pass approach to processing the property descriptors.
@@ -36216,27 +37495,27 @@ DUK_INTERNAL duk_ret_t duk_bi_object_constructor_define_properties(duk_context *
*/
for (pass = 0; pass < 2; pass++) {
- duk_set_top(ctx, 2); /* -> [ hobject props ] */
- duk_enum(ctx, 1, DUK_ENUM_OWN_PROPERTIES_ONLY | DUK_ENUM_INCLUDE_SYMBOLS /*enum_flags*/);
+ duk_set_top(thr, 2); /* -> [ hobject props ] */
+ duk_enum(thr, 1, DUK_ENUM_OWN_PROPERTIES_ONLY | DUK_ENUM_INCLUDE_SYMBOLS /*enum_flags*/);
for (;;) {
duk_hstring *key;
/* [ hobject props enum(props) ] */
- duk_set_top(ctx, 3);
+ duk_set_top(thr, 3);
- if (!duk_next(ctx, 2, 1 /*get_value*/)) {
+ if (!duk_next(thr, 2, 1 /*get_value*/)) {
break;
}
DUK_DDD(DUK_DDDPRINT("-> key=%!iT, desc=%!iT",
- (duk_tval *) duk_get_tval(ctx, -2),
- (duk_tval *) duk_get_tval(ctx, -1)));
+ (duk_tval *) duk_get_tval(thr, -2),
+ (duk_tval *) duk_get_tval(thr, -1)));
/* [ hobject props enum(props) key desc ] */
- duk_hobject_prepare_property_descriptor(ctx,
+ duk_hobject_prepare_property_descriptor(thr,
4 /*idx_desc*/,
&defprop_flags,
&idx_value,
@@ -36250,10 +37529,10 @@ DUK_INTERNAL duk_ret_t duk_bi_object_constructor_define_properties(duk_context *
}
/* This allows symbols on purpose. */
- key = duk_known_hstring(ctx, 3);
+ key = duk_known_hstring(thr, 3);
DUK_ASSERT(key != NULL);
- duk_hobject_define_property_helper(ctx,
+ duk_hobject_define_property_helper(thr,
defprop_flags,
obj,
key,
@@ -36268,149 +37547,100 @@ DUK_INTERNAL duk_ret_t duk_bi_object_constructor_define_properties(duk_context *
* Return target object
*/
- duk_dup_0(ctx);
+ duk_dup_0(thr);
return 1;
}
#endif /* DUK_USE_OBJECT_BUILTIN */
#if defined(DUK_USE_OBJECT_BUILTIN)
-DUK_INTERNAL duk_ret_t duk_bi_object_constructor_seal_freeze_shared(duk_context *ctx) {
- duk_hthread *thr = (duk_hthread *) ctx;
- duk_hobject *h;
- duk_bool_t is_freeze;
-
- DUK_ASSERT_TOP(ctx, 1);
+DUK_INTERNAL duk_ret_t duk_bi_object_constructor_seal_freeze_shared(duk_hthread *thr) {
+ DUK_ASSERT_TOP(thr, 1);
- is_freeze = (duk_bool_t) duk_get_current_magic(ctx);
- if (duk_is_buffer(ctx, 0)) {
- /* Plain buffer: already sealed, but not frozen (and can't be frozen
- * because index properties can't be made non-writable.
- */
- if (is_freeze) {
- goto fail_cannot_freeze;
- }
- return 1;
- } else if (duk_is_lightfunc(ctx, 0)) {
- /* Lightfunc: already sealed and frozen, success. */
- return 1;
- }
-#if 0
- /* Seal/freeze are quite rare in practice so it'd be nice to get the
- * correct behavior simply via automatic promotion (at the cost of some
- * memory churn). However, the promoted objects don't behave the same,
- * e.g. promoted lightfuncs are extensible.
- */
- h = duk_require_hobject_promote_mask(ctx, 0, DUK_TYPE_MASK_LIGHTFUNC | DUK_TYPE_MASK_BUFFER);
-#endif
-
- h = duk_get_hobject(ctx, 0);
- if (h == NULL) {
- /* ES2015 Sections 19.1.2.5, 19.1.2.17 */
- return 1;
- }
-
- if (is_freeze && DUK_HOBJECT_IS_BUFOBJ(h)) {
- /* Buffer objects cannot be frozen because there's no internal
- * support for making virtual array indices non-writable.
- */
- DUK_DD(DUK_DDPRINT("cannot freeze a buffer object"));
- goto fail_cannot_freeze;
- }
-
- duk_hobject_object_seal_freeze_helper(thr, h, is_freeze);
-
- /* Sealed and frozen objects cannot gain any more properties,
- * so this is a good time to compact them.
- */
- duk_hobject_compact_props(thr, h);
+ duk_seal_freeze_raw(thr, 0, (duk_bool_t) duk_get_current_magic(thr) /*is_freeze*/);
return 1;
-
- fail_cannot_freeze:
- DUK_DCERROR_TYPE_INVALID_ARGS(thr); /* XXX: proper error message */
}
#endif /* DUK_USE_OBJECT_BUILTIN */
#if defined(DUK_USE_OBJECT_BUILTIN)
-DUK_INTERNAL duk_ret_t duk_bi_object_constructor_is_sealed_frozen_shared(duk_context *ctx) {
+DUK_INTERNAL duk_ret_t duk_bi_object_constructor_is_sealed_frozen_shared(duk_hthread *thr) {
duk_hobject *h;
duk_bool_t is_frozen;
duk_uint_t mask;
- is_frozen = duk_get_current_magic(ctx);
- mask = duk_get_type_mask(ctx, 0);
+ is_frozen = (duk_bool_t) duk_get_current_magic(thr);
+ mask = duk_get_type_mask(thr, 0);
if (mask & (DUK_TYPE_MASK_LIGHTFUNC | DUK_TYPE_MASK_BUFFER)) {
DUK_ASSERT(is_frozen == 0 || is_frozen == 1);
- duk_push_boolean(ctx, (mask & DUK_TYPE_MASK_LIGHTFUNC) ?
+ duk_push_boolean(thr, (mask & DUK_TYPE_MASK_LIGHTFUNC) ?
1 : /* lightfunc always frozen and sealed */
(is_frozen ^ 1)); /* buffer sealed but not frozen (index props writable) */
} else {
/* ES2015 Sections 19.1.2.12, 19.1.2.13: anything other than an object
* is considered to be already sealed and frozen.
*/
- h = duk_get_hobject(ctx, 0);
- duk_push_boolean(ctx, (h == NULL) ||
- duk_hobject_object_is_sealed_frozen_helper((duk_hthread *) ctx, h, is_frozen /*is_frozen*/));
+ h = duk_get_hobject(thr, 0);
+ duk_push_boolean(thr, (h == NULL) ||
+ duk_hobject_object_is_sealed_frozen_helper(thr, h, is_frozen /*is_frozen*/));
}
return 1;
}
#endif /* DUK_USE_OBJECT_BUILTIN */
#if defined(DUK_USE_OBJECT_BUILTIN)
-DUK_INTERNAL duk_ret_t duk_bi_object_prototype_to_locale_string(duk_context *ctx) {
- DUK_ASSERT_TOP(ctx, 0);
- (void) duk_push_this_coercible_to_object(ctx);
- duk_get_prop_stridx_short(ctx, 0, DUK_STRIDX_TO_STRING);
+DUK_INTERNAL duk_ret_t duk_bi_object_prototype_to_locale_string(duk_hthread *thr) {
+ DUK_ASSERT_TOP(thr, 0);
+ (void) duk_push_this_coercible_to_object(thr);
+ duk_get_prop_stridx_short(thr, 0, DUK_STRIDX_TO_STRING);
#if 0 /* This is mentioned explicitly in the E5.1 spec, but duk_call_method() checks for it in practice. */
- duk_require_callable(ctx, 1);
+ duk_require_callable(thr, 1);
#endif
- duk_dup_0(ctx); /* -> [ O toString O ] */
- duk_call_method(ctx, 0); /* XXX: call method tail call? */
+ duk_dup_0(thr); /* -> [ O toString O ] */
+ duk_call_method(thr, 0); /* XXX: call method tail call? */
return 1;
}
#endif /* DUK_USE_OBJECT_BUILTIN */
#if defined(DUK_USE_OBJECT_BUILTIN)
-DUK_INTERNAL duk_ret_t duk_bi_object_prototype_value_of(duk_context *ctx) {
+DUK_INTERNAL duk_ret_t duk_bi_object_prototype_value_of(duk_hthread *thr) {
/* For lightfuncs and plain buffers, returns Object() coerced. */
- (void) duk_push_this_coercible_to_object(ctx);
+ (void) duk_push_this_coercible_to_object(thr);
return 1;
}
#endif /* DUK_USE_OBJECT_BUILTIN */
#if defined(DUK_USE_OBJECT_BUILTIN)
-DUK_INTERNAL duk_ret_t duk_bi_object_prototype_is_prototype_of(duk_context *ctx) {
- duk_hthread *thr = (duk_hthread *) ctx;
+DUK_INTERNAL duk_ret_t duk_bi_object_prototype_is_prototype_of(duk_hthread *thr) {
duk_hobject *h_v;
duk_hobject *h_obj;
- DUK_ASSERT_TOP(ctx, 1);
+ DUK_ASSERT_TOP(thr, 1);
- h_v = duk_get_hobject(ctx, 0);
+ h_v = duk_get_hobject(thr, 0);
if (!h_v) {
- duk_push_false(ctx); /* XXX: tail call: return duk_push_false(ctx) */
+ duk_push_false(thr); /* XXX: tail call: return duk_push_false(thr) */
return 1;
}
- h_obj = duk_push_this_coercible_to_object(ctx);
+ h_obj = duk_push_this_coercible_to_object(thr);
DUK_ASSERT(h_obj != NULL);
/* E5.1 Section 15.2.4.6, step 3.a, lookup proto once before compare.
* Prototype loops should cause an error to be thrown.
*/
- duk_push_boolean(ctx, duk_hobject_prototype_chain_contains(thr, DUK_HOBJECT_GET_PROTOTYPE(thr->heap, h_v), h_obj, 0 /*ignore_loop*/));
+ duk_push_boolean(thr, duk_hobject_prototype_chain_contains(thr, DUK_HOBJECT_GET_PROTOTYPE(thr->heap, h_v), h_obj, 0 /*ignore_loop*/));
return 1;
}
#endif /* DUK_USE_OBJECT_BUILTIN */
#if defined(DUK_USE_OBJECT_BUILTIN)
-DUK_INTERNAL duk_ret_t duk_bi_object_prototype_has_own_property(duk_context *ctx) {
- return duk_hobject_object_ownprop_helper(ctx, 0 /*required_desc_flags*/);
+DUK_INTERNAL duk_ret_t duk_bi_object_prototype_has_own_property(duk_hthread *thr) {
+ return (duk_ret_t) duk_hobject_object_ownprop_helper(thr, 0 /*required_desc_flags*/);
}
#endif /* DUK_USE_OBJECT_BUILTIN */
#if defined(DUK_USE_OBJECT_BUILTIN)
-DUK_INTERNAL duk_ret_t duk_bi_object_prototype_property_is_enumerable(duk_context *ctx) {
- return duk_hobject_object_ownprop_helper(ctx, DUK_PROPDESC_FLAG_ENUMERABLE /*required_desc_flags*/);
+DUK_INTERNAL duk_ret_t duk_bi_object_prototype_property_is_enumerable(duk_hthread *thr) {
+ return (duk_ret_t) duk_hobject_object_ownprop_helper(thr, DUK_PROPDESC_FLAG_ENUMERABLE /*required_desc_flags*/);
}
#endif /* DUK_USE_OBJECT_BUILTIN */
@@ -36420,31 +37650,30 @@ DUK_INTERNAL duk_ret_t duk_bi_object_prototype_property_is_enumerable(duk_contex
*
* http://www.ecma-international.org/ecma-262/6.0/index.html#sec-get-object.prototype.__proto__
*/
-DUK_INTERNAL duk_ret_t duk_bi_object_getprototype_shared(duk_context *ctx) {
+DUK_INTERNAL duk_ret_t duk_bi_object_getprototype_shared(duk_hthread *thr) {
/*
* magic = 0: __proto__ getter
* magic = 1: Object.getPrototypeOf()
* magic = 2: Reflect.getPrototypeOf()
*/
- duk_hthread *thr = (duk_hthread *) ctx;
duk_hobject *h;
duk_hobject *proto;
duk_tval *tv;
duk_int_t magic;
- magic = duk_get_current_magic(ctx);
+ magic = duk_get_current_magic(thr);
if (magic == 0) {
- DUK_ASSERT_TOP(ctx, 0);
- duk_push_this_coercible_to_object(ctx);
+ DUK_ASSERT_TOP(thr, 0);
+ duk_push_this_coercible_to_object(thr);
}
- DUK_ASSERT(duk_get_top(ctx) >= 1);
+ DUK_ASSERT(duk_get_top(thr) >= 1);
if (magic < 2) {
/* ES2015 Section 19.1.2.9, step 1 */
- duk_to_object(ctx, 0);
+ duk_to_object(thr, 0);
}
- tv = DUK_GET_TVAL_POSIDX(ctx, 0);
+ tv = DUK_GET_TVAL_POSIDX(thr, 0);
switch (DUK_TVAL_GET_TAG(tv)) {
case DUK_TAG_BUFFER:
@@ -36464,9 +37693,9 @@ DUK_INTERNAL duk_ret_t duk_bi_object_getprototype_shared(duk_context *ctx) {
DUK_DCERROR_TYPE_INVALID_ARGS(thr);
}
if (proto != NULL) {
- duk_push_hobject(ctx, proto);
+ duk_push_hobject(thr, proto);
} else {
- duk_push_null(ctx);
+ duk_push_null(thr);
}
return 1;
}
@@ -36479,14 +37708,13 @@ DUK_INTERNAL duk_ret_t duk_bi_object_getprototype_shared(duk_context *ctx) {
* http://www.ecma-international.org/ecma-262/6.0/index.html#sec-get-object.prototype.__proto__
* http://www.ecma-international.org/ecma-262/6.0/index.html#sec-object.setprototypeof
*/
-DUK_INTERNAL duk_ret_t duk_bi_object_setprototype_shared(duk_context *ctx) {
+DUK_INTERNAL duk_ret_t duk_bi_object_setprototype_shared(duk_hthread *thr) {
/*
* magic = 0: __proto__ setter
* magic = 1: Object.setPrototypeOf()
* magic = 2: Reflect.setPrototypeOf()
*/
- duk_hthread *thr = (duk_hthread *) ctx;
duk_hobject *h_obj;
duk_hobject *h_new_proto;
duk_hobject *h_curr;
@@ -36495,11 +37723,11 @@ DUK_INTERNAL duk_ret_t duk_bi_object_setprototype_shared(duk_context *ctx) {
duk_int_t magic;
/* Preliminaries for __proto__ and setPrototypeOf (E6 19.1.2.18 steps 1-4). */
- magic = duk_get_current_magic(ctx);
+ magic = duk_get_current_magic(thr);
if (magic == 0) {
- duk_push_this_check_object_coercible(ctx);
- duk_insert(ctx, 0);
- if (!duk_check_type_mask(ctx, 1, DUK_TYPE_MASK_NULL | DUK_TYPE_MASK_OBJECT)) {
+ duk_push_this_check_object_coercible(thr);
+ duk_insert(thr, 0);
+ if (!duk_check_type_mask(thr, 1, DUK_TYPE_MASK_NULL | DUK_TYPE_MASK_OBJECT)) {
return 0;
}
@@ -36509,19 +37737,19 @@ DUK_INTERNAL duk_ret_t duk_bi_object_setprototype_shared(duk_context *ctx) {
ret_success = 0;
} else {
if (magic == 1) {
- duk_require_object_coercible(ctx, 0);
+ duk_require_object_coercible(thr, 0);
} else {
- duk_require_hobject_accept_mask(ctx, 0,
+ duk_require_hobject_accept_mask(thr, 0,
DUK_TYPE_MASK_LIGHTFUNC |
DUK_TYPE_MASK_BUFFER);
}
- duk_require_type_mask(ctx, 1, DUK_TYPE_MASK_NULL | DUK_TYPE_MASK_OBJECT);
+ duk_require_type_mask(thr, 1, DUK_TYPE_MASK_NULL | DUK_TYPE_MASK_OBJECT);
}
- h_new_proto = duk_get_hobject(ctx, 1);
+ h_new_proto = duk_get_hobject(thr, 1);
/* h_new_proto may be NULL */
- mask = duk_get_type_mask(ctx, 0);
+ mask = duk_get_type_mask(thr, 0);
if (mask & (DUK_TYPE_MASK_LIGHTFUNC | DUK_TYPE_MASK_BUFFER)) {
duk_hobject *curr_proto;
curr_proto = thr->builtins[(mask & DUK_TYPE_MASK_LIGHTFUNC) ?
@@ -36532,7 +37760,7 @@ DUK_INTERNAL duk_ret_t duk_bi_object_setprototype_shared(duk_context *ctx) {
}
goto fail_nonextensible;
}
- h_obj = duk_get_hobject(ctx, 0);
+ h_obj = duk_get_hobject(thr, 0);
if (h_obj == NULL) {
goto skip;
}
@@ -36557,9 +37785,9 @@ DUK_INTERNAL duk_ret_t duk_bi_object_setprototype_shared(duk_context *ctx) {
/* fall thru */
skip:
- duk_set_top(ctx, 1);
+ duk_set_top(thr, 1);
if (magic == 2) {
- duk_push_true(ctx);
+ duk_push_true(thr);
}
return ret_success;
@@ -36568,14 +37796,14 @@ DUK_INTERNAL duk_ret_t duk_bi_object_setprototype_shared(duk_context *ctx) {
if (magic != 2) {
DUK_DCERROR_TYPE_INVALID_ARGS(thr);
} else {
- duk_push_false(ctx);
+ duk_push_false(thr);
return 1;
}
}
#endif /* DUK_USE_OBJECT_BUILTIN || DUK_USE_REFLECT_BUILTIN */
#if defined(DUK_USE_OBJECT_BUILTIN) || defined(DUK_USE_REFLECT_BUILTIN)
-DUK_INTERNAL duk_ret_t duk_bi_object_constructor_define_property(duk_context *ctx) {
+DUK_INTERNAL duk_ret_t duk_bi_object_constructor_define_property(duk_hthread *thr) {
/*
* magic = 0: Object.defineProperty()
* magic = 1: Reflect.defineProperty()
@@ -36587,34 +37815,34 @@ DUK_INTERNAL duk_ret_t duk_bi_object_constructor_define_property(duk_context *ct
duk_hobject *set;
duk_idx_t idx_value;
duk_uint_t defprop_flags;
- duk_int_t magic;
+ duk_small_uint_t magic;
duk_bool_t throw_flag;
duk_bool_t ret;
- DUK_ASSERT(ctx != NULL);
+ DUK_ASSERT(thr != NULL);
DUK_DDD(DUK_DDDPRINT("Object.defineProperty(): ctx=%p obj=%!T key=%!T desc=%!T",
- (void *) ctx,
- (duk_tval *) duk_get_tval(ctx, 0),
- (duk_tval *) duk_get_tval(ctx, 1),
- (duk_tval *) duk_get_tval(ctx, 2)));
+ (void *) thr,
+ (duk_tval *) duk_get_tval(thr, 0),
+ (duk_tval *) duk_get_tval(thr, 1),
+ (duk_tval *) duk_get_tval(thr, 2)));
/* [ obj key desc ] */
- magic = duk_get_current_magic(ctx);
+ magic = (duk_small_uint_t) duk_get_current_magic(thr);
/* Lightfuncs are currently supported by coercing to a temporary
* Function object; changes will be allowed (the coerced value is
* extensible) but will be lost. Same for plain buffers.
*/
- obj = duk_require_hobject_promote_mask(ctx, 0, DUK_TYPE_MASK_LIGHTFUNC | DUK_TYPE_MASK_BUFFER);
+ obj = duk_require_hobject_promote_mask(thr, 0, DUK_TYPE_MASK_LIGHTFUNC | DUK_TYPE_MASK_BUFFER);
DUK_ASSERT(obj != NULL);
- key = duk_to_property_key_hstring(ctx, 1);
- (void) duk_require_hobject(ctx, 2);
+ key = duk_to_property_key_hstring(thr, 1);
+ (void) duk_require_hobject(thr, 2);
DUK_ASSERT(obj != NULL);
DUK_ASSERT(key != NULL);
- DUK_ASSERT(duk_get_hobject(ctx, 2) != NULL);
+ DUK_ASSERT(duk_get_hobject(thr, 2) != NULL);
/*
* Validate and convert argument property descriptor (an Ecmascript
@@ -36624,7 +37852,7 @@ DUK_INTERNAL duk_ret_t duk_bi_object_constructor_define_property(duk_context *ct
* Lightfunc set/get values are coerced to full Functions.
*/
- duk_hobject_prepare_property_descriptor(ctx,
+ duk_hobject_prepare_property_descriptor(thr,
2 /*idx_desc*/,
&defprop_flags,
&idx_value,
@@ -36635,9 +37863,9 @@ DUK_INTERNAL duk_ret_t duk_bi_object_constructor_define_property(duk_context *ct
* Use Object.defineProperty() helper for the actual operation.
*/
- DUK_ASSERT(magic == 0 || magic == 1);
- throw_flag = magic ^ 1;
- ret = duk_hobject_define_property_helper(ctx,
+ DUK_ASSERT(magic == 0U || magic == 1U);
+ throw_flag = magic ^ 1U;
+ ret = duk_hobject_define_property_helper(thr,
defprop_flags,
obj,
key,
@@ -36650,35 +37878,35 @@ DUK_INTERNAL duk_ret_t duk_bi_object_constructor_define_property(duk_context *ct
* they're popped automatically.
*/
- if (magic == 0) {
+ if (magic == 0U) {
/* Object.defineProperty(): return target object. */
- duk_push_hobject(ctx, obj);
+ duk_push_hobject(thr, obj);
} else {
/* Reflect.defineProperty(): return success/fail. */
- duk_push_boolean(ctx, ret);
+ duk_push_boolean(thr, ret);
}
return 1;
}
#endif /* DUK_USE_OBJECT_BUILTIN || DUK_USE_REFLECT_BUILTIN */
#if defined(DUK_USE_OBJECT_BUILTIN) || defined(DUK_USE_REFLECT_BUILTIN)
-DUK_INTERNAL duk_ret_t duk_bi_object_constructor_get_own_property_descriptor(duk_context *ctx) {
- DUK_ASSERT_TOP(ctx, 2);
+DUK_INTERNAL duk_ret_t duk_bi_object_constructor_get_own_property_descriptor(duk_hthread *thr) {
+ DUK_ASSERT_TOP(thr, 2);
/* ES2015 Section 19.1.2.6, step 1 */
- if (duk_get_current_magic(ctx) == 0) {
- duk_to_object(ctx, 0);
+ if (duk_get_current_magic(thr) == 0) {
+ duk_to_object(thr, 0);
}
/* [ obj key ] */
- duk_hobject_object_get_own_property_descriptor(ctx, -2);
+ duk_hobject_object_get_own_property_descriptor(thr, -2);
return 1;
}
#endif /* DUK_USE_OBJECT_BUILTIN || DUK_USE_REFLECT_BUILTIN */
#if defined(DUK_USE_OBJECT_BUILTIN) || defined(DUK_USE_REFLECT_BUILTIN)
-DUK_INTERNAL duk_ret_t duk_bi_object_constructor_is_extensible(duk_context *ctx) {
+DUK_INTERNAL duk_ret_t duk_bi_object_constructor_is_extensible(duk_hthread *thr) {
/*
* magic = 0: Object.isExtensible()
* magic = 1: Reflect.isExtensible()
@@ -36686,16 +37914,16 @@ DUK_INTERNAL duk_ret_t duk_bi_object_constructor_is_extensible(duk_context *ctx)
duk_hobject *h;
- if (duk_get_current_magic(ctx) == 0) {
- h = duk_get_hobject(ctx, 0);
+ if (duk_get_current_magic(thr) == 0) {
+ h = duk_get_hobject(thr, 0);
} else {
/* Reflect.isExtensible(): throw if non-object, but we accept lightfuncs
* and plain buffers here because they pretend to be objects.
*/
- h = duk_require_hobject_accept_mask(ctx, 0, DUK_TYPE_MASK_LIGHTFUNC | DUK_TYPE_MASK_BUFFER);
+ h = duk_require_hobject_accept_mask(thr, 0, DUK_TYPE_MASK_LIGHTFUNC | DUK_TYPE_MASK_BUFFER);
}
- duk_push_boolean(ctx, (h != NULL) && DUK_HOBJECT_HAS_EXTENSIBLE(h));
+ duk_push_boolean(thr, (h != NULL) && DUK_HOBJECT_HAS_EXTENSIBLE(h));
return 1;
}
#endif /* DUK_USE_OBJECT_BUILTIN || DUK_USE_REFLECT_BUILTIN */
@@ -36731,8 +37959,7 @@ DUK_LOCAL const duk_small_uint_t duk__object_keys_enum_flags[4] = {
DUK_ENUM_NO_PROXY_BEHAVIOR
};
-DUK_INTERNAL duk_ret_t duk_bi_object_constructor_keys_shared(duk_context *ctx) {
- duk_hthread *thr = (duk_hthread *) ctx;
+DUK_INTERNAL duk_ret_t duk_bi_object_constructor_keys_shared(duk_hthread *thr) {
duk_hobject *obj;
#if defined(DUK_USE_ES6_PROXY)
duk_hobject *h_proxy_target;
@@ -36742,18 +37969,17 @@ DUK_INTERNAL duk_ret_t duk_bi_object_constructor_keys_shared(duk_context *ctx) {
duk_small_uint_t enum_flags;
duk_int_t magic;
- DUK_ASSERT_TOP(ctx, 1);
- DUK_UNREF(thr);
+ DUK_ASSERT_TOP(thr, 1);
- magic = duk_get_current_magic(ctx);
+ magic = duk_get_current_magic(thr);
if (magic == 3) {
/* ES2015 Section 26.1.11 requires a TypeError for non-objects. Lightfuncs
* and plain buffers pretend to be objects, so accept those too.
*/
- obj = duk_require_hobject_promote_mask(ctx, 0, DUK_TYPE_MASK_LIGHTFUNC | DUK_TYPE_MASK_BUFFER);
+ obj = duk_require_hobject_promote_mask(thr, 0, DUK_TYPE_MASK_LIGHTFUNC | DUK_TYPE_MASK_BUFFER);
} else {
/* ES2015: ToObject coerce. */
- obj = duk_to_hobject(ctx, 0);
+ obj = duk_to_hobject(thr, 0);
}
DUK_ASSERT(obj != NULL);
DUK_UNREF(obj);
@@ -36762,64 +37988,62 @@ DUK_INTERNAL duk_ret_t duk_bi_object_constructor_keys_shared(duk_context *ctx) {
#if defined(DUK_USE_ES6_PROXY)
/* XXX: better sharing of code between proxy target call sites */
- if (DUK_LIKELY(!duk_hobject_proxy_check(thr,
- obj,
+ if (DUK_LIKELY(!duk_hobject_proxy_check(obj,
&h_proxy_target,
&h_proxy_handler))) {
goto skip_proxy;
}
- duk_push_hobject(ctx, h_proxy_handler);
- if (!duk_get_prop_stridx_short(ctx, -1, DUK_STRIDX_OWN_KEYS)) {
+ duk_push_hobject(thr, h_proxy_handler);
+ if (!duk_get_prop_stridx_short(thr, -1, DUK_STRIDX_OWN_KEYS)) {
/* Careful with reachability here: don't pop 'obj' before pushing
* proxy target.
*/
DUK_DDD(DUK_DDDPRINT("no ownKeys trap, get keys of target instead"));
- duk_pop_2(ctx);
- duk_push_hobject(ctx, h_proxy_target);
- duk_replace(ctx, 0);
- DUK_ASSERT_TOP(ctx, 1);
+ duk_pop_2(thr);
+ duk_push_hobject(thr, h_proxy_target);
+ duk_replace(thr, 0);
+ DUK_ASSERT_TOP(thr, 1);
goto skip_proxy;
}
/* [ obj handler trap ] */
- duk_insert(ctx, -2);
- duk_push_hobject(ctx, h_proxy_target); /* -> [ obj trap handler target ] */
- duk_call_method(ctx, 1 /*nargs*/); /* -> [ obj trap_result ] */
- h_trap_result = duk_require_hobject(ctx, -1);
+ duk_insert(thr, -2);
+ duk_push_hobject(thr, h_proxy_target); /* -> [ obj trap handler target ] */
+ duk_call_method(thr, 1 /*nargs*/); /* -> [ obj trap_result ] */
+ h_trap_result = duk_require_hobject(thr, -1);
DUK_UNREF(h_trap_result);
- magic = duk_get_current_magic(ctx);
+ magic = duk_get_current_magic(thr);
DUK_ASSERT(magic >= 0 && magic < (duk_int_t) (sizeof(duk__object_keys_enum_flags) / sizeof(duk_small_uint_t)));
enum_flags = duk__object_keys_enum_flags[magic];
- duk_proxy_ownkeys_postprocess(ctx, h_proxy_target, enum_flags);
+ duk_proxy_ownkeys_postprocess(thr, h_proxy_target, enum_flags);
return 1;
skip_proxy:
#endif /* DUK_USE_ES6_PROXY */
- DUK_ASSERT_TOP(ctx, 1);
- magic = duk_get_current_magic(ctx);
+ DUK_ASSERT_TOP(thr, 1);
+ magic = duk_get_current_magic(thr);
DUK_ASSERT(magic >= 0 && magic < (duk_int_t) (sizeof(duk__object_keys_enum_flags) / sizeof(duk_small_uint_t)));
enum_flags = duk__object_keys_enum_flags[magic];
- return duk_hobject_get_enumerated_keys(ctx, enum_flags);
+ return duk_hobject_get_enumerated_keys(thr, enum_flags);
}
#endif /* DUK_USE_OBJECT_BUILTIN || DUK_USE_REFLECT_BUILTIN */
#if defined(DUK_USE_OBJECT_BUILTIN) || defined(DUK_USE_REFLECT_BUILTIN)
-DUK_INTERNAL duk_ret_t duk_bi_object_constructor_prevent_extensions(duk_context *ctx) {
+DUK_INTERNAL duk_ret_t duk_bi_object_constructor_prevent_extensions(duk_hthread *thr) {
/*
* magic = 0: Object.preventExtensions()
* magic = 1: Reflect.preventExtensions()
*/
- duk_hthread *thr = (duk_hthread *) ctx;
duk_hobject *h;
duk_uint_t mask;
duk_int_t magic;
- magic = duk_get_current_magic(ctx);
+ magic = duk_get_current_magic(thr);
/* Silent success for lightfuncs and plain buffers always. */
mask = DUK_TYPE_MASK_LIGHTFUNC | DUK_TYPE_MASK_BUFFER;
@@ -36834,11 +38058,11 @@ DUK_INTERNAL duk_ret_t duk_bi_object_constructor_prevent_extensions(duk_context
DUK_TYPE_MASK_POINTER;
}
- if (duk_check_type_mask(ctx, 0, mask)) {
+ if (duk_check_type_mask(thr, 0, mask)) {
/* Not an object, already non-extensible so always success. */
goto done;
}
- h = duk_require_hobject(ctx, 0);
+ h = duk_require_hobject(thr, 0);
DUK_ASSERT(h != NULL);
DUK_HOBJECT_CLEAR_EXTENSIBLE(h);
@@ -36850,11 +38074,94 @@ DUK_INTERNAL duk_ret_t duk_bi_object_constructor_prevent_extensions(duk_context
done:
if (magic == 1) {
- duk_push_true(ctx);
+ duk_push_true(thr);
}
return 1;
}
#endif /* DUK_USE_OBJECT_BUILTIN || DUK_USE_REFLECT_BUILTIN */
+
+/*
+ * __defineGetter__, __defineSetter__, __lookupGetter__, __lookupSetter__
+ */
+
+#if defined(DUK_USE_ES8)
+DUK_INTERNAL duk_ret_t duk_bi_object_prototype_defineaccessor(duk_hthread *thr) {
+ duk_push_this(thr);
+ duk_insert(thr, 0);
+ duk_to_object(thr, 0);
+ duk_require_callable(thr, 2);
+
+ /* [ ToObject(this) key getter/setter ] */
+
+ /* ToPropertyKey() coercion is not needed, duk_def_prop() does it. */
+ duk_def_prop(thr, 0, DUK_DEFPROP_SET_ENUMERABLE |
+ DUK_DEFPROP_SET_CONFIGURABLE |
+ (duk_get_current_magic(thr) ? DUK_DEFPROP_HAVE_SETTER : DUK_DEFPROP_HAVE_GETTER));
+ return 0;
+}
+DUK_INTERNAL duk_ret_t duk_bi_object_prototype_lookupaccessor(duk_hthread *thr) {
+ duk_uint_t sanity;
+
+ duk_push_this(thr);
+ duk_to_object(thr, -1);
+
+ /* XXX: Prototype walk (with sanity) should be a core property
+ * operation, could add a flag to e.g. duk_get_prop_desc().
+ */
+
+ /* ToPropertyKey() coercion is not needed, duk_get_prop_desc() does it. */
+ sanity = DUK_HOBJECT_PROTOTYPE_CHAIN_SANITY;
+ while (!duk_is_undefined(thr, -1)) {
+ /* [ key obj ] */
+ duk_dup(thr, 0);
+ duk_get_prop_desc(thr, 1, 0 /*flags*/);
+ if (!duk_is_undefined(thr, -1)) {
+ duk_get_prop_stridx(thr, -1, (duk_get_current_magic(thr) != 0 ? DUK_STRIDX_SET : DUK_STRIDX_GET));
+ return 1;
+ }
+ duk_pop(thr);
+
+ if (DUK_UNLIKELY(sanity-- == 0)) {
+ DUK_ERROR_RANGE(thr, DUK_STR_PROTOTYPE_CHAIN_LIMIT);
+ }
+
+ duk_get_prototype(thr, -1);
+ duk_remove(thr, -2);
+ }
+ return 1;
+}
+#endif /* DUK_USE_ES8 */
+/*
+ * High resolution time API (performance.now() et al)
+ *
+ * API specification: https://encoding.spec.whatwg.org/#ap://www.w3.org/TR/hr-time/
+ */
+
+/* #include duk_internal.h -> already included */
+
+#if defined(DUK_USE_PERFORMANCE_BUILTIN)
+DUK_INTERNAL duk_ret_t duk_bi_performance_now(duk_hthread *thr) {
+ /* From API spec:
+ * The DOMHighResTimeStamp type is used to store a time value in
+ * milliseconds, measured relative from the time origin, global
+ * monotonic clock, or a time value that represents a duration
+ * between two DOMHighResTimeStamp's.
+ */
+ duk_push_number(thr, duk_time_get_monotonic_time(thr));
+ return 1;
+}
+
+#if 0 /* Missing until semantics decided. */
+DUK_INTERNAL duk_ret_t duk_bi_performance_timeorigin_getter(duk_hthread *thr) {
+ /* No decision yet how to handle timeOrigins, e.g. should one be
+ * initialized per heap, or per global object set. See
+ * https://www.w3.org/TR/hr-time/#time-origin.
+ */
+ duk_push_uint(thr, 0);
+ return 1;
+}
+#endif /* 0 */
+#endif /* DUK_USE_PERFORMANCE_BUILTIN */
/*
* Pointer built-ins
*/
@@ -36865,29 +38172,29 @@ DUK_INTERNAL duk_ret_t duk_bi_object_constructor_prevent_extensions(duk_context
* Constructor
*/
-DUK_INTERNAL duk_ret_t duk_bi_pointer_constructor(duk_context *ctx) {
+DUK_INTERNAL duk_ret_t duk_bi_pointer_constructor(duk_hthread *thr) {
/* XXX: this behavior is quite useless now; it would be nice to be able
* to create pointer values from e.g. numbers or strings. Numbers are
* problematic on 64-bit platforms though. Hex encoded strings?
*/
- if (duk_get_top(ctx) == 0) {
- duk_push_pointer(ctx, NULL);
+ if (duk_get_top(thr) == 0) {
+ duk_push_pointer(thr, NULL);
} else {
- duk_to_pointer(ctx, 0);
+ duk_to_pointer(thr, 0);
}
- DUK_ASSERT(duk_is_pointer(ctx, 0));
- duk_set_top(ctx, 1);
+ DUK_ASSERT(duk_is_pointer(thr, 0));
+ duk_set_top(thr, 1);
- if (duk_is_constructor_call(ctx)) {
- (void) duk_push_object_helper(ctx,
+ if (duk_is_constructor_call(thr)) {
+ (void) duk_push_object_helper(thr,
DUK_HOBJECT_FLAG_EXTENSIBLE |
DUK_HOBJECT_FLAG_FASTREFS |
DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_POINTER),
DUK_BIDX_POINTER_PROTOTYPE);
/* Pointer object internal value is immutable */
- duk_dup_0(ctx);
- duk_xdef_prop_stridx_short(ctx, -2, DUK_STRIDX_INT_VALUE, DUK_PROPDESC_FLAGS_NONE);
+ duk_dup_0(thr);
+ duk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_INT_VALUE, DUK_PROPDESC_FLAGS_NONE);
}
/* Note: unbalanced stack on purpose */
@@ -36898,12 +38205,12 @@ DUK_INTERNAL duk_ret_t duk_bi_pointer_constructor(duk_context *ctx) {
* toString(), valueOf()
*/
-DUK_INTERNAL duk_ret_t duk_bi_pointer_prototype_tostring_shared(duk_context *ctx) {
+DUK_INTERNAL duk_ret_t duk_bi_pointer_prototype_tostring_shared(duk_hthread *thr) {
duk_tval *tv;
- duk_small_int_t to_string = duk_get_current_magic(ctx);
+ duk_small_int_t to_string = duk_get_current_magic(thr);
- duk_push_this(ctx);
- tv = duk_require_tval(ctx, -1);
+ duk_push_this(thr);
+ tv = duk_require_tval(thr, -1);
DUK_ASSERT(tv != NULL);
if (DUK_TVAL_IS_POINTER(tv)) {
@@ -36917,19 +38224,63 @@ DUK_INTERNAL duk_ret_t duk_bi_pointer_prototype_tostring_shared(duk_context *ctx
goto type_error;
}
- duk_get_prop_stridx_short(ctx, -1, DUK_STRIDX_INT_VALUE);
+ duk_get_prop_stridx_short(thr, -1, DUK_STRIDX_INT_VALUE);
} else {
goto type_error;
}
if (to_string) {
- duk_to_string(ctx, -1);
+ duk_to_string(thr, -1);
}
return 1;
type_error:
- DUK_DCERROR_TYPE_INVALID_ARGS((duk_hthread *) ctx);
+ DUK_DCERROR_TYPE_INVALID_ARGS(thr);
+}
+/*
+ * Promise built-in
+ */
+
+/* #include duk_internal.h -> already included */
+
+#if defined(DUK_USE_PROMISE_BUILTIN)
+
+DUK_INTERNAL duk_ret_t duk_bi_promise_constructor(duk_hthread *thr) {
+ DUK_ERROR_TYPE(thr, "unimplemented");
+ return 0;
+}
+
+DUK_INTERNAL duk_ret_t duk_bi_promise_all(duk_hthread *thr) {
+ DUK_ERROR_TYPE(thr, "unimplemented");
+ return 0;
+}
+
+DUK_INTERNAL duk_ret_t duk_bi_promise_race(duk_hthread *thr) {
+ DUK_ERROR_TYPE(thr, "unimplemented");
+ return 0;
+}
+
+DUK_INTERNAL duk_ret_t duk_bi_promise_reject(duk_hthread *thr) {
+ DUK_ERROR_TYPE(thr, "unimplemented");
+ return 0;
+}
+
+DUK_INTERNAL duk_ret_t duk_bi_promise_resolve(duk_hthread *thr) {
+ DUK_ERROR_TYPE(thr, "unimplemented");
+ return 0;
+}
+
+DUK_INTERNAL duk_ret_t duk_bi_promise_catch(duk_hthread *thr) {
+ DUK_ERROR_TYPE(thr, "unimplemented");
+ return 0;
}
+
+DUK_INTERNAL duk_ret_t duk_bi_promise_then(duk_hthread *thr) {
+ DUK_ERROR_TYPE(thr, "unimplemented");
+ return 0;
+}
+
+#endif /* DUK_USE_PROMISE_BUILTIN */
/*
* Proxy built-in (ES2015)
*/
@@ -36941,24 +38292,23 @@ DUK_INTERNAL duk_ret_t duk_bi_pointer_prototype_tostring_shared(duk_context *ctx
* array of valid result keys (strings or symbols). TypeError for invalid
* values. Flags are shared with duk_enum().
*/
-DUK_INTERNAL void duk_proxy_ownkeys_postprocess(duk_context *ctx, duk_hobject *h_proxy_target, duk_uint_t flags) {
- duk_hthread *thr = (duk_hthread *) ctx;
+DUK_INTERNAL void duk_proxy_ownkeys_postprocess(duk_hthread *thr, duk_hobject *h_proxy_target, duk_uint_t flags) {
duk_uarridx_t i, len, idx;
duk_propdesc desc;
- DUK_ASSERT_CTX_VALID(ctx);
+ DUK_ASSERT_CTX_VALID(thr);
DUK_ASSERT(h_proxy_target != NULL);
- len = (duk_uarridx_t) duk_get_length(ctx, -1);
+ len = (duk_uarridx_t) duk_get_length(thr, -1);
idx = 0;
- duk_push_array(ctx);
+ duk_push_array(thr);
/* XXX: preallocated dense array, fill in directly */
for (i = 0; i < len; i++) {
duk_hstring *h;
/* [ obj trap_result res_arr ] */
- (void) duk_get_prop_index(ctx, -2, i);
- h = duk_get_hstring(ctx, -1);
+ (void) duk_get_prop_index(thr, -2, i);
+ h = duk_get_hstring(thr, -1);
if (h == NULL) {
DUK_ERROR_TYPE_INVALID_TRAP_RESULT(thr);
}
@@ -36968,38 +38318,38 @@ DUK_INTERNAL void duk_proxy_ownkeys_postprocess(duk_context *ctx, duk_hobject *h
* so check enumerability always from target object
* descriptor.
*/
- if (duk_hobject_get_own_propdesc(thr, h_proxy_target, duk_known_hstring(ctx, -1), &desc, 0 /*flags*/)) {
+ if (duk_hobject_get_own_propdesc(thr, h_proxy_target, duk_known_hstring(thr, -1), &desc, 0 /*flags*/)) {
if ((desc.flags & DUK_PROPDESC_FLAG_ENUMERABLE) == 0) {
- DUK_DDD(DUK_DDDPRINT("ignore non-enumerable property: %!T", duk_get_tval(ctx, -1)));
+ DUK_DDD(DUK_DDDPRINT("ignore non-enumerable property: %!T", duk_get_tval(thr, -1)));
goto skip_key;
}
} else {
- DUK_DDD(DUK_DDDPRINT("ignore non-existent property: %!T", duk_get_tval(ctx, -1)));
+ DUK_DDD(DUK_DDDPRINT("ignore non-existent property: %!T", duk_get_tval(thr, -1)));
goto skip_key;
}
}
if (DUK_UNLIKELY(DUK_HSTRING_HAS_SYMBOL(h))) {
if (!(flags & DUK_ENUM_INCLUDE_SYMBOLS)) {
- DUK_DDD(DUK_DDDPRINT("ignore symbol property: %!T", duk_get_tval(ctx, -1)));
+ DUK_DDD(DUK_DDDPRINT("ignore symbol property: %!T", duk_get_tval(thr, -1)));
goto skip_key;
}
if (DUK_HSTRING_HAS_HIDDEN(h) && !(flags & DUK_ENUM_INCLUDE_HIDDEN)) {
- DUK_DDD(DUK_DDDPRINT("ignore hidden symbol property: %!T", duk_get_tval(ctx, -1)));
+ DUK_DDD(DUK_DDDPRINT("ignore hidden symbol property: %!T", duk_get_tval(thr, -1)));
goto skip_key;
}
} else {
if (flags & DUK_ENUM_EXCLUDE_STRINGS) {
- DUK_DDD(DUK_DDDPRINT("ignore string property: %!T", duk_get_tval(ctx, -1)));
+ DUK_DDD(DUK_DDDPRINT("ignore string property: %!T", duk_get_tval(thr, -1)));
goto skip_key;
}
}
/* [ obj trap_result res_arr propname ] */
- duk_put_prop_index(ctx, -2, idx++);
+ duk_put_prop_index(thr, -2, idx++);
continue;
skip_key:
- duk_pop(ctx);
+ duk_pop(thr);
continue;
}
@@ -37018,66 +38368,12 @@ DUK_INTERNAL void duk_proxy_ownkeys_postprocess(duk_context *ctx, duk_hobject *h
#endif /* DUK_USE_ES6_PROXY */
#if defined(DUK_USE_ES6_PROXY)
-DUK_INTERNAL duk_ret_t duk_bi_proxy_constructor(duk_context *ctx) {
- duk_hobject *h_target;
- duk_hobject *h_handler;
-
- duk_require_constructor_call(ctx);
+DUK_INTERNAL duk_ret_t duk_bi_proxy_constructor(duk_hthread *thr) {
+ DUK_ASSERT_TOP(thr, 2); /* [ target handler ] */
- /* Reject a proxy object as the target because it would need
- * special handler in property lookups. (ES2015 has no such restriction)
- */
- h_target = duk_require_hobject_promote_mask(ctx, 0, DUK_TYPE_MASK_LIGHTFUNC | DUK_TYPE_MASK_BUFFER);
- DUK_ASSERT(h_target != NULL);
- if (DUK_HOBJECT_HAS_EXOTIC_PROXYOBJ(h_target)) {
- goto fail_args;
- }
-
- /* Reject a proxy object as the handler because it would cause
- * potentially unbounded recursion. (ES2015 has no such restriction)
- *
- * There's little practical reason to use a lightfunc or a plain
- * buffer as the handler table: one could only provide traps via
- * their prototype objects (Function.prototype and ArrayBuffer.prototype).
- * Even so, as lightfuncs and plain buffers mimic their object
- * counterparts, they're promoted and accepted here.
- */
- h_handler = duk_require_hobject_promote_mask(ctx, 1, DUK_TYPE_MASK_LIGHTFUNC | DUK_TYPE_MASK_BUFFER);
- DUK_ASSERT(h_handler != NULL);
- if (DUK_HOBJECT_HAS_EXOTIC_PROXYOBJ(h_handler)) {
- goto fail_args;
- }
-
- /* XXX: the returned value is exotic in ES2015, but we use a
- * simple object here with no prototype. Without a prototype,
- * ToPrimitive() coercion fails which is a bit confusing.
- * No callable check/handling in the current Proxy subset.
- */
- (void) duk_push_object_helper_proto(ctx,
- DUK_HOBJECT_FLAG_EXTENSIBLE |
- DUK_HOBJECT_FLAG_FASTREFS |
- DUK_HOBJECT_FLAG_EXOTIC_PROXYOBJ |
- DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_OBJECT),
- NULL);
- DUK_ASSERT_TOP(ctx, 3);
-
- /* Make _Target and _Handler non-configurable and non-writable.
- * They can still be forcibly changed by C code (both user and
- * Duktape internal), but not by Ecmascript code.
- */
-
- /* Proxy target */
- duk_dup_0(ctx);
- duk_xdef_prop_stridx_short(ctx, -2, DUK_STRIDX_INT_TARGET, DUK_PROPDESC_FLAGS_NONE);
-
- /* Proxy handler */
- duk_dup_1(ctx);
- duk_xdef_prop_stridx_short(ctx, -2, DUK_STRIDX_INT_HANDLER, DUK_PROPDESC_FLAGS_NONE);
-
- return 1; /* replacement handler */
-
- fail_args:
- DUK_DCERROR_TYPE_INVALID_ARGS((duk_hthread *) ctx);
+ duk_require_constructor_call(thr);
+ duk_push_proxy(thr, 0 /*flags*/); /* [ target handler ] -> [ proxy ] */
+ return 1; /* replacement */
}
#endif /* DUK_USE_ES6_PROXY */
/*
@@ -37091,97 +38387,89 @@ DUK_INTERNAL duk_ret_t duk_bi_proxy_constructor(duk_context *ctx) {
/* #include duk_internal.h -> already included */
#if defined(DUK_USE_REFLECT_BUILTIN)
-DUK_INTERNAL duk_ret_t duk_bi_reflect_object_delete_property(duk_context *ctx) {
- duk_hthread *thr;
+DUK_INTERNAL duk_ret_t duk_bi_reflect_object_delete_property(duk_hthread *thr) {
duk_tval *tv_obj;
duk_tval *tv_key;
duk_bool_t ret;
- DUK_ASSERT_TOP(ctx, 2);
- (void) duk_require_hobject(ctx, 0);
- (void) duk_to_string(ctx, 1);
+ DUK_ASSERT_TOP(thr, 2);
+ (void) duk_require_hobject(thr, 0);
+ (void) duk_to_string(thr, 1);
/* [ target key ] */
- thr = (duk_hthread *) ctx;
DUK_ASSERT(thr != NULL);
- tv_obj = DUK_GET_TVAL_POSIDX(ctx, 0);
- tv_key = DUK_GET_TVAL_POSIDX(ctx, 1);
+ tv_obj = DUK_GET_TVAL_POSIDX(thr, 0);
+ tv_key = DUK_GET_TVAL_POSIDX(thr, 1);
ret = duk_hobject_delprop(thr, tv_obj, tv_key, 0 /*throw_flag*/);
- duk_push_boolean(ctx, ret);
+ duk_push_boolean(thr, ret);
return 1;
}
-DUK_INTERNAL duk_ret_t duk_bi_reflect_object_get(duk_context *ctx) {
- duk_hthread *thr;
+DUK_INTERNAL duk_ret_t duk_bi_reflect_object_get(duk_hthread *thr) {
duk_tval *tv_obj;
duk_tval *tv_key;
duk_idx_t nargs;
- nargs = duk_get_top_require_min(ctx, 2 /*min_top*/);
- (void) duk_require_hobject(ctx, 0);
- (void) duk_to_string(ctx, 1);
- if (nargs >= 3 && !duk_strict_equals(ctx, 0, 2)) {
+ DUK_ASSERT(thr != NULL);
+ nargs = duk_get_top_require_min(thr, 2 /*min_top*/);
+ (void) duk_require_hobject(thr, 0);
+ (void) duk_to_string(thr, 1);
+ if (nargs >= 3 && !duk_strict_equals(thr, 0, 2)) {
/* XXX: [[Get]] receiver currently unsupported */
- DUK_ERROR_UNSUPPORTED((duk_hthread *) ctx);
+ DUK_ERROR_UNSUPPORTED(thr);
}
/* [ target key receiver? ...? ] */
- thr = (duk_hthread *) ctx;
- DUK_ASSERT(thr != NULL);
- tv_obj = DUK_GET_TVAL_POSIDX(ctx, 0);
- tv_key = DUK_GET_TVAL_POSIDX(ctx, 1);
+ tv_obj = DUK_GET_TVAL_POSIDX(thr, 0);
+ tv_key = DUK_GET_TVAL_POSIDX(thr, 1);
(void) duk_hobject_getprop(thr, tv_obj, tv_key); /* This could also be a duk_get_prop(). */
return 1;
}
-DUK_INTERNAL duk_ret_t duk_bi_reflect_object_has(duk_context *ctx) {
- duk_hthread *thr;
+DUK_INTERNAL duk_ret_t duk_bi_reflect_object_has(duk_hthread *thr) {
duk_tval *tv_obj;
duk_tval *tv_key;
duk_bool_t ret;
- DUK_ASSERT_TOP(ctx, 2);
- (void) duk_require_hobject(ctx, 0);
- (void) duk_to_string(ctx, 1);
+ DUK_ASSERT(thr != NULL);
+ DUK_ASSERT_TOP(thr, 2);
+ (void) duk_require_hobject(thr, 0);
+ (void) duk_to_string(thr, 1);
/* [ target key ] */
- thr = (duk_hthread *) ctx;
- DUK_ASSERT(thr != NULL);
- tv_obj = DUK_GET_TVAL_POSIDX(ctx, 0);
- tv_key = DUK_GET_TVAL_POSIDX(ctx, 1);
+ tv_obj = DUK_GET_TVAL_POSIDX(thr, 0);
+ tv_key = DUK_GET_TVAL_POSIDX(thr, 1);
ret = duk_hobject_hasprop(thr, tv_obj, tv_key);
- duk_push_boolean(ctx, ret);
+ duk_push_boolean(thr, ret);
return 1;
}
-DUK_INTERNAL duk_ret_t duk_bi_reflect_object_set(duk_context *ctx) {
- duk_hthread *thr;
+DUK_INTERNAL duk_ret_t duk_bi_reflect_object_set(duk_hthread *thr) {
duk_tval *tv_obj;
duk_tval *tv_key;
duk_tval *tv_val;
duk_idx_t nargs;
duk_bool_t ret;
- nargs = duk_get_top_require_min(ctx, 3 /*min_top*/);
- (void) duk_require_hobject(ctx, 0);
- (void) duk_to_string(ctx, 1);
- if (nargs >= 4 && !duk_strict_equals(ctx, 0, 3)) {
+ DUK_ASSERT(thr != NULL);
+ nargs = duk_get_top_require_min(thr, 3 /*min_top*/);
+ (void) duk_require_hobject(thr, 0);
+ (void) duk_to_string(thr, 1);
+ if (nargs >= 4 && !duk_strict_equals(thr, 0, 3)) {
/* XXX: [[Set]] receiver currently unsupported */
- DUK_ERROR_UNSUPPORTED((duk_hthread *) ctx);
+ DUK_ERROR_UNSUPPORTED(thr);
}
/* [ target key value receiver? ...? ] */
- thr = (duk_hthread *) ctx;
- DUK_ASSERT(thr != NULL);
- tv_obj = DUK_GET_TVAL_POSIDX(ctx, 0);
- tv_key = DUK_GET_TVAL_POSIDX(ctx, 1);
- tv_val = DUK_GET_TVAL_POSIDX(ctx, 2);
+ tv_obj = DUK_GET_TVAL_POSIDX(thr, 0);
+ tv_key = DUK_GET_TVAL_POSIDX(thr, 1);
+ tv_val = DUK_GET_TVAL_POSIDX(thr, 2);
ret = duk_hobject_putprop(thr, tv_obj, tv_key, tv_val, 0 /*throw_flag*/);
- duk_push_boolean(ctx, ret);
+ duk_push_boolean(thr, ret);
return 1;
}
#endif /* DUK_USE_REFLECT_BUILTIN */
@@ -37193,35 +38481,34 @@ DUK_INTERNAL duk_ret_t duk_bi_reflect_object_set(duk_context *ctx) {
#if defined(DUK_USE_REGEXP_SUPPORT)
-DUK_LOCAL void duk__get_this_regexp(duk_context *ctx) {
+DUK_LOCAL void duk__get_this_regexp(duk_hthread *thr) {
duk_hobject *h;
- duk_push_this(ctx);
- h = duk_require_hobject_with_class(ctx, -1, DUK_HOBJECT_CLASS_REGEXP);
+ duk_push_this(thr);
+ h = duk_require_hobject_with_class(thr, -1, DUK_HOBJECT_CLASS_REGEXP);
DUK_ASSERT(h != NULL);
DUK_UNREF(h);
- duk_insert(ctx, 0); /* prepend regexp to valstack 0 index */
+ duk_insert(thr, 0); /* prepend regexp to valstack 0 index */
}
/* XXX: much to improve (code size) */
-DUK_INTERNAL duk_ret_t duk_bi_regexp_constructor(duk_context *ctx) {
- duk_hthread *thr = (duk_hthread *) ctx;
+DUK_INTERNAL duk_ret_t duk_bi_regexp_constructor(duk_hthread *thr) {
duk_hobject *h_pattern;
- DUK_ASSERT_TOP(ctx, 2);
- h_pattern = duk_get_hobject(ctx, 0);
+ DUK_ASSERT_TOP(thr, 2);
+ h_pattern = duk_get_hobject(thr, 0);
- if (!duk_is_constructor_call(ctx) &&
+ if (!duk_is_constructor_call(thr) &&
h_pattern != NULL &&
DUK_HOBJECT_GET_CLASS_NUMBER(h_pattern) == DUK_HOBJECT_CLASS_REGEXP &&
- duk_is_undefined(ctx, 1)) {
+ duk_is_undefined(thr, 1)) {
/* Called as a function, pattern has [[Class]] "RegExp" and
* flags is undefined -> return object as is.
*/
/* XXX: ES2015 has a NewTarget SameValue() check which is not
* yet implemented.
*/
- duk_dup_0(ctx);
+ duk_dup_0(thr);
return 1;
}
@@ -37231,40 +38518,40 @@ DUK_INTERNAL duk_ret_t duk_bi_regexp_constructor(duk_context *ctx) {
if (h_pattern != NULL &&
DUK_HOBJECT_GET_CLASS_NUMBER(h_pattern) == DUK_HOBJECT_CLASS_REGEXP) {
- duk_get_prop_stridx_short(ctx, 0, DUK_STRIDX_SOURCE);
- if (duk_is_undefined(ctx, 1)) {
+ duk_get_prop_stridx_short(thr, 0, DUK_STRIDX_SOURCE);
+ if (duk_is_undefined(thr, 1)) {
/* In ES5 one would need to read the flags individually;
* in ES2015 just read .flags.
*/
- duk_get_prop_stridx(ctx, 0, DUK_STRIDX_FLAGS);
+ duk_get_prop_stridx(thr, 0, DUK_STRIDX_FLAGS);
} else {
/* In ES2015 allowed; overrides argument RegExp flags. */
- duk_dup_1(ctx);
+ duk_dup_1(thr);
}
} else {
- if (duk_is_undefined(ctx, 0)) {
- duk_push_hstring_empty(ctx);
+ if (duk_is_undefined(thr, 0)) {
+ duk_push_hstring_empty(thr);
} else {
- duk_dup_0(ctx);
- duk_to_string(ctx, -1); /* Rejects Symbols. */
+ duk_dup_0(thr);
+ duk_to_string(thr, -1); /* Rejects Symbols. */
}
- if (duk_is_undefined(ctx, 1)) {
- duk_push_hstring_empty(ctx);
+ if (duk_is_undefined(thr, 1)) {
+ duk_push_hstring_empty(thr);
} else {
- duk_dup_1(ctx);
- duk_to_string(ctx, -1); /* Rejects Symbols. */
+ duk_dup_1(thr);
+ duk_to_string(thr, -1); /* Rejects Symbols. */
}
/* [ ... pattern flags ] */
}
DUK_DDD(DUK_DDDPRINT("RegExp constructor/function call, pattern=%!T, flags=%!T",
- (duk_tval *) duk_get_tval(ctx, -2), (duk_tval *) duk_get_tval(ctx, -1)));
+ (duk_tval *) duk_get_tval(thr, -2), (duk_tval *) duk_get_tval(thr, -1)));
/* [ ... pattern flags ] (both uncoerced) */
- duk_to_string(ctx, -2);
- duk_to_string(ctx, -1);
+ duk_to_string(thr, -2);
+ duk_to_string(thr, -1);
duk_regexp_compile(thr);
/* [ ... bytecode escaped_source ] */
@@ -37276,46 +38563,46 @@ DUK_INTERNAL duk_ret_t duk_bi_regexp_constructor(duk_context *ctx) {
return 1;
}
-DUK_INTERNAL duk_ret_t duk_bi_regexp_prototype_exec(duk_context *ctx) {
- duk__get_this_regexp(ctx);
+DUK_INTERNAL duk_ret_t duk_bi_regexp_prototype_exec(duk_hthread *thr) {
+ duk__get_this_regexp(thr);
/* [ regexp input ] */
- duk_regexp_match((duk_hthread *) ctx);
+ duk_regexp_match(thr);
/* [ result ] */
return 1;
}
-DUK_INTERNAL duk_ret_t duk_bi_regexp_prototype_test(duk_context *ctx) {
- duk__get_this_regexp(ctx);
+DUK_INTERNAL duk_ret_t duk_bi_regexp_prototype_test(duk_hthread *thr) {
+ duk__get_this_regexp(thr);
/* [ regexp input ] */
/* result object is created and discarded; wasteful but saves code space */
- duk_regexp_match((duk_hthread *) ctx);
+ duk_regexp_match(thr);
/* [ result ] */
- duk_push_boolean(ctx, (duk_is_null(ctx, -1) ? 0 : 1));
+ duk_push_boolean(thr, (duk_is_null(thr, -1) ? 0 : 1));
return 1;
}
-DUK_INTERNAL duk_ret_t duk_bi_regexp_prototype_tostring(duk_context *ctx) {
+DUK_INTERNAL duk_ret_t duk_bi_regexp_prototype_tostring(duk_hthread *thr) {
/* This must be generic in ES2015 and later. */
- DUK_ASSERT_TOP(ctx, 0);
- duk_push_this(ctx);
- duk_push_string(ctx, "/");
- duk_get_prop_stridx(ctx, 0, DUK_STRIDX_SOURCE);
- duk_dup_m2(ctx); /* another "/" */
- duk_get_prop_stridx(ctx, 0, DUK_STRIDX_FLAGS);
- duk_concat(ctx, 4);
+ DUK_ASSERT_TOP(thr, 0);
+ duk_push_this(thr);
+ duk_push_string(thr, "/");
+ duk_get_prop_stridx(thr, 0, DUK_STRIDX_SOURCE);
+ duk_dup_m2(thr); /* another "/" */
+ duk_get_prop_stridx(thr, 0, DUK_STRIDX_FLAGS);
+ duk_concat(thr, 4);
return 1;
}
-DUK_INTERNAL duk_ret_t duk_bi_regexp_prototype_flags(duk_context *ctx) {
+DUK_INTERNAL duk_ret_t duk_bi_regexp_prototype_flags(duk_hthread *thr) {
/* .flags is ES2015 but present even when ES2015 bindings are
* disabled because the constructor relies on it.
*/
@@ -37323,15 +38610,15 @@ DUK_INTERNAL duk_ret_t duk_bi_regexp_prototype_flags(duk_context *ctx) {
duk_uint8_t *p = buf;
/* .flags is generic and works on any object. */
- duk_push_this(ctx);
- (void) duk_require_hobject(ctx, -1);
- if (duk_get_prop_stridx_boolean(ctx, 0, DUK_STRIDX_GLOBAL, NULL)) {
+ duk_push_this(thr);
+ (void) duk_require_hobject(thr, -1);
+ if (duk_get_prop_stridx_boolean(thr, 0, DUK_STRIDX_GLOBAL, NULL)) {
*p++ = DUK_ASC_LC_G;
}
- if (duk_get_prop_stridx_boolean(ctx, 0, DUK_STRIDX_IGNORE_CASE, NULL)) {
+ if (duk_get_prop_stridx_boolean(thr, 0, DUK_STRIDX_IGNORE_CASE, NULL)) {
*p++ = DUK_ASC_LC_I;
}
- if (duk_get_prop_stridx_boolean(ctx, 0, DUK_STRIDX_MULTILINE, NULL)) {
+ if (duk_get_prop_stridx_boolean(thr, 0, DUK_STRIDX_MULTILINE, NULL)) {
*p++ = DUK_ASC_LC_M;
}
/* .unicode: to be added */
@@ -37339,30 +38626,29 @@ DUK_INTERNAL duk_ret_t duk_bi_regexp_prototype_flags(duk_context *ctx) {
*p++ = DUK_ASC_NUL;
DUK_ASSERT((duk_size_t) (p - buf) <= sizeof(buf));
- duk_push_string(ctx, (const char *) buf);
+ duk_push_string(thr, (const char *) buf);
return 1;
}
/* Shared helper for providing .source, .global, .multiline, etc getters. */
-DUK_INTERNAL duk_ret_t duk_bi_regexp_prototype_shared_getter(duk_context *ctx) {
- duk_hthread *thr = (duk_hthread *) ctx;
+DUK_INTERNAL duk_ret_t duk_bi_regexp_prototype_shared_getter(duk_hthread *thr) {
duk_hstring *h_bc;
- duk_small_int_t re_flags;
+ duk_small_uint_t re_flags;
duk_hobject *h;
duk_int_t magic;
- DUK_ASSERT_TOP(ctx, 0);
+ DUK_ASSERT_TOP(thr, 0);
- duk_push_this(ctx);
- h = duk_require_hobject(ctx, -1);
- magic = duk_get_current_magic(ctx);
+ duk_push_this(thr);
+ h = duk_require_hobject(thr, -1);
+ magic = duk_get_current_magic(thr);
if (DUK_HOBJECT_GET_CLASS_NUMBER(h) == DUK_HOBJECT_CLASS_REGEXP) {
- duk_get_prop_stridx_short(ctx, 0, DUK_STRIDX_INT_SOURCE);
- duk_get_prop_stridx_short(ctx, 0, DUK_STRIDX_INT_BYTECODE);
- h_bc = duk_require_hstring(ctx, -1);
- re_flags = (duk_small_int_t) DUK_HSTRING_GET_DATA(h_bc)[0]; /* Safe even if h_bc length is 0 (= NUL) */
- duk_pop(ctx);
+ duk_get_prop_stridx_short(thr, 0, DUK_STRIDX_INT_SOURCE);
+ duk_get_prop_stridx_short(thr, 0, DUK_STRIDX_INT_BYTECODE);
+ h_bc = duk_require_hstring(thr, -1);
+ re_flags = (duk_small_uint_t) DUK_HSTRING_GET_DATA(h_bc)[0]; /* Safe even if h_bc length is 0 (= NUL) */
+ duk_pop(thr);
} else if (h == thr->builtins[DUK_BIDX_REGEXP_PROTOTYPE]) {
/* In ES2015 and ES2016 a TypeError would be thrown here.
* However, this had real world issues so ES2017 draft
@@ -37372,7 +38658,7 @@ DUK_INTERNAL duk_ret_t duk_bi_regexp_prototype_shared_getter(duk_context *ctx) {
if (magic != 16 /* .source */) {
return 0;
}
- duk_push_string(ctx, "(?:)"); /* .source handled by switch-case */
+ duk_push_string(thr, "(?:)"); /* .source handled by switch-case */
re_flags = 0;
} else {
DUK_DCERROR_TYPE_INVALID_ARGS(thr);
@@ -37382,15 +38668,15 @@ DUK_INTERNAL duk_ret_t duk_bi_regexp_prototype_shared_getter(duk_context *ctx) {
switch (magic) {
case 0: { /* global */
- duk_push_boolean(ctx, (re_flags & DUK_RE_FLAG_GLOBAL));
+ duk_push_boolean(thr, (re_flags & DUK_RE_FLAG_GLOBAL));
break;
}
case 1: { /* ignoreCase */
- duk_push_boolean(ctx, (re_flags & DUK_RE_FLAG_IGNORE_CASE));
+ duk_push_boolean(thr, (re_flags & DUK_RE_FLAG_IGNORE_CASE));
break;
}
case 2: { /* multiline */
- duk_push_boolean(ctx, (re_flags & DUK_RE_FLAG_MULTILINE));
+ duk_push_boolean(thr, (re_flags & DUK_RE_FLAG_MULTILINE));
break;
}
#if 0
@@ -37399,7 +38685,7 @@ DUK_INTERNAL duk_ret_t duk_bi_regexp_prototype_shared_getter(duk_context *ctx) {
*/
case 3: /* sticky */
case 4: { /* unicode */
- duk_push_false(ctx);
+ duk_push_false(thr);
break;
}
#endif
@@ -37438,19 +38724,19 @@ DUK_INTERNAL duk_ret_t duk_bi_regexp_prototype_shared_getter(duk_context *ctx) {
* Helpers
*/
-DUK_LOCAL duk_hstring *duk__str_tostring_notregexp(duk_context *ctx, duk_idx_t idx) {
+DUK_LOCAL duk_hstring *duk__str_tostring_notregexp(duk_hthread *thr, duk_idx_t idx) {
duk_hstring *h;
- if (duk_get_class_number(ctx, idx) == DUK_HOBJECT_CLASS_REGEXP) {
- DUK_ERROR_TYPE_INVALID_ARGS((duk_hthread *) ctx);
+ if (duk_get_class_number(thr, idx) == DUK_HOBJECT_CLASS_REGEXP) {
+ DUK_ERROR_TYPE_INVALID_ARGS(thr);
}
- h = duk_to_hstring(ctx, idx);
+ h = duk_to_hstring(thr, idx);
DUK_ASSERT(h != NULL);
return h;
}
-DUK_LOCAL duk_int_t duk__str_search_shared(duk_context *ctx, duk_hstring *h_this, duk_hstring *h_search, duk_int_t start_cpos, duk_bool_t backwards) {
+DUK_LOCAL duk_int_t duk__str_search_shared(duk_hthread *thr, duk_hstring *h_this, duk_hstring *h_search, duk_int_t start_cpos, duk_bool_t backwards) {
duk_int_t cpos;
duk_int_t bpos;
const duk_uint8_t *p_start, *p_end, *p;
@@ -37472,7 +38758,7 @@ DUK_LOCAL duk_int_t duk__str_search_shared(duk_context *ctx, duk_hstring *h_this
}
DUK_ASSERT(q_blen > 0);
- bpos = (duk_int_t) duk_heap_strcache_offset_char2byte((duk_hthread *) ctx, h_this, (duk_uint32_t) cpos);
+ bpos = (duk_int_t) duk_heap_strcache_offset_char2byte(thr, h_this, (duk_uint32_t) cpos);
p_start = DUK_HSTRING_GET_DATA(h_this);
p_end = p_start + DUK_HSTRING_GET_BYTELEN(h_this);
@@ -37528,7 +38814,7 @@ DUK_LOCAL duk_int_t duk__str_search_shared(duk_context *ctx, duk_hstring *h_this
* Constructor
*/
-DUK_INTERNAL duk_ret_t duk_bi_string_constructor(duk_context *ctx) {
+DUK_INTERNAL duk_ret_t duk_bi_string_constructor(duk_hthread *thr) {
duk_hstring *h;
duk_uint_t flags;
@@ -37542,36 +38828,35 @@ DUK_INTERNAL duk_ret_t duk_bi_string_constructor(duk_context *ctx) {
* current magic call sites.
*/
- if (duk_get_top(ctx) == 0) {
- duk_push_hstring_empty(ctx);
+ if (duk_get_top(thr) == 0) {
+ duk_push_hstring_empty(thr);
} else {
- h = duk_to_hstring_acceptsymbol(ctx, 0);
- if (DUK_UNLIKELY(DUK_HSTRING_HAS_SYMBOL(h) && !duk_is_constructor_call(ctx))) {
- duk_push_symbol_descriptive_string(ctx, h);
- duk_replace(ctx, 0);
+ h = duk_to_hstring_acceptsymbol(thr, 0);
+ if (DUK_UNLIKELY(DUK_HSTRING_HAS_SYMBOL(h) && !duk_is_constructor_call(thr))) {
+ duk_push_symbol_descriptive_string(thr, h);
+ duk_replace(thr, 0);
}
}
- duk_to_string(ctx, 0); /* catches symbol argument for constructor call */
- DUK_ASSERT(duk_is_string(ctx, 0));
- duk_set_top(ctx, 1); /* Top may be 1 or larger. */
+ duk_to_string(thr, 0); /* catches symbol argument for constructor call */
+ DUK_ASSERT(duk_is_string(thr, 0));
+ duk_set_top(thr, 1); /* Top may be 1 or larger. */
- if (duk_is_constructor_call(ctx)) {
+ if (duk_is_constructor_call(thr)) {
/* String object internal value is immutable */
flags = DUK_HOBJECT_FLAG_EXTENSIBLE |
DUK_HOBJECT_FLAG_FASTREFS |
DUK_HOBJECT_FLAG_EXOTIC_STRINGOBJ |
DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_STRING);
- duk_push_object_helper(ctx, flags, DUK_BIDX_STRING_PROTOTYPE);
- duk_dup_0(ctx);
- duk_xdef_prop_stridx_short(ctx, -2, DUK_STRIDX_INT_VALUE, DUK_PROPDESC_FLAGS_NONE);
+ duk_push_object_helper(thr, flags, DUK_BIDX_STRING_PROTOTYPE);
+ duk_dup_0(thr);
+ duk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_INT_VALUE, DUK_PROPDESC_FLAGS_NONE);
}
/* Note: unbalanced stack on purpose */
return 1;
}
-DUK_LOCAL duk_ret_t duk__construct_from_codepoints(duk_context *ctx, duk_bool_t nonbmp) {
- duk_hthread *thr = (duk_hthread *) ctx;
+DUK_LOCAL duk_ret_t duk__construct_from_codepoints(duk_hthread *thr, duk_bool_t nonbmp) {
duk_bufwriter_ctx bw_alloc;
duk_bufwriter_ctx *bw;
duk_idx_t i, n;
@@ -37583,10 +38868,10 @@ DUK_LOCAL duk_ret_t duk__construct_from_codepoints(duk_context *ctx, duk_bool_t
* build a string from a duk_tval number sequence in one go?).
*/
- n = duk_get_top(ctx);
+ n = duk_get_top(thr);
bw = &bw_alloc;
- DUK_BW_INIT_PUSHBUF(thr, bw, n); /* initial estimate for ASCII only codepoints */
+ DUK_BW_INIT_PUSHBUF(thr, bw, (duk_size_t) n); /* initial estimate for ASCII only codepoints */
for (i = 0; i < n; i++) {
/* XXX: could improve bufwriter handling to write multiple codepoints
@@ -37600,9 +38885,9 @@ DUK_LOCAL duk_ret_t duk__construct_from_codepoints(duk_context *ctx, duk_bool_t
* the same.
*/
duk_int32_t i32 = 0;
- if (!duk_is_whole_get_int32(duk_to_number(ctx, i), &i32) ||
+ if (!duk_is_whole_get_int32(duk_to_number(thr, i), &i32) ||
i32 < 0 || i32 > 0x10ffffL) {
- DUK_DCERROR_RANGE_INVALID_ARGS((duk_hthread *) ctx);
+ DUK_DCERROR_RANGE_INVALID_ARGS(thr);
}
DUK_ASSERT(i32 >= 0 && i32 <= 0x10ffffL);
cp = (duk_ucodepoint_t) i32;
@@ -37614,10 +38899,10 @@ DUK_LOCAL duk_ret_t duk__construct_from_codepoints(duk_context *ctx, duk_bool_t
* non-BMP codepoints. Don't use CESU-8 because that'd create
* surrogate pairs.
*/
- cp = (duk_ucodepoint_t) duk_to_uint32(ctx, i);
+ cp = (duk_ucodepoint_t) duk_to_uint32(thr, i);
DUK_BW_WRITE_ENSURE_XUTF8(thr, bw, cp);
#else
- cp = (duk_ucodepoint_t) duk_to_uint16(ctx, i);
+ cp = (duk_ucodepoint_t) duk_to_uint16(thr, i);
DUK_ASSERT(cp >= 0 && cp <= 0x10ffffL);
DUK_BW_WRITE_ENSURE_CESU8(thr, bw, cp);
#endif
@@ -37625,17 +38910,17 @@ DUK_LOCAL duk_ret_t duk__construct_from_codepoints(duk_context *ctx, duk_bool_t
}
DUK_BW_COMPACT(thr, bw);
- (void) duk_buffer_to_string(ctx, -1); /* Safe, extended UTF-8 or CESU-8 encoded. */
+ (void) duk_buffer_to_string(thr, -1); /* Safe, extended UTF-8 or CESU-8 encoded. */
return 1;
}
-DUK_INTERNAL duk_ret_t duk_bi_string_constructor_from_char_code(duk_context *ctx) {
- return duk__construct_from_codepoints(ctx, 0 /*nonbmp*/);
+DUK_INTERNAL duk_ret_t duk_bi_string_constructor_from_char_code(duk_hthread *thr) {
+ return duk__construct_from_codepoints(thr, 0 /*nonbmp*/);
}
#if defined(DUK_USE_ES6)
-DUK_INTERNAL duk_ret_t duk_bi_string_constructor_from_code_point(duk_context *ctx) {
- return duk__construct_from_codepoints(ctx, 1 /*nonbmp*/);
+DUK_INTERNAL duk_ret_t duk_bi_string_constructor_from_code_point(duk_hthread *thr) {
+ return duk__construct_from_codepoints(thr, 1 /*nonbmp*/);
}
#endif
@@ -37643,11 +38928,11 @@ DUK_INTERNAL duk_ret_t duk_bi_string_constructor_from_code_point(duk_context *ct
* toString(), valueOf()
*/
-DUK_INTERNAL duk_ret_t duk_bi_string_prototype_to_string(duk_context *ctx) {
+DUK_INTERNAL duk_ret_t duk_bi_string_prototype_to_string(duk_hthread *thr) {
duk_tval *tv;
- duk_push_this(ctx);
- tv = duk_require_tval(ctx, -1);
+ duk_push_this(thr);
+ tv = duk_require_tval(thr, -1);
DUK_ASSERT(tv != NULL);
if (DUK_TVAL_IS_STRING(tv)) {
@@ -37661,37 +38946,36 @@ DUK_INTERNAL duk_ret_t duk_bi_string_prototype_to_string(duk_context *ctx) {
goto type_error;
}
- duk_get_prop_stridx_short(ctx, -1, DUK_STRIDX_INT_VALUE);
- DUK_ASSERT(duk_is_string(ctx, -1));
+ duk_get_prop_stridx_short(thr, -1, DUK_STRIDX_INT_VALUE);
+ DUK_ASSERT(duk_is_string(thr, -1));
} else {
goto type_error;
}
- (void) duk_require_hstring_notsymbol(ctx, -1); /* Reject symbols (and wrapped symbols). */
+ (void) duk_require_hstring_notsymbol(thr, -1); /* Reject symbols (and wrapped symbols). */
return 1;
type_error:
- DUK_DCERROR_TYPE_INVALID_ARGS((duk_hthread *) ctx);
+ DUK_DCERROR_TYPE_INVALID_ARGS(thr);
}
/*
* Character and charcode access
*/
-DUK_INTERNAL duk_ret_t duk_bi_string_prototype_char_at(duk_context *ctx) {
+DUK_INTERNAL duk_ret_t duk_bi_string_prototype_char_at(duk_hthread *thr) {
duk_int_t pos;
/* XXX: faster implementation */
- (void) duk_push_this_coercible_to_string(ctx);
- pos = duk_to_int(ctx, 0);
- duk_substring(ctx, -1, pos, pos + 1);
+ (void) duk_push_this_coercible_to_string(thr);
+ pos = duk_to_int(thr, 0);
+ duk_substring(thr, -1, (duk_size_t) pos, (duk_size_t) (pos + 1));
return 1;
}
/* Magic: 0=charCodeAt, 1=codePointAt */
-DUK_INTERNAL duk_ret_t duk_bi_string_prototype_char_code_at(duk_context *ctx) {
- duk_hthread *thr = (duk_hthread *) ctx;
+DUK_INTERNAL duk_ret_t duk_bi_string_prototype_char_code_at(duk_hthread *thr) {
duk_int_t pos;
duk_hstring *h;
duk_bool_t clamped;
@@ -37700,20 +38984,20 @@ DUK_INTERNAL duk_ret_t duk_bi_string_prototype_char_code_at(duk_context *ctx) {
/* XXX: faster implementation */
- DUK_DDD(DUK_DDDPRINT("arg=%!T", (duk_tval *) duk_get_tval(ctx, 0)));
+ DUK_DDD(DUK_DDDPRINT("arg=%!T", (duk_tval *) duk_get_tval(thr, 0)));
- h = duk_push_this_coercible_to_string(ctx);
+ h = duk_push_this_coercible_to_string(thr);
DUK_ASSERT(h != NULL);
- pos = duk_to_int_clamped_raw(ctx,
+ pos = duk_to_int_clamped_raw(thr,
0 /*index*/,
0 /*min(incl)*/,
(duk_int_t) DUK_HSTRING_GET_CHARLEN(h) - 1 /*max(incl)*/,
&clamped /*out_clamped*/);
#if defined(DUK_USE_ES6)
- magic = duk_get_current_magic(ctx);
+ magic = duk_get_current_magic(thr);
#else
- DUK_ASSERT(duk_get_current_magic(ctx) == 0);
+ DUK_ASSERT(duk_get_current_magic(thr) == 0);
magic = 0;
#endif
if (clamped) {
@@ -37723,10 +39007,11 @@ DUK_INTERNAL duk_ret_t duk_bi_string_prototype_char_code_at(duk_context *ctx) {
if (magic != 0) {
return 0;
}
- duk_push_nan(ctx);
+ duk_push_nan(thr);
} else {
- cp = (duk_uint32_t) duk_hstring_char_code_at_raw(thr, h, pos, (duk_bool_t) magic /*surrogate_aware*/);
- duk_push_u32(ctx, cp);
+ DUK_ASSERT(pos >= 0);
+ cp = (duk_uint32_t) duk_hstring_char_code_at_raw(thr, h, (duk_uint_t) pos, (duk_bool_t) magic /*surrogate_aware*/);
+ duk_push_u32(thr, cp);
}
return 1;
}
@@ -37739,22 +39024,22 @@ DUK_INTERNAL duk_ret_t duk_bi_string_prototype_char_code_at(duk_context *ctx) {
* different algorithms so that footprint would be reduced?
*/
-DUK_INTERNAL duk_ret_t duk_bi_string_prototype_substring(duk_context *ctx) {
+DUK_INTERNAL duk_ret_t duk_bi_string_prototype_substring(duk_hthread *thr) {
duk_hstring *h;
duk_int_t start_pos, end_pos;
duk_int_t len;
- h = duk_push_this_coercible_to_string(ctx);
+ h = duk_push_this_coercible_to_string(thr);
DUK_ASSERT(h != NULL);
len = (duk_int_t) DUK_HSTRING_GET_CHARLEN(h);
/* [ start end str ] */
- start_pos = duk_to_int_clamped(ctx, 0, 0, len);
- if (duk_is_undefined(ctx, 1)) {
+ start_pos = duk_to_int_clamped(thr, 0, 0, len);
+ if (duk_is_undefined(thr, 1)) {
end_pos = len;
} else {
- end_pos = duk_to_int_clamped(ctx, 1, 0, len);
+ end_pos = duk_to_int_clamped(thr, 1, 0, len);
}
DUK_ASSERT(start_pos >= 0 && start_pos <= len);
DUK_ASSERT(end_pos >= 0 && end_pos <= len);
@@ -37767,12 +39052,12 @@ DUK_INTERNAL duk_ret_t duk_bi_string_prototype_substring(duk_context *ctx) {
DUK_ASSERT(end_pos >= start_pos);
- duk_substring(ctx, -1, (duk_size_t) start_pos, (duk_size_t) end_pos);
+ duk_substring(thr, -1, (duk_size_t) start_pos, (duk_size_t) end_pos);
return 1;
}
#if defined(DUK_USE_SECTION_B)
-DUK_INTERNAL duk_ret_t duk_bi_string_prototype_substr(duk_context *ctx) {
+DUK_INTERNAL duk_ret_t duk_bi_string_prototype_substr(duk_hthread *thr) {
duk_hstring *h;
duk_int_t start_pos, end_pos;
duk_int_t len;
@@ -37781,8 +39066,8 @@ DUK_INTERNAL duk_ret_t duk_bi_string_prototype_substr(duk_context *ctx) {
* specification will happily coerce undefined and null to strings
* ("undefined" and "null").
*/
- duk_push_this(ctx);
- h = duk_to_hstring_m1(ctx); /* Reject Symbols. */
+ duk_push_this(thr);
+ h = duk_to_hstring_m1(thr); /* Reject Symbols. */
DUK_ASSERT(h != NULL);
len = (duk_int_t) DUK_HSTRING_GET_CHARLEN(h);
@@ -37794,47 +39079,47 @@ DUK_INTERNAL duk_ret_t duk_bi_string_prototype_substr(duk_context *ctx) {
*/
/* combines steps 2 and 5; -len ensures max() not needed for step 5 */
- start_pos = duk_to_int_clamped(ctx, 0, -len, len);
+ start_pos = duk_to_int_clamped(thr, 0, -len, len);
if (start_pos < 0) {
start_pos = len + start_pos;
}
DUK_ASSERT(start_pos >= 0 && start_pos <= len);
/* combines steps 3, 6; step 7 is not needed */
- if (duk_is_undefined(ctx, 1)) {
+ if (duk_is_undefined(thr, 1)) {
end_pos = len;
} else {
DUK_ASSERT(start_pos <= len);
- end_pos = start_pos + duk_to_int_clamped(ctx, 1, 0, len - start_pos);
+ end_pos = start_pos + duk_to_int_clamped(thr, 1, 0, len - start_pos);
}
DUK_ASSERT(start_pos >= 0 && start_pos <= len);
DUK_ASSERT(end_pos >= 0 && end_pos <= len);
DUK_ASSERT(end_pos >= start_pos);
- duk_substring(ctx, -1, (duk_size_t) start_pos, (duk_size_t) end_pos);
+ duk_substring(thr, -1, (duk_size_t) start_pos, (duk_size_t) end_pos);
return 1;
}
#endif /* DUK_USE_SECTION_B */
-DUK_INTERNAL duk_ret_t duk_bi_string_prototype_slice(duk_context *ctx) {
+DUK_INTERNAL duk_ret_t duk_bi_string_prototype_slice(duk_hthread *thr) {
duk_hstring *h;
duk_int_t start_pos, end_pos;
duk_int_t len;
- h = duk_push_this_coercible_to_string(ctx);
+ h = duk_push_this_coercible_to_string(thr);
DUK_ASSERT(h != NULL);
len = (duk_int_t) DUK_HSTRING_GET_CHARLEN(h);
/* [ start end str ] */
- start_pos = duk_to_int_clamped(ctx, 0, -len, len);
+ start_pos = duk_to_int_clamped(thr, 0, -len, len);
if (start_pos < 0) {
start_pos = len + start_pos;
}
- if (duk_is_undefined(ctx, 1)) {
+ if (duk_is_undefined(thr, 1)) {
end_pos = len;
} else {
- end_pos = duk_to_int_clamped(ctx, 1, -len, len);
+ end_pos = duk_to_int_clamped(thr, 1, -len, len);
if (end_pos < 0) {
end_pos = len + end_pos;
}
@@ -37848,7 +39133,7 @@ DUK_INTERNAL duk_ret_t duk_bi_string_prototype_slice(duk_context *ctx) {
DUK_ASSERT(end_pos >= start_pos);
- duk_substring(ctx, -1, (duk_size_t) start_pos, (duk_size_t) end_pos);
+ duk_substring(thr, -1, (duk_size_t) start_pos, (duk_size_t) end_pos);
return 1;
}
@@ -37856,11 +39141,10 @@ DUK_INTERNAL duk_ret_t duk_bi_string_prototype_slice(duk_context *ctx) {
* Case conversion
*/
-DUK_INTERNAL duk_ret_t duk_bi_string_prototype_caseconv_shared(duk_context *ctx) {
- duk_hthread *thr = (duk_hthread *) ctx;
- duk_small_int_t uppercase = duk_get_current_magic(ctx);
+DUK_INTERNAL duk_ret_t duk_bi_string_prototype_caseconv_shared(duk_hthread *thr) {
+ duk_small_int_t uppercase = duk_get_current_magic(thr);
- (void) duk_push_this_coercible_to_string(ctx);
+ (void) duk_push_this_coercible_to_string(thr);
duk_unicode_case_convert_string(thr, (duk_bool_t) uppercase);
return 1;
}
@@ -37869,33 +39153,33 @@ DUK_INTERNAL duk_ret_t duk_bi_string_prototype_caseconv_shared(duk_context *ctx)
* indexOf() and lastIndexOf()
*/
-DUK_INTERNAL duk_ret_t duk_bi_string_prototype_indexof_shared(duk_context *ctx) {
+DUK_INTERNAL duk_ret_t duk_bi_string_prototype_indexof_shared(duk_hthread *thr) {
duk_hstring *h_this;
duk_hstring *h_search;
duk_int_t clen_this;
duk_int_t cpos;
- duk_small_int_t is_lastindexof = duk_get_current_magic(ctx); /* 0=indexOf, 1=lastIndexOf */
+ duk_small_uint_t is_lastindexof = (duk_small_uint_t) duk_get_current_magic(thr); /* 0=indexOf, 1=lastIndexOf */
- h_this = duk_push_this_coercible_to_string(ctx);
+ h_this = duk_push_this_coercible_to_string(thr);
DUK_ASSERT(h_this != NULL);
clen_this = (duk_int_t) DUK_HSTRING_GET_CHARLEN(h_this);
- h_search = duk_to_hstring(ctx, 0);
+ h_search = duk_to_hstring(thr, 0);
DUK_ASSERT(h_search != NULL);
- duk_to_number(ctx, 1);
- if (duk_is_nan(ctx, 1) && is_lastindexof) {
+ duk_to_number(thr, 1);
+ if (duk_is_nan(thr, 1) && is_lastindexof) {
/* indexOf: NaN should cause pos to be zero.
* lastIndexOf: NaN should cause pos to be +Infinity
* (and later be clamped to len).
*/
cpos = clen_this;
} else {
- cpos = duk_to_int_clamped(ctx, 1, 0, clen_this);
+ cpos = duk_to_int_clamped(thr, 1, 0, clen_this);
}
- cpos = duk__str_search_shared(ctx, h_this, h_search, cpos, is_lastindexof /*backwards*/);
- duk_push_int(ctx, cpos);
+ cpos = duk__str_search_shared(thr, h_this, h_search, cpos, is_lastindexof /*backwards*/);
+ duk_push_int(thr, cpos);
return 1;
}
@@ -37914,8 +39198,7 @@ DUK_INTERNAL duk_ret_t duk_bi_string_prototype_indexof_shared(duk_context *ctx)
* - API call to get_prop and to_boolean
*/
-DUK_INTERNAL duk_ret_t duk_bi_string_prototype_replace(duk_context *ctx) {
- duk_hthread *thr = (duk_hthread *) ctx;
+DUK_INTERNAL duk_ret_t duk_bi_string_prototype_replace(duk_hthread *thr) {
duk_hstring *h_input;
duk_hstring *h_match;
duk_hstring *h_search;
@@ -37935,14 +39218,14 @@ DUK_INTERNAL duk_ret_t duk_bi_string_prototype_replace(duk_context *ctx) {
const duk_uint8_t *r_start, *r_end, *r; /* repl string scan */
duk_size_t tmp_sz;
- DUK_ASSERT_TOP(ctx, 2);
- h_input = duk_push_this_coercible_to_string(ctx);
+ DUK_ASSERT_TOP(thr, 2);
+ h_input = duk_push_this_coercible_to_string(thr);
DUK_ASSERT(h_input != NULL);
bw = &bw_alloc;
DUK_BW_INIT_PUSHBUF(thr, bw, DUK_HSTRING_GET_BYTELEN(h_input)); /* input size is good output starting point */
- DUK_ASSERT_TOP(ctx, 4);
+ DUK_ASSERT_TOP(thr, 4);
/* stack[0] = search value
* stack[1] = replace value
@@ -37950,29 +39233,29 @@ DUK_INTERNAL duk_ret_t duk_bi_string_prototype_replace(duk_context *ctx) {
* stack[3] = result buffer
*/
- h_re = duk_get_hobject_with_class(ctx, 0, DUK_HOBJECT_CLASS_REGEXP);
+ h_re = duk_get_hobject_with_class(thr, 0, DUK_HOBJECT_CLASS_REGEXP);
if (h_re) {
#if defined(DUK_USE_REGEXP_SUPPORT)
is_regexp = 1;
- is_global = duk_get_prop_stridx_boolean(ctx, 0, DUK_STRIDX_GLOBAL, NULL);
+ is_global = duk_get_prop_stridx_boolean(thr, 0, DUK_STRIDX_GLOBAL, NULL);
if (is_global) {
/* start match from beginning */
- duk_push_int(ctx, 0);
- duk_put_prop_stridx_short(ctx, 0, DUK_STRIDX_LAST_INDEX);
+ duk_push_int(thr, 0);
+ duk_put_prop_stridx_short(thr, 0, DUK_STRIDX_LAST_INDEX);
}
#else /* DUK_USE_REGEXP_SUPPORT */
DUK_DCERROR_UNSUPPORTED(thr);
#endif /* DUK_USE_REGEXP_SUPPORT */
} else {
- duk_to_string(ctx, 0); /* rejects symbols */
+ duk_to_string(thr, 0); /* rejects symbols */
#if defined(DUK_USE_REGEXP_SUPPORT)
is_regexp = 0;
is_global = 0;
#endif
}
- if (duk_is_function(ctx, 1)) {
+ if (duk_is_function(thr, 1)) {
is_repl_func = 1;
r_start = NULL;
r_end = NULL;
@@ -37980,7 +39263,7 @@ DUK_INTERNAL duk_ret_t duk_bi_string_prototype_replace(duk_context *ctx) {
duk_hstring *h_repl;
is_repl_func = 0;
- h_repl = duk_to_hstring(ctx, 1); /* reject symbols */
+ h_repl = duk_to_hstring(thr, 1); /* reject symbols */
DUK_ASSERT(h_repl != NULL);
r_start = DUK_HSTRING_GET_DATA(h_repl);
r_end = r_start + DUK_HSTRING_GET_BYTELEN(h_repl);
@@ -38012,27 +39295,27 @@ DUK_INTERNAL duk_ret_t duk_bi_string_prototype_replace(duk_context *ctx) {
* are made? See: test-bi-string-proto-replace.js for discussion.
*/
- DUK_ASSERT_TOP(ctx, 4);
+ DUK_ASSERT_TOP(thr, 4);
#if defined(DUK_USE_REGEXP_SUPPORT)
if (is_regexp) {
- duk_dup_0(ctx);
- duk_dup_2(ctx);
+ duk_dup_0(thr);
+ duk_dup_2(thr);
duk_regexp_match(thr); /* [ ... regexp input ] -> [ res_obj ] */
- if (!duk_is_object(ctx, -1)) {
- duk_pop(ctx);
+ if (!duk_is_object(thr, -1)) {
+ duk_pop(thr);
break;
}
- duk_get_prop_stridx_short(ctx, -1, DUK_STRIDX_INDEX);
- DUK_ASSERT(duk_is_number(ctx, -1));
- match_start_coff = duk_get_int(ctx, -1);
- duk_pop(ctx);
+ duk_get_prop_stridx_short(thr, -1, DUK_STRIDX_INDEX);
+ DUK_ASSERT(duk_is_number(thr, -1));
+ match_start_coff = duk_get_uint(thr, -1);
+ duk_pop(thr);
- duk_get_prop_index(ctx, -1, 0);
- DUK_ASSERT(duk_is_string(ctx, -1));
- h_match = duk_known_hstring(ctx, -1);
- duk_pop(ctx); /* h_match is borrowed, remains reachable through match_obj */
+ duk_get_prop_index(thr, -1, 0);
+ DUK_ASSERT(duk_is_string(thr, -1));
+ h_match = duk_known_hstring(thr, -1);
+ duk_pop(thr); /* h_match is borrowed, remains reachable through match_obj */
if (DUK_HSTRING_GET_BYTELEN(h_match) == 0) {
/* This should be equivalent to match() algorithm step 8.f.iii.2:
@@ -38040,17 +39323,17 @@ DUK_INTERNAL duk_ret_t duk_bi_string_prototype_replace(duk_context *ctx) {
*/
duk_uint32_t last_index;
- duk_get_prop_stridx_short(ctx, 0, DUK_STRIDX_LAST_INDEX);
- last_index = (duk_uint32_t) duk_get_uint(ctx, -1);
+ duk_get_prop_stridx_short(thr, 0, DUK_STRIDX_LAST_INDEX);
+ last_index = (duk_uint32_t) duk_get_uint(thr, -1);
DUK_DDD(DUK_DDDPRINT("empty match, bump lastIndex: %ld -> %ld",
(long) last_index, (long) (last_index + 1)));
- duk_pop(ctx);
- duk_push_int(ctx, last_index + 1);
- duk_put_prop_stridx_short(ctx, 0, DUK_STRIDX_LAST_INDEX);
+ duk_pop(thr);
+ duk_push_uint(thr, (duk_uint_t) (last_index + 1));
+ duk_put_prop_stridx_short(thr, 0, DUK_STRIDX_LAST_INDEX);
}
- DUK_ASSERT(duk_get_length(ctx, -1) <= DUK_INT_MAX); /* string limits */
- match_caps = (duk_int_t) duk_get_length(ctx, -1);
+ DUK_ASSERT(duk_get_length(thr, -1) <= DUK_INT_MAX); /* string limits */
+ match_caps = (duk_int_t) duk_get_length(thr, -1);
} else {
#else /* DUK_USE_REGEXP_SUPPORT */
{ /* unconditionally */
@@ -38067,7 +39350,7 @@ DUK_INTERNAL duk_ret_t duk_bi_string_prototype_replace(duk_context *ctx) {
p_end = p_start + DUK_HSTRING_GET_BYTELEN(h_input);
p = p_start;
- h_search = duk_known_hstring(ctx, 0);
+ h_search = duk_known_hstring(thr, 0);
q_start = DUK_HSTRING_GET_DATA(h_search);
q_blen = (duk_size_t) DUK_HSTRING_GET_BYTELEN(h_search);
@@ -38078,8 +39361,8 @@ DUK_INTERNAL duk_ret_t duk_bi_string_prototype_replace(duk_context *ctx) {
while (p <= p_end) {
DUK_ASSERT(p + q_blen <= DUK_HSTRING_GET_DATA(h_input) + DUK_HSTRING_GET_BYTELEN(h_input));
if (DUK_MEMCMP((const void *) p, (const void *) q_start, (size_t) q_blen) == 0) {
- duk_dup_0(ctx);
- h_match = duk_known_hstring(ctx, -1);
+ duk_dup_0(thr);
+ h_match = duk_known_hstring(thr, -1);
#if defined(DUK_USE_REGEXP_SUPPORT)
match_caps = 0;
#endif
@@ -38105,7 +39388,7 @@ DUK_INTERNAL duk_ret_t duk_bi_string_prototype_replace(duk_context *ctx) {
* stack[4] = regexp match OR match string
*/
- match_start_boff = duk_heap_strcache_offset_char2byte(thr, h_input, match_start_coff);
+ match_start_boff = (duk_uint32_t) duk_heap_strcache_offset_char2byte(thr, h_input, match_start_coff);
tmp_sz = (duk_size_t) (match_start_boff - prev_match_end_boff);
DUK_BW_WRITE_ENSURE_BYTES(thr, bw, DUK_HSTRING_GET_DATA(h_input) + prev_match_end_boff, tmp_sz);
@@ -38118,36 +39401,36 @@ DUK_INTERNAL duk_ret_t duk_bi_string_prototype_replace(duk_context *ctx) {
/* regexp res_obj is at index 4 */
- duk_dup_1(ctx);
- idx_args = duk_get_top(ctx);
+ duk_dup_1(thr);
+ idx_args = duk_get_top(thr);
#if defined(DUK_USE_REGEXP_SUPPORT)
if (is_regexp) {
duk_int_t idx;
- duk_require_stack(ctx, match_caps + 2);
+ duk_require_stack(thr, match_caps + 2);
for (idx = 0; idx < match_caps; idx++) {
/* match followed by capture(s) */
- duk_get_prop_index(ctx, 4, idx);
+ duk_get_prop_index(thr, 4, (duk_uarridx_t) idx);
}
} else {
#else /* DUK_USE_REGEXP_SUPPORT */
{ /* unconditionally */
#endif /* DUK_USE_REGEXP_SUPPORT */
/* match == search string, by definition */
- duk_dup_0(ctx);
+ duk_dup_0(thr);
}
- duk_push_int(ctx, match_start_coff);
- duk_dup_2(ctx);
+ duk_push_uint(thr, (duk_uint_t) match_start_coff);
+ duk_dup_2(thr);
/* [ ... replacer match [captures] match_char_offset input ] */
- duk_call(ctx, duk_get_top(ctx) - idx_args);
- h_repl = duk_to_hstring_m1(ctx); /* -> [ ... repl_value ] */
+ duk_call(thr, duk_get_top(thr) - idx_args);
+ h_repl = duk_to_hstring_m1(thr); /* -> [ ... repl_value ] */
DUK_ASSERT(h_repl != NULL);
DUK_BW_WRITE_ENSURE_HSTRING(thr, bw, h_repl);
- duk_pop(ctx); /* repl_value */
+ duk_pop(thr); /* repl_value */
} else {
r = r_start;
@@ -38163,7 +39446,8 @@ DUK_INTERNAL duk_ret_t duk_bi_string_prototype_replace(duk_context *ctx) {
if (ch1 != DUK_ASC_DOLLAR) {
goto repl_write;
}
- left = r_end - r;
+ DUK_ASSERT(r <= r_end);
+ left = (duk_size_t) (r_end - r);
if (left <= 0) {
goto repl_write;
@@ -38193,9 +39477,9 @@ DUK_INTERNAL duk_ret_t duk_bi_string_prototype_replace(duk_context *ctx) {
* match codepoint encodings would have different lengths.
*/
/* XXX: charlen computed here, and also in char2byte helper. */
- match_end_boff = duk_heap_strcache_offset_char2byte(thr,
- h_input,
- match_start_coff + (duk_uint_fast32_t) DUK_HSTRING_GET_CHARLEN(h_match));
+ match_end_boff = (duk_uint32_t) duk_heap_strcache_offset_char2byte(thr,
+ h_input,
+ match_start_coff + (duk_uint_fast32_t) DUK_HSTRING_GET_CHARLEN(h_match));
tmp_sz = (duk_size_t) (DUK_HSTRING_GET_BYTELEN(h_input) - match_end_boff);
DUK_BW_WRITE_ENSURE_BYTES(thr, bw, DUK_HSTRING_GET_DATA(h_input) + match_end_boff, tmp_sz);
@@ -38234,17 +39518,17 @@ DUK_INTERNAL duk_ret_t duk_bi_string_prototype_replace(duk_context *ctx) {
DUK_ASSERT(is_regexp != 0); /* match_caps == 0 without regexps */
/* regexp res_obj is at offset 4 */
- duk_get_prop_index(ctx, 4, (duk_uarridx_t) capnum);
- if (duk_is_string(ctx, -1)) {
+ duk_get_prop_index(thr, 4, (duk_uarridx_t) capnum);
+ if (duk_is_string(thr, -1)) {
duk_hstring *h_tmp_str;
- h_tmp_str = duk_known_hstring(ctx, -1);
+ h_tmp_str = duk_known_hstring(thr, -1);
DUK_BW_WRITE_ENSURE_HSTRING(thr, bw, h_tmp_str);
} else {
/* undefined -> skip (replaced with empty) */
}
- duk_pop(ctx);
+ duk_pop(thr);
r += capadv;
continue;
} else {
@@ -38264,7 +39548,7 @@ DUK_INTERNAL duk_ret_t duk_bi_string_prototype_replace(duk_context *ctx) {
} /* while repl */
} /* if (is_repl_func) */
- duk_pop(ctx); /* pop regexp res_obj or match string */
+ duk_pop(thr); /* pop regexp res_obj or match string */
#if defined(DUK_USE_REGEXP_SUPPORT)
if (!is_global) {
@@ -38279,9 +39563,9 @@ DUK_INTERNAL duk_ret_t duk_bi_string_prototype_replace(duk_context *ctx) {
tmp_sz = (duk_size_t) (DUK_HSTRING_GET_BYTELEN(h_input) - prev_match_end_boff);
DUK_BW_WRITE_ENSURE_BYTES(thr, bw, DUK_HSTRING_GET_DATA(h_input) + prev_match_end_boff, tmp_sz);
- DUK_ASSERT_TOP(ctx, 4);
+ DUK_ASSERT_TOP(thr, 4);
DUK_BW_COMPACT(thr, bw);
- (void) duk_buffer_to_string(ctx, -1); /* Safe if inputs are safe. */
+ (void) duk_buffer_to_string(thr, -1); /* Safe if inputs are safe. */
return 1;
}
@@ -38293,8 +39577,7 @@ DUK_INTERNAL duk_ret_t duk_bi_string_prototype_replace(duk_context *ctx) {
* used so compiler doesn't complain).
*/
-DUK_INTERNAL duk_ret_t duk_bi_string_prototype_split(duk_context *ctx) {
- duk_hthread *thr = (duk_hthread *) ctx;
+DUK_INTERNAL duk_ret_t duk_bi_string_prototype_split(duk_hthread *thr) {
duk_hstring *h_input;
duk_hstring *h_sep;
duk_uint32_t limit;
@@ -38307,17 +39590,15 @@ DUK_INTERNAL duk_ret_t duk_bi_string_prototype_split(duk_context *ctx) {
duk_uint32_t match_start_boff, match_start_coff;
duk_uint32_t match_end_boff, match_end_coff;
- DUK_UNREF(thr);
-
- h_input = duk_push_this_coercible_to_string(ctx);
+ h_input = duk_push_this_coercible_to_string(thr);
DUK_ASSERT(h_input != NULL);
- duk_push_array(ctx);
+ duk_push_array(thr);
- if (duk_is_undefined(ctx, 1)) {
+ if (duk_is_undefined(thr, 1)) {
limit = 0xffffffffUL;
} else {
- limit = duk_to_uint32(ctx, 1);
+ limit = duk_to_uint32(thr, 1);
}
if (limit == 0) {
@@ -38330,27 +39611,27 @@ DUK_INTERNAL duk_ret_t duk_bi_string_prototype_split(duk_context *ctx) {
* which will use global-style matching even when the RegExp itself is non-global.
*/
- if (duk_is_undefined(ctx, 0)) {
+ if (duk_is_undefined(thr, 0)) {
/* The spec algorithm first does "R = ToString(separator)" before checking
* whether separator is undefined. Since this is side effect free, we can
* skip the ToString() here.
*/
- duk_dup_2(ctx);
- duk_put_prop_index(ctx, 3, 0);
+ duk_dup_2(thr);
+ duk_put_prop_index(thr, 3, 0);
return 1;
- } else if (duk_get_hobject_with_class(ctx, 0, DUK_HOBJECT_CLASS_REGEXP) != NULL) {
+ } else if (duk_get_hobject_with_class(thr, 0, DUK_HOBJECT_CLASS_REGEXP) != NULL) {
#if defined(DUK_USE_REGEXP_SUPPORT)
- duk_push_hobject_bidx(ctx, DUK_BIDX_REGEXP_CONSTRUCTOR);
- duk_dup_0(ctx);
- duk_new(ctx, 1); /* [ ... RegExp val ] -> [ ... res ] */
- duk_replace(ctx, 0);
+ duk_push_hobject_bidx(thr, DUK_BIDX_REGEXP_CONSTRUCTOR);
+ duk_dup_0(thr);
+ duk_new(thr, 1); /* [ ... RegExp val ] -> [ ... res ] */
+ duk_replace(thr, 0);
/* lastIndex is initialized to zero by new RegExp() */
is_regexp = 1;
#else
DUK_DCERROR_UNSUPPORTED(thr);
#endif
} else {
- duk_to_string(ctx, 0);
+ duk_to_string(thr, 0);
#if defined(DUK_USE_REGEXP_SUPPORT)
is_regexp = 0;
#endif
@@ -38375,42 +39656,42 @@ DUK_INTERNAL duk_ret_t duk_bi_string_prototype_split(duk_context *ctx) {
* special variant which forces global-like behavior for matching.
*/
- DUK_ASSERT_TOP(ctx, 4);
+ DUK_ASSERT_TOP(thr, 4);
#if defined(DUK_USE_REGEXP_SUPPORT)
if (is_regexp) {
- duk_dup_0(ctx);
- duk_dup_2(ctx);
+ duk_dup_0(thr);
+ duk_dup_2(thr);
duk_regexp_match_force_global(thr); /* [ ... regexp input ] -> [ res_obj ] */
- if (!duk_is_object(ctx, -1)) {
- duk_pop(ctx);
+ if (!duk_is_object(thr, -1)) {
+ duk_pop(thr);
break;
}
matched = 1;
- duk_get_prop_stridx_short(ctx, -1, DUK_STRIDX_INDEX);
- DUK_ASSERT(duk_is_number(ctx, -1));
- match_start_coff = duk_get_int(ctx, -1);
- match_start_boff = duk_heap_strcache_offset_char2byte(thr, h_input, match_start_coff);
- duk_pop(ctx);
+ duk_get_prop_stridx_short(thr, -1, DUK_STRIDX_INDEX);
+ DUK_ASSERT(duk_is_number(thr, -1));
+ match_start_coff = duk_get_uint(thr, -1);
+ match_start_boff = (duk_uint32_t) duk_heap_strcache_offset_char2byte(thr, h_input, match_start_coff);
+ duk_pop(thr);
if (match_start_coff == DUK_HSTRING_GET_CHARLEN(h_input)) {
/* don't allow an empty match at the end of the string */
- duk_pop(ctx);
+ duk_pop(thr);
break;
}
- duk_get_prop_stridx_short(ctx, 0, DUK_STRIDX_LAST_INDEX);
- DUK_ASSERT(duk_is_number(ctx, -1));
- match_end_coff = duk_get_int(ctx, -1);
- match_end_boff = duk_heap_strcache_offset_char2byte(thr, h_input, match_end_coff);
- duk_pop(ctx);
+ duk_get_prop_stridx_short(thr, 0, DUK_STRIDX_LAST_INDEX);
+ DUK_ASSERT(duk_is_number(thr, -1));
+ match_end_coff = duk_get_uint(thr, -1);
+ match_end_boff = (duk_uint32_t) duk_heap_strcache_offset_char2byte(thr, h_input, match_end_coff);
+ duk_pop(thr);
/* empty match -> bump and continue */
if (prev_match_end_boff == match_end_boff) {
- duk_push_int(ctx, match_end_coff + 1);
- duk_put_prop_stridx_short(ctx, 0, DUK_STRIDX_LAST_INDEX);
- duk_pop(ctx);
+ duk_push_uint(thr, (duk_uint_t) (match_end_coff + 1));
+ duk_put_prop_stridx_short(thr, 0, DUK_STRIDX_LAST_INDEX);
+ duk_pop(thr);
continue;
}
} else {
@@ -38425,7 +39706,7 @@ DUK_INTERNAL duk_ret_t duk_bi_string_prototype_split(duk_context *ctx) {
p_end = p_start + DUK_HSTRING_GET_BYTELEN(h_input);
p = p_start + prev_match_end_boff;
- h_sep = duk_known_hstring(ctx, 0); /* symbol already rejected above */
+ h_sep = duk_known_hstring(thr, 0); /* symbol already rejected above */
q_start = DUK_HSTRING_GET_DATA(h_sep);
q_blen = (duk_size_t) DUK_HSTRING_GET_BYTELEN(h_sep);
q_clen = (duk_size_t) DUK_HSTRING_GET_CHARLEN(h_sep);
@@ -38502,10 +39783,10 @@ DUK_INTERNAL duk_ret_t duk_bi_string_prototype_split(duk_context *ctx) {
(long) match_end_boff, (long) match_end_coff,
(long) prev_match_end_boff, (long) prev_match_end_coff));
- duk_push_lstring(ctx,
+ duk_push_lstring(thr,
(const char *) (DUK_HSTRING_GET_DATA(h_input) + prev_match_end_boff),
(duk_size_t) (match_start_boff - prev_match_end_boff));
- duk_put_prop_index(ctx, 3, arr_idx);
+ duk_put_prop_index(thr, 3, arr_idx);
arr_idx++;
if (arr_idx >= limit) {
goto hit_limit;
@@ -38515,18 +39796,18 @@ DUK_INTERNAL duk_ret_t duk_bi_string_prototype_split(duk_context *ctx) {
if (is_regexp) {
duk_size_t i, len;
- len = duk_get_length(ctx, 4);
+ len = duk_get_length(thr, 4);
for (i = 1; i < len; i++) {
DUK_ASSERT(i <= DUK_UARRIDX_MAX); /* cannot have >4G captures */
- duk_get_prop_index(ctx, 4, (duk_uarridx_t) i);
- duk_put_prop_index(ctx, 3, arr_idx);
+ duk_get_prop_index(thr, 4, (duk_uarridx_t) i);
+ duk_put_prop_index(thr, 3, arr_idx);
arr_idx++;
if (arr_idx >= limit) {
goto hit_limit;
}
}
- duk_pop(ctx);
+ duk_pop(thr);
/* lastIndex already set up for next match */
} else {
#else /* DUK_USE_REGEXP_SUPPORT */
@@ -38551,10 +39832,10 @@ DUK_INTERNAL duk_ret_t duk_bi_string_prototype_split(duk_context *ctx) {
* b) empty input and no (zero size) match found (step 11)
*/
- duk_push_lstring(ctx,
+ duk_push_lstring(thr,
(const char *) DUK_HSTRING_GET_DATA(h_input) + prev_match_end_boff,
(duk_size_t) (DUK_HSTRING_GET_BYTELEN(h_input) - prev_match_end_boff));
- duk_put_prop_index(ctx, 3, arr_idx);
+ duk_put_prop_index(thr, 3, arr_idx);
/* No arr_idx update or limit check */
}
@@ -38563,7 +39844,7 @@ DUK_INTERNAL duk_ret_t duk_bi_string_prototype_split(duk_context *ctx) {
hit_limit:
#if defined(DUK_USE_REGEXP_SUPPORT)
if (is_regexp) {
- duk_pop(ctx);
+ duk_pop(thr);
}
#endif
@@ -38575,7 +39856,7 @@ DUK_INTERNAL duk_ret_t duk_bi_string_prototype_split(duk_context *ctx) {
*/
#if defined(DUK_USE_REGEXP_SUPPORT)
-DUK_LOCAL void duk__to_regexp_helper(duk_context *ctx, duk_idx_t idx, duk_bool_t force_new) {
+DUK_LOCAL void duk__to_regexp_helper(duk_hthread *thr, duk_idx_t idx, duk_bool_t force_new) {
duk_hobject *h;
/* Shared helper for match() steps 3-4, search() steps 3-4. */
@@ -38586,24 +39867,22 @@ DUK_LOCAL void duk__to_regexp_helper(duk_context *ctx, duk_idx_t idx, duk_bool_t
goto do_new;
}
- h = duk_get_hobject_with_class(ctx, idx, DUK_HOBJECT_CLASS_REGEXP);
+ h = duk_get_hobject_with_class(thr, idx, DUK_HOBJECT_CLASS_REGEXP);
if (!h) {
goto do_new;
}
return;
do_new:
- duk_push_hobject_bidx(ctx, DUK_BIDX_REGEXP_CONSTRUCTOR);
- duk_dup(ctx, idx);
- duk_new(ctx, 1); /* [ ... RegExp val ] -> [ ... res ] */
- duk_replace(ctx, idx);
+ duk_push_hobject_bidx(thr, DUK_BIDX_REGEXP_CONSTRUCTOR);
+ duk_dup(thr, idx);
+ duk_new(thr, 1); /* [ ... RegExp val ] -> [ ... res ] */
+ duk_replace(thr, idx);
}
#endif /* DUK_USE_REGEXP_SUPPORT */
#if defined(DUK_USE_REGEXP_SUPPORT)
-DUK_INTERNAL duk_ret_t duk_bi_string_prototype_search(duk_context *ctx) {
- duk_hthread *thr = (duk_hthread *) ctx;
-
+DUK_INTERNAL duk_ret_t duk_bi_string_prototype_search(duk_hthread *thr) {
/* Easiest way to implement the search required by the specification
* is to do a RegExp test() with lastIndex forced to zero. To avoid
* side effects on the argument, "clone" the RegExp if a RegExp was
@@ -38614,9 +39893,9 @@ DUK_INTERNAL duk_ret_t duk_bi_string_prototype_search(duk_context *ctx) {
* equivalent effect.
*/
- DUK_ASSERT_TOP(ctx, 1);
- (void) duk_push_this_coercible_to_string(ctx); /* at index 1 */
- duk__to_regexp_helper(ctx, 0 /*index*/, 1 /*force_new*/);
+ DUK_ASSERT_TOP(thr, 1);
+ (void) duk_push_this_coercible_to_string(thr); /* at index 1 */
+ duk__to_regexp_helper(thr, 0 /*index*/, 1 /*force_new*/);
/* stack[0] = regexp
* stack[1] = string
@@ -38626,34 +39905,33 @@ DUK_INTERNAL duk_ret_t duk_bi_string_prototype_search(duk_context *ctx) {
* configurable and may have been changed.
*/
- duk_dup_0(ctx);
- duk_dup_1(ctx); /* [ ... re_obj input ] */
+ duk_dup_0(thr);
+ duk_dup_1(thr); /* [ ... re_obj input ] */
duk_regexp_match(thr); /* -> [ ... res_obj ] */
- if (!duk_is_object(ctx, -1)) {
- duk_push_int(ctx, -1);
+ if (!duk_is_object(thr, -1)) {
+ duk_push_int(thr, -1);
return 1;
}
- duk_get_prop_stridx_short(ctx, -1, DUK_STRIDX_INDEX);
- DUK_ASSERT(duk_is_number(ctx, -1));
+ duk_get_prop_stridx_short(thr, -1, DUK_STRIDX_INDEX);
+ DUK_ASSERT(duk_is_number(thr, -1));
return 1;
}
#endif /* DUK_USE_REGEXP_SUPPORT */
#if defined(DUK_USE_REGEXP_SUPPORT)
-DUK_INTERNAL duk_ret_t duk_bi_string_prototype_match(duk_context *ctx) {
- duk_hthread *thr = (duk_hthread *) ctx;
+DUK_INTERNAL duk_ret_t duk_bi_string_prototype_match(duk_hthread *thr) {
duk_bool_t global;
duk_int_t prev_last_index;
duk_int_t this_index;
duk_int_t arr_idx;
- DUK_ASSERT_TOP(ctx, 1);
- (void) duk_push_this_coercible_to_string(ctx);
- duk__to_regexp_helper(ctx, 0 /*index*/, 0 /*force_new*/);
- global = duk_get_prop_stridx_boolean(ctx, 0, DUK_STRIDX_GLOBAL, NULL);
- DUK_ASSERT_TOP(ctx, 2);
+ DUK_ASSERT_TOP(thr, 1);
+ (void) duk_push_this_coercible_to_string(thr);
+ duk__to_regexp_helper(thr, 0 /*index*/, 0 /*force_new*/);
+ global = duk_get_prop_stridx_boolean(thr, 0, DUK_STRIDX_GLOBAL, NULL);
+ DUK_ASSERT_TOP(thr, 2);
/* stack[0] = regexp
* stack[1] = string
@@ -38668,9 +39946,9 @@ DUK_INTERNAL duk_ret_t duk_bi_string_prototype_match(duk_context *ctx) {
/* [ regexp string ] */
- duk_push_int(ctx, 0);
- duk_put_prop_stridx_short(ctx, 0, DUK_STRIDX_LAST_INDEX);
- duk_push_array(ctx);
+ duk_push_int(thr, 0);
+ duk_put_prop_stridx_short(thr, 0, DUK_STRIDX_LAST_INDEX);
+ duk_push_array(thr);
/* [ regexp string res_arr ] */
@@ -38678,61 +39956,61 @@ DUK_INTERNAL duk_ret_t duk_bi_string_prototype_match(duk_context *ctx) {
arr_idx = 0;
for (;;) {
- DUK_ASSERT_TOP(ctx, 3);
+ DUK_ASSERT_TOP(thr, 3);
- duk_dup_0(ctx);
- duk_dup_1(ctx);
+ duk_dup_0(thr);
+ duk_dup_1(thr);
duk_regexp_match(thr); /* -> [ ... regexp string ] -> [ ... res_obj ] */
- if (!duk_is_object(ctx, -1)) {
- duk_pop(ctx);
+ if (!duk_is_object(thr, -1)) {
+ duk_pop(thr);
break;
}
- duk_get_prop_stridx_short(ctx, 0, DUK_STRIDX_LAST_INDEX);
- DUK_ASSERT(duk_is_number(ctx, -1));
- this_index = duk_get_int(ctx, -1);
- duk_pop(ctx);
+ duk_get_prop_stridx_short(thr, 0, DUK_STRIDX_LAST_INDEX);
+ DUK_ASSERT(duk_is_number(thr, -1));
+ this_index = duk_get_int(thr, -1);
+ duk_pop(thr);
if (this_index == prev_last_index) {
this_index++;
- duk_push_int(ctx, this_index);
- duk_put_prop_stridx_short(ctx, 0, DUK_STRIDX_LAST_INDEX);
+ duk_push_int(thr, this_index);
+ duk_put_prop_stridx_short(thr, 0, DUK_STRIDX_LAST_INDEX);
}
prev_last_index = this_index;
- duk_get_prop_index(ctx, -1, 0); /* match string */
- duk_put_prop_index(ctx, 2, arr_idx);
+ duk_get_prop_index(thr, -1, 0); /* match string */
+ duk_put_prop_index(thr, 2, (duk_uarridx_t) arr_idx);
arr_idx++;
- duk_pop(ctx); /* res_obj */
+ duk_pop(thr); /* res_obj */
}
if (arr_idx == 0) {
- duk_push_null(ctx);
+ duk_push_null(thr);
}
return 1; /* return 'res_arr' or 'null' */
}
#endif /* DUK_USE_REGEXP_SUPPORT */
-DUK_INTERNAL duk_ret_t duk_bi_string_prototype_concat(duk_context *ctx) {
+DUK_INTERNAL duk_ret_t duk_bi_string_prototype_concat(duk_hthread *thr) {
/* duk_concat() coerces arguments with ToString() in correct order */
- (void) duk_push_this_coercible_to_string(ctx);
- duk_insert(ctx, 0); /* this is relatively expensive */
- duk_concat(ctx, duk_get_top(ctx));
+ (void) duk_push_this_coercible_to_string(thr);
+ duk_insert(thr, 0); /* this is relatively expensive */
+ duk_concat(thr, duk_get_top(thr));
return 1;
}
-DUK_INTERNAL duk_ret_t duk_bi_string_prototype_trim(duk_context *ctx) {
- DUK_ASSERT_TOP(ctx, 0);
- (void) duk_push_this_coercible_to_string(ctx);
- duk_trim(ctx, 0);
- DUK_ASSERT_TOP(ctx, 1);
+DUK_INTERNAL duk_ret_t duk_bi_string_prototype_trim(duk_hthread *thr) {
+ DUK_ASSERT_TOP(thr, 0);
+ (void) duk_push_this_coercible_to_string(thr);
+ duk_trim(thr, 0);
+ DUK_ASSERT_TOP(thr, 1);
return 1;
}
#if defined(DUK_USE_ES6)
-DUK_INTERNAL duk_ret_t duk_bi_string_prototype_repeat(duk_context *ctx) {
+DUK_INTERNAL duk_ret_t duk_bi_string_prototype_repeat(duk_hthread *thr) {
duk_hstring *h_input;
duk_size_t input_blen;
duk_size_t result_len;
@@ -38747,8 +40025,8 @@ DUK_INTERNAL duk_ret_t duk_bi_string_prototype_repeat(duk_context *ctx) {
duk_uint8_t *p_end;
#endif
- DUK_ASSERT_TOP(ctx, 1);
- h_input = duk_push_this_coercible_to_string(ctx);
+ DUK_ASSERT_TOP(thr, 1);
+ h_input = duk_push_this_coercible_to_string(thr);
DUK_ASSERT(h_input != NULL);
input_blen = DUK_HSTRING_GET_BYTELEN(h_input);
@@ -38758,11 +40036,11 @@ DUK_INTERNAL duk_ret_t duk_bi_string_prototype_repeat(duk_context *ctx) {
* because duk_get_int() clamps it to DUK_INT_MIN which gets rejected
* as a negative value (regardless of input string length).
*/
- d = duk_to_number(ctx, 0);
+ d = duk_to_number(thr, 0);
if (duk_double_is_posinf(d)) {
goto fail_range;
}
- count_signed = duk_get_int(ctx, 0);
+ count_signed = duk_get_int(thr, 0);
if (count_signed < 0) {
goto fail_range;
}
@@ -38775,7 +40053,7 @@ DUK_INTERNAL duk_ret_t duk_bi_string_prototype_repeat(duk_context *ctx) {
}
/* Temporary fixed buffer, later converted to string. */
- buf = (duk_uint8_t *) duk_push_fixed_buffer_nozero(ctx, result_len);
+ buf = (duk_uint8_t *) duk_push_fixed_buffer_nozero(thr, result_len);
src = (const duk_uint8_t *) DUK_HSTRING_GET_DATA(h_input);
#if defined(DUK_USE_PREFER_SIZE)
@@ -38821,15 +40099,15 @@ DUK_INTERNAL duk_ret_t duk_bi_string_prototype_repeat(duk_context *ctx) {
* intern table (they are not in heap_allocated).
*/
- duk_buffer_to_string(ctx, -1); /* Safe if input is safe. */
+ duk_buffer_to_string(thr, -1); /* Safe if input is safe. */
return 1;
fail_range:
- DUK_DCERROR_RANGE_INVALID_ARGS((duk_hthread *) ctx);
+ DUK_DCERROR_RANGE_INVALID_ARGS(thr);
}
#endif /* DUK_USE_ES6 */
-DUK_INTERNAL duk_ret_t duk_bi_string_prototype_locale_compare(duk_context *ctx) {
+DUK_INTERNAL duk_ret_t duk_bi_string_prototype_locale_compare(duk_hthread *thr) {
duk_hstring *h1;
duk_hstring *h2;
duk_size_t h1_len, h2_len, prefix_len;
@@ -38848,10 +40126,10 @@ DUK_INTERNAL duk_ret_t duk_bi_string_prototype_locale_compare(duk_context *ctx)
/* XXX: could share code with duk_js_ops.c, duk_js_compare_helper */
- h1 = duk_push_this_coercible_to_string(ctx);
+ h1 = duk_push_this_coercible_to_string(thr);
DUK_ASSERT(h1 != NULL);
- h2 = duk_to_hstring(ctx, 0);
+ h2 = duk_to_hstring(thr, 0);
DUK_ASSERT(h2 != NULL);
h1_len = (duk_size_t) DUK_HSTRING_GET_BYTELEN(h1);
@@ -38883,12 +40161,12 @@ DUK_INTERNAL duk_ret_t duk_bi_string_prototype_locale_compare(duk_context *ctx)
goto done;
done:
- duk_push_int(ctx, (duk_int_t) ret);
+ duk_push_int(thr, (duk_int_t) ret);
return 1;
}
#if defined(DUK_USE_ES6)
-DUK_INTERNAL duk_ret_t duk_bi_string_prototype_startswith_endswith(duk_context *ctx) {
+DUK_INTERNAL duk_ret_t duk_bi_string_prototype_startswith_endswith(duk_hthread *thr) {
duk_int_t magic;
duk_hstring *h;
duk_hstring *h_search;
@@ -38896,18 +40174,18 @@ DUK_INTERNAL duk_ret_t duk_bi_string_prototype_startswith_endswith(duk_context *
const duk_uint8_t *p_cmp_start;
duk_bool_t result;
- h = duk_push_this_coercible_to_string(ctx);
+ h = duk_push_this_coercible_to_string(thr);
DUK_ASSERT(h != NULL);
- h_search = duk__str_tostring_notregexp(ctx, 0);
+ h_search = duk__str_tostring_notregexp(thr, 0);
DUK_ASSERT(h_search != NULL);
- magic = duk_get_current_magic(ctx);
+ magic = duk_get_current_magic(thr);
p_cmp_start = (const duk_uint8_t *) DUK_HSTRING_GET_DATA(h);
blen_search = DUK_HSTRING_GET_BYTELEN(h_search);
- if (duk_is_undefined(ctx, 1)) {
+ if (duk_is_undefined(thr, 1)) {
if (magic) {
p_cmp_start += DUK_HSTRING_GET_BYTELEN(h) - blen_search;
} else {
@@ -38919,7 +40197,7 @@ DUK_INTERNAL duk_ret_t duk_bi_string_prototype_startswith_endswith(duk_context *
DUK_ASSERT(DUK_HSTRING_MAX_BYTELEN <= DUK_INT_MAX);
len = (duk_int_t) DUK_HSTRING_GET_CHARLEN(h);
- pos = duk_to_int_clamped(ctx, 1, 0, len);
+ pos = duk_to_int_clamped(thr, 1, 0, len);
DUK_ASSERT(pos >= 0 && pos <= len);
if (magic) {
@@ -38927,7 +40205,7 @@ DUK_INTERNAL duk_ret_t duk_bi_string_prototype_startswith_endswith(duk_context *
}
DUK_ASSERT(pos >= 0 && pos <= len);
- p_cmp_start += duk_heap_strcache_offset_char2byte((duk_hthread *) ctx, h, pos);
+ p_cmp_start += duk_heap_strcache_offset_char2byte(thr, h, (duk_uint_fast32_t) pos);
}
/* The main comparison can be done using a memcmp() rather than
@@ -38939,7 +40217,7 @@ DUK_INTERNAL duk_ret_t duk_bi_string_prototype_startswith_endswith(duk_context *
result = 0;
if (p_cmp_start >= DUK_HSTRING_GET_DATA(h) &&
- p_cmp_start - (const duk_uint8_t *) DUK_HSTRING_GET_DATA(h) + blen_search <= DUK_HSTRING_GET_BYTELEN(h)) {
+ (duk_size_t) (p_cmp_start - (const duk_uint8_t *) DUK_HSTRING_GET_DATA(h)) + blen_search <= DUK_HSTRING_GET_BYTELEN(h)) {
if (DUK_MEMCMP((const void *) p_cmp_start,
(const void *) DUK_HSTRING_GET_DATA(h_search),
(size_t) blen_search) == 0) {
@@ -38947,30 +40225,30 @@ DUK_INTERNAL duk_ret_t duk_bi_string_prototype_startswith_endswith(duk_context *
}
}
- duk_push_boolean(ctx, result);
+ duk_push_boolean(thr, result);
return 1;
}
#endif /* DUK_USE_ES6 */
#if defined(DUK_USE_ES6)
-DUK_INTERNAL duk_ret_t duk_bi_string_prototype_includes(duk_context *ctx) {
+DUK_INTERNAL duk_ret_t duk_bi_string_prototype_includes(duk_hthread *thr) {
duk_hstring *h;
duk_hstring *h_search;
duk_int_t len;
duk_int_t pos;
- h = duk_push_this_coercible_to_string(ctx);
+ h = duk_push_this_coercible_to_string(thr);
DUK_ASSERT(h != NULL);
- h_search = duk__str_tostring_notregexp(ctx, 0);
+ h_search = duk__str_tostring_notregexp(thr, 0);
DUK_ASSERT(h_search != NULL);
len = (duk_int_t) DUK_HSTRING_GET_CHARLEN(h);
- pos = duk_to_int_clamped(ctx, 1, 0, len);
+ pos = duk_to_int_clamped(thr, 1, 0, len);
DUK_ASSERT(pos >= 0 && pos <= len);
- pos = duk__str_search_shared(ctx, h, h_search, pos, 0 /*backwards*/);
- duk_push_boolean(ctx, pos >= 0);
+ pos = duk__str_search_shared(thr, h, h_search, pos, 0 /*backwards*/);
+ duk_push_boolean(thr, pos >= 0);
return 1;
}
#endif /* DUK_USE_ES6 */
@@ -38987,18 +40265,15 @@ DUK_INTERNAL duk_ret_t duk_bi_string_prototype_includes(duk_context *ctx) {
* Constructor
*/
-DUK_INTERNAL duk_ret_t duk_bi_symbol_constructor_shared(duk_context *ctx) {
- duk_hthread *thr;
+DUK_INTERNAL duk_ret_t duk_bi_symbol_constructor_shared(duk_hthread *thr) {
const duk_uint8_t *desc;
duk_size_t len;
duk_uint8_t *buf;
duk_uint8_t *p;
duk_int_t magic;
- thr = (duk_hthread *) ctx;
-
- magic = duk_get_current_magic(ctx);
- if (duk_is_undefined(ctx, 0) && (magic == 0)) {
+ magic = duk_get_current_magic(thr);
+ if (duk_is_undefined(thr, 0) && (magic == 0)) {
/* Symbol() accepts undefined and empty string, but they are
* treated differently.
*/
@@ -39006,7 +40281,7 @@ DUK_INTERNAL duk_ret_t duk_bi_symbol_constructor_shared(duk_context *ctx) {
len = 0;
} else {
/* Symbol.for() coerces undefined to 'undefined' */
- desc = (const duk_uint8_t *) duk_to_lstring(ctx, 0, &len);
+ desc = (const duk_uint8_t *) duk_to_lstring(thr, 0, &len);
}
/* Maximum symbol data length:
@@ -39016,7 +40291,7 @@ DUK_INTERNAL duk_ret_t duk_bi_symbol_constructor_shared(duk_context *ctx) {
* +17 autogenerated unique suffix: 'ffffffff-ffffffff' is longest
* +1 0xff after unique suffix for symbols with undefined description
*/
- buf = (duk_uint8_t *) duk_push_fixed_buffer(ctx, 1 + len + 1 + 17 + 1);
+ buf = (duk_uint8_t *) duk_push_fixed_buffer(thr, 1 + len + 1 + 17 + 1);
p = buf + 1;
DUK_ASSERT(desc != NULL || len == 0); /* may be NULL if len is 0 */
DUK_MEMCPY((void *) p, (const void *) desc, len);
@@ -39045,12 +40320,12 @@ DUK_INTERNAL duk_ret_t duk_bi_symbol_constructor_shared(duk_context *ctx) {
buf[0] = 0x80;
}
- duk_push_lstring(ctx, (const char *) buf, (duk_size_t) (p - buf));
- DUK_DDD(DUK_DDDPRINT("created symbol: %!T", duk_get_tval(ctx, -1)));
+ duk_push_lstring(thr, (const char *) buf, (duk_size_t) (p - buf));
+ DUK_DDD(DUK_DDDPRINT("created symbol: %!T", duk_get_tval(thr, -1)));
return 1;
}
-DUK_LOCAL duk_hstring *duk__auto_unbox_symbol(duk_context *ctx, duk_tval *tv_arg) {
+DUK_LOCAL duk_hstring *duk__auto_unbox_symbol(duk_hthread *thr, duk_tval *tv_arg) {
duk_tval *tv;
duk_tval tv_val;
duk_hobject *h_obj;
@@ -39058,15 +40333,15 @@ DUK_LOCAL duk_hstring *duk__auto_unbox_symbol(duk_context *ctx, duk_tval *tv_arg
DUK_ASSERT(tv_arg != NULL);
- /* XXX: add internal helper: duk_auto_unbox_tval(ctx, tv, mask); */
- /* XXX: add internal helper: duk_auto_unbox(ctx, tv, idx); */
+ /* XXX: add internal helper: duk_auto_unbox_tval(thr, tv, mask); */
+ /* XXX: add internal helper: duk_auto_unbox(thr, tv, idx); */
tv = tv_arg;
if (DUK_TVAL_IS_OBJECT(tv)) {
h_obj = DUK_TVAL_GET_OBJECT(tv);
DUK_ASSERT(h_obj != NULL);
if (DUK_HOBJECT_GET_CLASS_NUMBER(h_obj) == DUK_HOBJECT_CLASS_SYMBOL) {
- if (!duk_hobject_get_internal_value(((duk_hthread *) ctx)->heap, h_obj, &tv_val)) {
+ if (!duk_hobject_get_internal_value(thr->heap, h_obj, &tv_val)) {
return NULL;
}
tv = &tv_val;
@@ -39089,32 +40364,32 @@ DUK_LOCAL duk_hstring *duk__auto_unbox_symbol(duk_context *ctx, duk_tval *tv_arg
return h_str;
}
-DUK_INTERNAL duk_ret_t duk_bi_symbol_tostring_shared(duk_context *ctx) {
+DUK_INTERNAL duk_ret_t duk_bi_symbol_tostring_shared(duk_hthread *thr) {
duk_hstring *h_str;
- h_str = duk__auto_unbox_symbol(ctx, DUK_HTHREAD_THIS_PTR((duk_hthread *) ctx));
+ h_str = duk__auto_unbox_symbol(thr, DUK_HTHREAD_THIS_PTR(thr));
if (h_str == NULL) {
return DUK_RET_TYPE_ERROR;
}
- if (duk_get_current_magic(ctx) == 0) {
+ if (duk_get_current_magic(thr) == 0) {
/* .toString() */
- duk_push_symbol_descriptive_string(ctx, h_str);
+ duk_push_symbol_descriptive_string(thr, h_str);
} else {
/* .valueOf() */
- duk_push_hstring(ctx, h_str);
+ duk_push_hstring(thr, h_str);
}
return 1;
}
-DUK_INTERNAL duk_ret_t duk_bi_symbol_key_for(duk_context *ctx) {
+DUK_INTERNAL duk_ret_t duk_bi_symbol_key_for(duk_hthread *thr) {
duk_hstring *h;
const duk_uint8_t *p;
/* Argument must be a symbol but not checked here. The initial byte
* check will catch non-symbol strings.
*/
- h = duk_require_hstring(ctx, 0);
+ h = duk_require_hstring(thr, 0);
DUK_ASSERT(h != NULL);
p = (const duk_uint8_t *) DUK_HSTRING_GET_DATA(h);
@@ -39125,9 +40400,9 @@ DUK_INTERNAL duk_ret_t duk_bi_symbol_key_for(duk_context *ctx) {
*/
if (p[0] == 0x80) {
/* Global symbol, return its key (bytes just after the initial byte). */
- duk_push_lstring(ctx, (const char *) (p + 1), DUK_HSTRING_GET_BYTELEN(h) - 1);
+ duk_push_lstring(thr, (const char *) (p + 1), (duk_size_t) (DUK_HSTRING_GET_BYTELEN(h) - 1));
return 1;
- } else if (p[0] == 0x81 || p[0] == 0xff) {
+ } else if (p[0] == 0x81 || p[0] == 0x82 || p[0] == 0xff) {
/* Local symbol or hidden symbol, return undefined. */
return 0;
}
@@ -39136,14 +40411,14 @@ DUK_INTERNAL duk_ret_t duk_bi_symbol_key_for(duk_context *ctx) {
return DUK_RET_TYPE_ERROR;
}
-DUK_INTERNAL duk_ret_t duk_bi_symbol_toprimitive(duk_context *ctx) {
+DUK_INTERNAL duk_ret_t duk_bi_symbol_toprimitive(duk_hthread *thr) {
duk_hstring *h_str;
- h_str = duk__auto_unbox_symbol(ctx, DUK_HTHREAD_THIS_PTR((duk_hthread *) ctx));
+ h_str = duk__auto_unbox_symbol(thr, DUK_HTHREAD_THIS_PTR(thr));
if (h_str == NULL) {
return DUK_RET_TYPE_ERROR;
}
- duk_push_hstring(ctx, h_str);
+ duk_push_hstring(thr, h_str);
return 1;
}
@@ -39159,7 +40434,7 @@ DUK_INTERNAL duk_ret_t duk_bi_symbol_toprimitive(duk_context *ctx) {
*/
#if defined(DUK_USE_COROUTINE_SUPPORT)
-DUK_INTERNAL duk_ret_t duk_bi_thread_constructor(duk_context *ctx) {
+DUK_INTERNAL duk_ret_t duk_bi_thread_constructor(duk_hthread *thr) {
duk_hthread *new_thr;
duk_hobject *func;
@@ -39168,18 +40443,18 @@ DUK_INTERNAL duk_ret_t duk_bi_thread_constructor(duk_context *ctx) {
* Resume will reject such functions in any case.
*/
/* XXX: need a duk_require_func_promote_lfunc() */
- func = duk_require_hobject_promote_lfunc(ctx, 0);
+ func = duk_require_hobject_promote_lfunc(thr, 0);
DUK_ASSERT(func != NULL);
- duk_require_callable(ctx, 0);
+ duk_require_callable(thr, 0);
- duk_push_thread(ctx);
- new_thr = (duk_hthread *) duk_known_hobject(ctx, -1);
+ duk_push_thread(thr);
+ new_thr = (duk_hthread *) duk_known_hobject(thr, -1);
new_thr->state = DUK_HTHREAD_STATE_INACTIVE;
/* push initial function call to new thread stack; this is
* picked up by resume().
*/
- duk_push_hobject((duk_context *) new_thr, func);
+ duk_push_hobject(new_thr, func);
return 1; /* return thread */
}
@@ -39201,23 +40476,23 @@ DUK_INTERNAL duk_ret_t duk_bi_thread_constructor(duk_context *ctx) {
*/
#if defined(DUK_USE_COROUTINE_SUPPORT)
-DUK_INTERNAL duk_ret_t duk_bi_thread_resume(duk_context *ctx) {
+DUK_INTERNAL duk_ret_t duk_bi_thread_resume(duk_hthread *ctx) {
duk_hthread *thr = (duk_hthread *) ctx;
duk_hthread *thr_resume;
duk_hobject *caller_func;
- duk_small_int_t is_error;
+ duk_small_uint_t is_error;
DUK_DDD(DUK_DDDPRINT("Duktape.Thread.resume(): thread=%!T, value=%!T, is_error=%!T",
- (duk_tval *) duk_get_tval(ctx, 0),
- (duk_tval *) duk_get_tval(ctx, 1),
- (duk_tval *) duk_get_tval(ctx, 2)));
+ (duk_tval *) duk_get_tval(thr, 0),
+ (duk_tval *) duk_get_tval(thr, 1),
+ (duk_tval *) duk_get_tval(thr, 2)));
DUK_ASSERT(thr->state == DUK_HTHREAD_STATE_RUNNING);
DUK_ASSERT(thr->heap->curr_thread == thr);
- thr_resume = duk_require_hthread(ctx, 0);
- is_error = (duk_small_int_t) duk_to_boolean(ctx, 2);
- duk_set_top(ctx, 2);
+ thr_resume = duk_require_hthread(thr, 0);
+ is_error = (duk_small_uint_t) duk_to_boolean(thr, 2);
+ duk_set_top(thr, 2);
/* [ thread value ] */
@@ -39230,11 +40505,12 @@ DUK_INTERNAL duk_ret_t duk_bi_thread_resume(duk_context *ctx) {
goto state_error;
}
DUK_ASSERT(thr->callstack_curr != NULL);
+ DUK_ASSERT(thr->callstack_curr->parent != NULL);
DUK_ASSERT(DUK_ACT_GET_FUNC(thr->callstack_curr) != NULL); /* us */
DUK_ASSERT(DUK_HOBJECT_IS_NATFUNC(DUK_ACT_GET_FUNC(thr->callstack_curr)));
- DUK_ASSERT(DUK_ACT_GET_FUNC(thr->callstack_curr - 1) != NULL); /* caller */
+ DUK_ASSERT(DUK_ACT_GET_FUNC(thr->callstack_curr->parent) != NULL); /* caller */
- caller_func = DUK_ACT_GET_FUNC(thr->callstack_curr - 1);
+ caller_func = DUK_ACT_GET_FUNC(thr->callstack_curr->parent);
if (!DUK_HOBJECT_IS_COMPFUNC(caller_func)) {
DUK_DD(DUK_DDPRINT("resume state invalid: caller must be Ecmascript code"));
goto state_error;
@@ -39274,13 +40550,13 @@ DUK_INTERNAL duk_ret_t duk_bi_thread_resume(duk_context *ctx) {
goto state_error;
}
- duk_push_tval(ctx, DUK_GET_TVAL_NEGIDX((duk_context *) thr_resume, -1));
- duk_resolve_nonbound_function(ctx);
- h_fun = duk_require_hobject(ctx, -1); /* reject lightfuncs on purpose */
+ duk_push_tval(thr, DUK_GET_TVAL_NEGIDX(thr_resume, -1));
+ duk_resolve_nonbound_function(thr);
+ h_fun = duk_require_hobject(thr, -1); /* reject lightfuncs on purpose */
if (!DUK_HOBJECT_IS_CALLABLE(h_fun) || !DUK_HOBJECT_IS_COMPFUNC(h_fun)) {
goto state_error;
}
- duk_pop(ctx);
+ duk_pop(thr);
}
/*
@@ -39293,7 +40569,7 @@ DUK_INTERNAL duk_ret_t duk_bi_thread_resume(duk_context *ctx) {
#if defined(DUK_USE_AUGMENT_ERROR_THROW)
if (is_error) {
- DUK_ASSERT_TOP(ctx, 2); /* value (error) is at stack top */
+ DUK_ASSERT_TOP(thr, 2); /* value (error) is at stack top */
duk_err_augment_error_throw(thr); /* in resumer's context */
}
#endif
@@ -39301,16 +40577,16 @@ DUK_INTERNAL duk_ret_t duk_bi_thread_resume(duk_context *ctx) {
#if defined(DUK_USE_DEBUG)
if (is_error) {
DUK_DDD(DUK_DDDPRINT("RESUME ERROR: thread=%!T, value=%!T",
- (duk_tval *) duk_get_tval(ctx, 0),
- (duk_tval *) duk_get_tval(ctx, 1)));
+ (duk_tval *) duk_get_tval(thr, 0),
+ (duk_tval *) duk_get_tval(thr, 1)));
} else if (thr_resume->state == DUK_HTHREAD_STATE_YIELDED) {
DUK_DDD(DUK_DDDPRINT("RESUME NORMAL: thread=%!T, value=%!T",
- (duk_tval *) duk_get_tval(ctx, 0),
- (duk_tval *) duk_get_tval(ctx, 1)));
+ (duk_tval *) duk_get_tval(thr, 0),
+ (duk_tval *) duk_get_tval(thr, 1)));
} else {
DUK_DDD(DUK_DDDPRINT("RESUME INITIAL: thread=%!T, value=%!T",
- (duk_tval *) duk_get_tval(ctx, 0),
- (duk_tval *) duk_get_tval(ctx, 1)));
+ (duk_tval *) duk_get_tval(thr, 0),
+ (duk_tval *) duk_get_tval(thr, 1)));
}
#endif
@@ -39353,20 +40629,19 @@ DUK_INTERNAL duk_ret_t duk_bi_thread_resume(duk_context *ctx) {
*/
#if defined(DUK_USE_COROUTINE_SUPPORT)
-DUK_INTERNAL duk_ret_t duk_bi_thread_yield(duk_context *ctx) {
- duk_hthread *thr = (duk_hthread *) ctx;
+DUK_INTERNAL duk_ret_t duk_bi_thread_yield(duk_hthread *thr) {
duk_hobject *caller_func;
- duk_small_int_t is_error;
+ duk_small_uint_t is_error;
DUK_DDD(DUK_DDDPRINT("Duktape.Thread.yield(): value=%!T, is_error=%!T",
- (duk_tval *) duk_get_tval(ctx, 0),
- (duk_tval *) duk_get_tval(ctx, 1)));
+ (duk_tval *) duk_get_tval(thr, 0),
+ (duk_tval *) duk_get_tval(thr, 1)));
DUK_ASSERT(thr->state == DUK_HTHREAD_STATE_RUNNING);
DUK_ASSERT(thr->heap->curr_thread == thr);
- is_error = (duk_small_int_t) duk_to_boolean(ctx, 1);
- duk_set_top(ctx, 1);
+ is_error = (duk_small_uint_t) duk_to_boolean(thr, 1);
+ duk_set_top(thr, 1);
/* [ value ] */
@@ -39385,11 +40660,12 @@ DUK_INTERNAL duk_ret_t duk_bi_thread_yield(duk_context *ctx) {
goto state_error;
}
DUK_ASSERT(thr->callstack_curr != NULL);
+ DUK_ASSERT(thr->callstack_curr->parent != NULL);
DUK_ASSERT(DUK_ACT_GET_FUNC(thr->callstack_curr) != NULL); /* us */
DUK_ASSERT(DUK_HOBJECT_IS_NATFUNC(DUK_ACT_GET_FUNC(thr->callstack_curr)));
- DUK_ASSERT(DUK_ACT_GET_FUNC(thr->callstack_curr - 1) != NULL); /* caller */
+ DUK_ASSERT(DUK_ACT_GET_FUNC(thr->callstack_curr->parent) != NULL); /* caller */
- caller_func = DUK_ACT_GET_FUNC(thr->callstack_curr - 1);
+ caller_func = DUK_ACT_GET_FUNC(thr->callstack_curr->parent);
if (!DUK_HOBJECT_IS_COMPFUNC(caller_func)) {
DUK_DD(DUK_DDPRINT("yield state invalid: caller must be Ecmascript code"));
goto state_error;
@@ -39412,7 +40688,7 @@ DUK_INTERNAL duk_ret_t duk_bi_thread_yield(duk_context *ctx) {
#if defined(DUK_USE_AUGMENT_ERROR_THROW)
if (is_error) {
- DUK_ASSERT_TOP(ctx, 1); /* value (error) is at stack top */
+ DUK_ASSERT_TOP(thr, 1); /* value (error) is at stack top */
duk_err_augment_error_throw(thr); /* in yielder's context */
}
#endif
@@ -39420,10 +40696,10 @@ DUK_INTERNAL duk_ret_t duk_bi_thread_yield(duk_context *ctx) {
#if defined(DUK_USE_DEBUG)
if (is_error) {
DUK_DDD(DUK_DDDPRINT("YIELD ERROR: value=%!T",
- (duk_tval *) duk_get_tval(ctx, 0)));
+ (duk_tval *) duk_get_tval(thr, 0)));
} else {
DUK_DDD(DUK_DDDPRINT("YIELD NORMAL: value=%!T",
- (duk_tval *) duk_get_tval(ctx, 0)));
+ (duk_tval *) duk_get_tval(thr, 0)));
}
#endif
@@ -39454,8 +40730,8 @@ DUK_INTERNAL duk_ret_t duk_bi_thread_yield(duk_context *ctx) {
#endif
#if defined(DUK_USE_COROUTINE_SUPPORT)
-DUK_INTERNAL duk_ret_t duk_bi_thread_current(duk_context *ctx) {
- duk_push_current_thread(ctx);
+DUK_INTERNAL duk_ret_t duk_bi_thread_current(duk_hthread *thr) {
+ duk_push_current_thread(thr);
return 1;
}
#endif
@@ -39465,8 +40741,8 @@ DUK_INTERNAL duk_ret_t duk_bi_thread_current(duk_context *ctx) {
/* #include duk_internal.h -> already included */
-DUK_INTERNAL duk_ret_t duk_bi_type_error_thrower(duk_context *ctx) {
- DUK_DCERROR_TYPE_INVALID_ARGS((duk_hthread *) ctx);
+DUK_INTERNAL duk_ret_t duk_bi_type_error_thrower(duk_hthread *thr) {
+ DUK_DCERROR_TYPE_INVALID_ARGS(thr);
}
/*
* Fixed buffer helper useful for debugging, requires no allocation
@@ -39519,7 +40795,7 @@ DUK_INTERNAL void duk_fb_sprintf(duk_fixedbuffer *fb, const char *fmt, ...) {
}
} else {
/* normal */
- fb->offset += res;
+ fb->offset += (duk_size_t) res;
}
}
va_end(ap);
@@ -39612,9 +40888,9 @@ DUK_INTERNAL duk_bool_t duk_fb_is_full(duk_fixedbuffer *fb) {
#define DUK__LOOP_STACK_DEPTH 256
/* must match bytecode defines now; build autogenerate? */
-DUK_LOCAL const char *duk__bc_optab[256] = {
- "LDREG", "STREG", "LDCONST", "LDINT", "LDINTX", "LDTHIS", "LDUNDEF", "LDNULL",
- "LDTRUE", "LDFALSE", "BNOT", "LNOT", "UNM", "UNP", "TYPEOF", "TYPEOFID",
+DUK_LOCAL const char * const duk__bc_optab[256] = {
+ "LDREG", "STREG", "JUMP", "LDCONST", "LDINT", "LDINTX", "LDTHIS", "LDUNDEF",
+ "LDNULL", "LDTRUE", "LDFALSE", "GETVAR", "BNOT", "LNOT", "UNM", "UNP",
"EQ_RR", "EQ_CR", "EQ_RC", "EQ_CC", "NEQ_RR", "NEQ_CR", "NEQ_RC", "NEQ_CC",
"SEQ_RR", "SEQ_CR", "SEQ_RC", "SEQ_CC", "SNEQ_RR", "SNEQ_CR", "SNEQ_RC", "SNEQ_CC",
@@ -39624,28 +40900,28 @@ DUK_LOCAL const char *duk__bc_optab[256] = {
"SUB_RR", "SUB_CR", "SUB_RC", "SUB_CC", "MUL_RR", "MUL_CR", "MUL_RC", "MUL_CC",
"DIV_RR", "DIV_CR", "DIV_RC", "DIV_CC", "MOD_RR", "MOD_CR", "MOD_RC", "MOD_CC",
- "BAND_RR", "BAND_CR", "BAND_RC", "BAND_CC", "BOR_RR", "BOR_CR", "BOR_RC", "BOR_CC",
- "BXOR_RR", "BXOR_CR", "BXOR_RC", "BXOR_CC", "BASL_RR", "BASL_CR", "BASL_RC", "BASL_CC",
- "BLSR_RR", "BLSR_CR", "BLSR_RC", "BLSR_CC", "BASR_RR", "BASR_CR", "BASR_RC", "BASR_CC",
+ "EXP_RR", "EXP_CR", "EXP_RC", "EXP_CC", "BAND_RR", "BAND_CR", "BAND_RC", "BAND_CC",
+ "BOR_RR", "BOR_CR", "BOR_RC", "BOR_CC", "BXOR_RR", "BXOR_CR", "BXOR_RC", "BXOR_CC",
+ "BASL_RR", "BASL_CR", "BASL_RC", "BASL_CC", "BLSR_RR", "BLSR_CR", "BLSR_RC", "BLSR_CC",
- "INSTOF_RR", "INSTOF_CR", "INSTOF_RC", "INSTOF_CC", "IN_RR", "IN_CR", "IN_RC", "IN_CC",
+ "BASR_RR", "BASR_CR", "BASR_RC", "BASR_CC", "INSTOF_RR", "INSTOF_CR", "INSTOF_RC", "INSTOF_CC",
+ "IN_RR", "IN_CR", "IN_RC", "IN_CC", "GETPROP_RR", "GETPROP_CR", "GETPROP_RC", "GETPROP_CC",
+ "PUTPROP_RR", "PUTPROP_CR", "PUTPROP_RC", "PUTPROP_CC", "DELPROP_RR", "DELPROP_CR", "DELPROP_RC", "DELPROP_CC",
"PREINCR", "PREDECR", "POSTINCR", "POSTDECR", "PREINCV", "PREDECV", "POSTINCV", "POSTDECV",
+
"PREINCP_RR", "PREINCP_CR", "PREINCP_RC", "PREINCP_CC", "PREDECP_RR", "PREDECP_CR", "PREDECP_RC", "PREDECP_CC",
"POSTINCP_RR", "POSTINCP_CR", "POSTINCP_RC", "POSTINCP_CC", "POSTDECP_RR", "POSTDECP_CR", "POSTDECP_RC", "POSTDECP_CC",
-
- "GETPROP_RR", "GETPROP_CR", "GETPROP_RC", "GETPROP_CC", "PUTPROP_RR", "PUTPROP_CR", "PUTPROP_RC", "PUTPROP_CC",
- "DELPROP_RR", "DELPROP_CR", "DELPROP_RC", "DELPROP_CC", "DECLVAR_RR", "DECLVAR_CR", "DECLVAR_RC", "DECLVAR_CC",
- "REGEXP_RR", "REGEXP_RC", "REGEXP_CR", "REGEXP_CC", "CSVAR_RR", "CSVAR_CR", "CSVAR_RC", "CSVAR_CC",
- "CLOSURE", "GETVAR", "PUTVAR", "DELVAR", "JUMP", "RETREG", "RETUNDEF", "RETCONST",
+ "DECLVAR_RR", "DECLVAR_CR", "DECLVAR_RC", "DECLVAR_CC", "REGEXP_RR", "REGEXP_RC", "REGEXP_CR", "REGEXP_CC",
+ "CLOSURE", "TYPEOF", "TYPEOFID", "PUTVAR", "DELVAR", "RETREG", "RETUNDEF", "RETCONST",
"RETCONSTN", "LABEL", "ENDLABEL", "BREAK", "CONTINUE", "TRYCATCH", "ENDTRY", "ENDCATCH",
- "ENDFIN", "THROW", "CSREG", "EVALCALL", "CALL", "TAILCALL", "NEW", "NEWOBJ",
- "NEWARR", "MPUTOBJ", "MPUTOBJI", "INITSET", "INITGET", "MPUTARR", "MPUTARRI", "SETALEN",
- "INITENUM", "NEXTENUM", "INVLHS", "DEBUGGER", "NOP", "INVALID", "UNUSED190", "UNUSED191",
+ "ENDFIN", "THROW", "INVLHS", "CSREG", "CSVAR_RR", "CSVAR_CR", "CSVAR_RC", "CSVAR_CC",
+ "CALL0", "CALL1", "CALL2", "CALL3", "CALL4", "CALL5", "CALL6", "CALL7",
+ "CALL8", "CALL9", "CALL10", "CALL11", "CALL12", "CALL13", "CALL14", "CALL15",
- "UNUSED192", "UNUSED193", "UNUSED194", "UNUSED195", "UNUSED196", "UNUSED197", "UNUSED198", "UNUSED199",
- "UNUSED200", "UNUSED201", "UNUSED202", "UNUSED203", "UNUSED204", "UNUSED205", "UNUSED206", "UNUSED207",
- "UNUSED208", "UNUSED209", "UNUSED210", "UNUSED211", "UNUSED212", "UNUSED213", "UNUSED214", "UNUSED215",
+ "NEWOBJ", "NEWARR", "MPUTOBJ", "MPUTOBJI", "INITSET", "INITGET", "MPUTARR", "MPUTARRI",
+ "SETALEN", "INITENUM", "NEXTENUM", "NEWTARGET", "DEBUGGER", "NOP", "INVALID", "UNUSED207",
+ "GETPROPC_RR", "GETPROPC_CR", "GETPROPC_RC", "GETPROPC_CC", "UNUSED212", "UNUSED213", "UNUSED214", "UNUSED215",
"UNUSED216", "UNUSED217", "UNUSED218", "UNUSED219", "UNUSED220", "UNUSED221", "UNUSED222", "UNUSED223",
"UNUSED224", "UNUSED225", "UNUSED226", "UNUSED227", "UNUSED228", "UNUSED229", "UNUSED230", "UNUSED231",
@@ -39800,9 +41076,9 @@ DUK_LOCAL void duk__print_hstring(duk__dprint_state *st, duk_hstring *h, duk_boo
p_end = p + DUK_HSTRING_GET_BYTELEN(h);
if (p_end > p && p[0] == DUK_ASC_UNDERSCORE) {
- /* if property key begins with underscore, encode it with
+ /* If property key begins with underscore, encode it with
* forced quotes (e.g. "_Foo") to distinguish it from encoded
- * internal properties (e.g. \xffBar -> _Bar).
+ * internal properties (e.g. \x82Bar -> _Bar).
*/
quotes = 1;
}
@@ -39820,9 +41096,9 @@ DUK_LOCAL void duk__print_hstring(duk__dprint_state *st, duk_hstring *h, duk_boo
duk_fb_sprintf(fb, "\\\"");
} else if (ch >= 0x20 && ch <= 0x7e) {
duk_fb_put_byte(fb, ch);
- } else if (ch == 0xff && !quotes) {
- /* encode \xffBar as _Bar if no quotes are applied, this is for
- * readable internal keys.
+ } else if (ch == 0x82 && !quotes) {
+ /* encode \x82Bar as _Bar if no quotes are
+ * applied, this is for readable internal keys.
*/
duk_fb_put_byte(fb, (duk_uint8_t) DUK_ASC_UNDERSCORE);
} else {
@@ -40015,9 +41291,6 @@ DUK_LOCAL void duk__print_hobject(duk__dprint_state *st, duk_hobject *h) {
if (DUK_HOBJECT_HAS_EXOTIC_ARGUMENTS(h)) {
DUK__COMMA(); duk_fb_sprintf(fb, "__exotic_arguments:true");
}
- if (DUK_HOBJECT_HAS_EXOTIC_DUKFUNC(h)) {
- DUK__COMMA(); duk_fb_sprintf(fb, "__exotic_dukfunc:true");
- }
if (DUK_HOBJECT_IS_BUFOBJ(h)) {
DUK__COMMA(); duk_fb_sprintf(fb, "__exotic_bufobj:true");
}
@@ -40054,7 +41327,7 @@ DUK_LOCAL void duk__print_hobject(duk__dprint_state *st, duk_hobject *h) {
duk_hdecenv *e = (duk_hdecenv *) h;
DUK__COMMA(); duk_fb_sprintf(fb, "__thread:"); duk__print_hobject(st, (duk_hobject *) e->thread);
DUK__COMMA(); duk_fb_sprintf(fb, "__varmap:"); duk__print_hobject(st, (duk_hobject *) e->varmap);
- DUK__COMMA(); duk_fb_sprintf(fb, "__regbase:%ld", (long) e->regbase);
+ DUK__COMMA(); duk_fb_sprintf(fb, "__regbase_byteoff:%ld", (long) e->regbase_byteoff);
} else if (st->internal && DUK_HOBJECT_IS_OBJENV(h)) {
duk_hobjenv *e = (duk_hobjenv *) h;
DUK__COMMA(); duk_fb_sprintf(fb, "__target:"); duk__print_hobject(st, (duk_hobject *) e->target);
@@ -40071,23 +41344,35 @@ DUK_LOCAL void duk__print_hobject(duk__dprint_state *st, duk_hobject *h) {
DUK__COMMA(); duk_fb_sprintf(fb, "__shift:%ld", (long) b->shift);
DUK__COMMA(); duk_fb_sprintf(fb, "__elemtype:%ld", (long) b->elem_type);
#endif
+ } else if (st->internal && DUK_HOBJECT_IS_PROXY(h)) {
+ duk_hproxy *p = (duk_hproxy *) h;
+ DUK__COMMA(); duk_fb_sprintf(fb, "__target:");
+ duk__print_hobject(st, p->target);
+ DUK__COMMA(); duk_fb_sprintf(fb, "__handler:");
+ duk__print_hobject(st, p->handler);
} else if (st->internal && DUK_HOBJECT_IS_THREAD(h)) {
duk_hthread *t = (duk_hthread *) h;
+ DUK__COMMA(); duk_fb_sprintf(fb, "__ptr_curr_pc:%p", (void *) t->ptr_curr_pc);
+ DUK__COMMA(); duk_fb_sprintf(fb, "__heap:%p", (void *) t->heap);
DUK__COMMA(); duk_fb_sprintf(fb, "__strict:%ld", (long) t->strict);
DUK__COMMA(); duk_fb_sprintf(fb, "__state:%ld", (long) t->state);
DUK__COMMA(); duk_fb_sprintf(fb, "__unused1:%ld", (long) t->unused1);
DUK__COMMA(); duk_fb_sprintf(fb, "__unused2:%ld", (long) t->unused2);
- DUK__COMMA(); duk_fb_sprintf(fb, "__valstack_max:%ld", (long) t->valstack_max);
- DUK__COMMA(); duk_fb_sprintf(fb, "__callstack_max:%ld", (long) t->callstack_max);
- DUK__COMMA(); duk_fb_sprintf(fb, "__catchstack_max:%ld", (long) t->catchstack_max);
DUK__COMMA(); duk_fb_sprintf(fb, "__valstack:%p", (void *) t->valstack);
DUK__COMMA(); duk_fb_sprintf(fb, "__valstack_end:%p/%ld", (void *) t->valstack_end, (long) (t->valstack_end - t->valstack));
+ DUK__COMMA(); duk_fb_sprintf(fb, "__valstack_alloc_end:%p/%ld", (void *) t->valstack_alloc_end, (long) (t->valstack_alloc_end - t->valstack));
DUK__COMMA(); duk_fb_sprintf(fb, "__valstack_bottom:%p/%ld", (void *) t->valstack_bottom, (long) (t->valstack_bottom - t->valstack));
DUK__COMMA(); duk_fb_sprintf(fb, "__valstack_top:%p/%ld", (void *) t->valstack_top, (long) (t->valstack_top - t->valstack));
- DUK__COMMA(); duk_fb_sprintf(fb, "__catchstack:%p", (void *) t->catchstack);
- DUK__COMMA(); duk_fb_sprintf(fb, "__catchstack_size:%ld", (long) t->catchstack_size);
- DUK__COMMA(); duk_fb_sprintf(fb, "__catchstack_top:%ld", (long) t->catchstack_top);
+ DUK__COMMA(); duk_fb_sprintf(fb, "__callstack_curr:%p", (void *) t->callstack_curr);
+ DUK__COMMA(); duk_fb_sprintf(fb, "__callstack_top:%ld", (long) t->callstack_top);
+ DUK__COMMA(); duk_fb_sprintf(fb, "__callstack_preventcount:%ld", (long) t->callstack_preventcount);
DUK__COMMA(); duk_fb_sprintf(fb, "__resumer:"); duk__print_hobject(st, (duk_hobject *) t->resumer);
+ DUK__COMMA(); duk_fb_sprintf(fb, "__compile_ctx:%p", (void *) t->compile_ctx);
+#if defined(DUK_USE_INTERRUPT_COUNTER)
+ DUK__COMMA(); duk_fb_sprintf(fb, "__interrupt_counter:%ld", (long) t->interrupt_counter);
+ DUK__COMMA(); duk_fb_sprintf(fb, "__interrupt_init:%ld", (long) t->interrupt_init);
+#endif
+
/* XXX: print built-ins array? */
}
@@ -40294,7 +41579,7 @@ DUK_LOCAL void duk__print_tval(duk__dprint_state *st, duk_tval *tv) {
case DUK_TAG_FASTINT:
DUK_ASSERT(!DUK_TVAL_IS_UNUSED(tv));
DUK_ASSERT(DUK_TVAL_IS_NUMBER(tv));
- duk_fb_sprintf(fb, "%.18gF", (double) DUK_TVAL_GET_NUMBER(tv));
+ duk_fb_sprintf(fb, "%.18g_F", (double) DUK_TVAL_GET_NUMBER(tv));
break;
#endif
default: {
@@ -40321,8 +41606,8 @@ DUK_LOCAL void duk__print_instr(duk__dprint_state *st, duk_instr_t ins) {
/* XXX: option to fix opcode length so it lines up nicely */
if (op == DUK_OP_JUMP) {
- duk_int_t diff1 = DUK_DEC_ABC(ins) - DUK_BC_JUMP_BIAS; /* from next pc */
- duk_int_t diff2 = diff1 + 1; /* from curr pc */
+ duk_int_t diff1 = (duk_int_t) (DUK_DEC_ABC(ins) - DUK_BC_JUMP_BIAS); /* from next pc */
+ duk_int_t diff2 = diff1 + 1; /* from curr pc */
duk_fb_sprintf(fb, "%s %ld (to pc%c%ld)",
(const char *) op_name, (long) diff1,
@@ -40564,7 +41849,7 @@ DUK_INTERNAL void duk_debug_format_funcptr(char *buf, duk_size_t buf_size, duk_u
#else
ch = fptr[fptr_size - 1 - i];
#endif
- p += DUK_SNPRINTF((char *) p, left, "%02lx", (unsigned long) ch);
+ p += DUK_SNPRINTF((char *) p, (duk_size_t) left, "%02lx", (unsigned long) ch);
}
}
@@ -40585,6 +41870,24 @@ DUK_INTERNAL void duk_debug_format_funcptr(char *buf, duk_size_t buf_size, duk_u
#if defined(DUK_USE_DEBUGGER_SUPPORT)
/*
+ * Assert helpers
+ */
+
+#if defined(DUK_USE_ASSERTIONS)
+#define DUK__DBG_TPORT_ENTER() do { \
+ DUK_ASSERT(heap->dbg_calling_transport == 0); \
+ heap->dbg_calling_transport = 1; \
+ } while (0)
+#define DUK__DBG_TPORT_EXIT() do { \
+ DUK_ASSERT(heap->dbg_calling_transport == 1); \
+ heap->dbg_calling_transport = 0; \
+ } while (0)
+#else
+#define DUK__DBG_TPORT_ENTER() do {} while (0)
+#define DUK__DBG_TPORT_EXIT() do {} while (0)
+#endif
+
+/*
* Helper structs
*/
@@ -40646,10 +41949,9 @@ DUK_LOCAL void duk__debug_do_detach1(duk_heap *heap, duk_int_t reason) {
/* heap->dbg_processing: keep on purpose to avoid debugger re-entry in detaching state */
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;
- heap->dbg_step_startline = 0;
+ heap->dbg_pause_flags = 0;
+ heap->dbg_pause_act = NULL;
+ heap->dbg_pause_startline = 0;
heap->dbg_have_next_byte = 0;
duk_debug_clear_paused(heap); /* XXX: some overlap with field inits above */
heap->dbg_state_dirty = 0; /* XXX: clear_paused sets dirty; rework? */
@@ -40668,14 +41970,12 @@ DUK_LOCAL void duk__debug_do_detach2(duk_heap *heap) {
duk_debug_detached_function detached_cb;
void *detached_udata;
duk_hthread *thr;
- duk_context *ctx;
thr = heap->heap_thread;
if (thr == NULL) {
DUK_ASSERT(heap->dbg_detached_cb == NULL);
return;
}
- ctx = (duk_context *) thr;
/* Safe to call multiple times. */
@@ -40690,7 +41990,7 @@ DUK_LOCAL void duk__debug_do_detach2(duk_heap *heap) {
* inside the callback.
*/
DUK_D(DUK_DPRINT("detached during message loop, delayed call to detached_cb"));
- detached_cb(ctx, detached_udata);
+ detached_cb(thr, detached_udata);
}
heap->dbg_detaching = 0;
@@ -40723,11 +42023,40 @@ DUK_LOCAL void duk__debug_null_most_callbacks(duk_hthread *thr) {
}
/*
+ * Pause handling
+ */
+
+DUK_LOCAL void duk__debug_set_pause_state(duk_hthread *thr, duk_heap *heap, duk_small_uint_t pause_flags) {
+ duk_uint_fast32_t line;
+
+ line = duk_debug_curr_line(thr);
+ if (line == 0) {
+ /* No line info for current function. */
+ duk_small_uint_t updated_flags;
+
+ updated_flags = pause_flags & ~(DUK_PAUSE_FLAG_LINE_CHANGE);
+ DUK_D(DUK_DPRINT("no line info for current activation, disable line-based pause flags: 0x%08lx -> 0x%08lx",
+ (long) pause_flags, (long) updated_flags));
+ pause_flags = updated_flags;
+ }
+
+ heap->dbg_pause_flags = pause_flags;
+ heap->dbg_pause_act = thr->callstack_curr;
+ heap->dbg_pause_startline = (duk_uint32_t) line;
+ heap->dbg_state_dirty = 1;
+
+ DUK_D(DUK_DPRINT("set state for automatic pause triggers, flags=0x%08lx, act=%p, startline=%ld",
+ (long) heap->dbg_pause_flags, (void *) heap->dbg_pause_act,
+ (long) heap->dbg_pause_startline));
+}
+
+/*
* Debug connection peek and flush primitives
*/
DUK_INTERNAL duk_bool_t duk_debug_read_peek(duk_hthread *thr) {
duk_heap *heap;
+ duk_bool_t ret;
DUK_ASSERT(thr != NULL);
heap = thr->heap;
@@ -40742,7 +42071,10 @@ DUK_INTERNAL duk_bool_t duk_debug_read_peek(duk_hthread *thr) {
return 0;
}
- return (duk_bool_t) (heap->dbg_peek_cb(heap->dbg_udata) > 0);
+ DUK__DBG_TPORT_ENTER();
+ ret = (duk_bool_t) (heap->dbg_peek_cb(heap->dbg_udata) > 0);
+ DUK__DBG_TPORT_EXIT();
+ return ret;
}
DUK_INTERNAL void duk_debug_read_flush(duk_hthread *thr) {
@@ -40761,7 +42093,9 @@ DUK_INTERNAL void duk_debug_read_flush(duk_hthread *thr) {
return;
}
+ DUK__DBG_TPORT_ENTER();
heap->dbg_read_flush_cb(heap->dbg_udata);
+ DUK__DBG_TPORT_EXIT();
}
DUK_INTERNAL void duk_debug_write_flush(duk_hthread *thr) {
@@ -40780,7 +42114,9 @@ DUK_INTERNAL void duk_debug_write_flush(duk_hthread *thr) {
return;
}
+ DUK__DBG_TPORT_ENTER();
heap->dbg_write_flush_cb(heap->dbg_udata);
+ DUK__DBG_TPORT_EXIT();
}
/*
@@ -40858,7 +42194,10 @@ DUK_INTERNAL void duk_debug_read_bytes(duk_hthread *thr, duk_uint8_t *data, duk_
#if defined(DUK_USE_DEBUGGER_TRANSPORT_TORTURE)
left = 1;
#endif
+ DUK__DBG_TPORT_ENTER();
got = heap->dbg_read_cb(heap->dbg_udata, (char *) p, left);
+ DUK__DBG_TPORT_EXIT();
+
if (got == 0 || got > left) {
DUK_D(DUK_DPRINT("connection error during read, return zero data"));
duk__debug_null_most_callbacks(thr); /* avoid calling write callback in detach1() */
@@ -40893,7 +42232,7 @@ DUK_LOCAL duk_uint32_t duk__debug_read_uint32_raw(duk_hthread *thr) {
(duk_uint32_t) buf[3];
}
-DUK_LOCAL duk_uint32_t duk__debug_read_int32_raw(duk_hthread *thr) {
+DUK_LOCAL duk_int32_t duk__debug_read_int32_raw(duk_hthread *thr) {
return (duk_int32_t) duk__debug_read_uint32_raw(thr);
}
@@ -40929,25 +42268,23 @@ DUK_INTERNAL duk_int32_t duk_debug_read_int(duk_hthread *thr) {
}
DUK_LOCAL duk_hstring *duk__debug_read_hstring_raw(duk_hthread *thr, duk_uint32_t len) {
- duk_context *ctx = (duk_context *) thr;
duk_uint8_t buf[31];
duk_uint8_t *p;
if (len <= sizeof(buf)) {
duk_debug_read_bytes(thr, buf, (duk_size_t) len);
- duk_push_lstring(ctx, (const char *) buf, (duk_size_t) len);
+ duk_push_lstring(thr, (const char *) buf, (duk_size_t) len);
} else {
- p = (duk_uint8_t *) duk_push_fixed_buffer(ctx, (duk_size_t) len); /* zero for paranoia */
+ p = (duk_uint8_t *) duk_push_fixed_buffer(thr, (duk_size_t) len); /* zero for paranoia */
DUK_ASSERT(p != NULL);
duk_debug_read_bytes(thr, p, (duk_size_t) len);
- (void) duk_buffer_to_string(ctx, -1); /* Safety relies on debug client, which is OK. */
+ (void) duk_buffer_to_string(thr, -1); /* Safety relies on debug client, which is OK. */
}
- return duk_require_hstring(ctx, -1);
+ return duk_require_hstring(thr, -1);
}
DUK_INTERNAL duk_hstring *duk_debug_read_hstring(duk_hthread *thr) {
- duk_context *ctx = (duk_context *) thr;
duk_small_uint_t x;
duk_uint32_t len;
@@ -40970,19 +42307,18 @@ DUK_INTERNAL duk_hstring *duk_debug_read_hstring(duk_hthread *thr) {
fail:
DUK_D(DUK_DPRINT("debug connection error: failed to decode int"));
DUK__SET_CONN_BROKEN(thr, 1);
- duk_push_hstring_empty(ctx); /* always push some string */
- return duk_require_hstring(ctx, -1);
+ duk_push_hstring_empty(thr); /* always push some string */
+ return duk_require_hstring(thr, -1);
}
DUK_LOCAL duk_hbuffer *duk__debug_read_hbuffer_raw(duk_hthread *thr, duk_uint32_t len) {
- duk_context *ctx = (duk_context *) thr;
duk_uint8_t *p;
- p = (duk_uint8_t *) duk_push_fixed_buffer(ctx, (duk_size_t) len); /* zero for paranoia */
+ p = (duk_uint8_t *) duk_push_fixed_buffer(thr, (duk_size_t) len); /* zero for paranoia */
DUK_ASSERT(p != NULL);
duk_debug_read_bytes(thr, p, (duk_size_t) len);
- return duk_require_hbuffer(ctx, -1);
+ return duk_require_hbuffer(thr, -1);
}
DUK_LOCAL void *duk__debug_read_pointer_raw(duk_hthread *thr) {
@@ -41066,7 +42402,6 @@ DUK_INTERNAL duk_heaphdr *duk_debug_read_any_ptr(duk_hthread *thr) {
}
DUK_INTERNAL duk_tval *duk_debug_read_tval(duk_hthread *thr) {
- duk_context *ctx = (duk_context *) thr;
duk_uint8_t x;
duk_uint_t t;
duk_uint32_t len;
@@ -41078,11 +42413,11 @@ DUK_INTERNAL duk_tval *duk_debug_read_tval(duk_hthread *thr) {
if (x >= 0xc0) {
t = (duk_uint_t) (x - 0xc0);
t = (t << 8) + duk_debug_read_byte(thr);
- duk_push_uint(ctx, (duk_uint_t) t);
+ duk_push_uint(thr, (duk_uint_t) t);
goto return_ptr;
}
if (x >= 0x80) {
- duk_push_uint(ctx, (duk_uint_t) (x - 0x80));
+ duk_push_uint(thr, (duk_uint_t) (x - 0x80));
goto return_ptr;
}
if (x >= 0x60) {
@@ -41094,7 +42429,7 @@ DUK_INTERNAL duk_tval *duk_debug_read_tval(duk_hthread *thr) {
switch (x) {
case DUK_DBG_IB_INT4: {
duk_int32_t i = duk__debug_read_int32_raw(thr);
- duk_push_i32(ctx, i);
+ duk_push_i32(thr, i);
break;
}
case DUK_DBG_IB_STR4: {
@@ -41118,25 +42453,25 @@ DUK_INTERNAL duk_tval *duk_debug_read_tval(duk_hthread *thr) {
break;
}
case DUK_DBG_IB_UNDEFINED: {
- duk_push_undefined(ctx);
+ duk_push_undefined(thr);
break;
}
case DUK_DBG_IB_NULL: {
- duk_push_null(ctx);
+ duk_push_null(thr);
break;
}
case DUK_DBG_IB_TRUE: {
- duk_push_true(ctx);
+ duk_push_true(thr);
break;
}
case DUK_DBG_IB_FALSE: {
- duk_push_false(ctx);
+ duk_push_false(thr);
break;
}
case DUK_DBG_IB_NUMBER: {
duk_double_t d;
d = duk__debug_read_double_raw(thr);
- duk_push_number(ctx, d);
+ duk_push_number(thr, d);
break;
}
case DUK_DBG_IB_OBJECT: {
@@ -41219,7 +42554,10 @@ DUK_INTERNAL void duk_debug_write_bytes(duk_hthread *thr, const duk_uint8_t *dat
#if defined(DUK_USE_DEBUGGER_TRANSPORT_TORTURE)
left = 1;
#endif
+ DUK__DBG_TPORT_ENTER();
got = heap->dbg_write_cb(heap->dbg_udata, (const char *) p, left);
+ DUK__DBG_TPORT_EXIT();
+
if (got == 0 || got > left) {
duk__debug_null_most_callbacks(thr); /* avoid calling write callback in detach1() */
DUK_D(DUK_DPRINT("connection error during write"));
@@ -41345,8 +42683,7 @@ DUK_INTERNAL void duk_debug_write_hstring(duk_hthread *thr, duk_hstring *h) {
}
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_debug_write_hstring(thr, duk_safe_to_hstring(thr, -1));
}
DUK_INTERNAL void duk_debug_write_buffer(duk_hthread *thr, const char *data, duk_size_t length) {
@@ -41534,7 +42871,7 @@ DUK_INTERNAL void duk_debug_write_error_eom(duk_hthread *thr, duk_small_uint_t e
DUK_INTERNAL void duk_debug_write_notify(duk_hthread *thr, duk_small_uint_t command) {
duk_debug_write_byte(thr, DUK_DBG_IB_NOTIFY);
- duk_debug_write_int(thr, command);
+ duk_debug_write_int(thr, (duk_int32_t) command);
}
DUK_INTERNAL void duk_debug_write_eom(duk_hthread *thr) {
@@ -41553,7 +42890,6 @@ DUK_INTERNAL void duk_debug_write_eom(duk_hthread *thr) {
*/
DUK_INTERNAL duk_uint_fast32_t duk_debug_curr_line(duk_hthread *thr) {
- duk_context *ctx = (duk_context *) thr;
duk_activation *act;
duk_uint_fast32_t line;
duk_uint_fast32_t pc;
@@ -41575,20 +42911,18 @@ DUK_INTERNAL duk_uint_fast32_t duk_debug_curr_line(duk_hthread *thr) {
/* XXX: this should be optimized to be a raw query and avoid valstack
* operations if possible.
*/
- duk_push_tval(ctx, &act->tv_func);
- line = duk_hobject_pc2line_query(ctx, -1, pc);
- duk_pop(ctx);
+ duk_push_tval(thr, &act->tv_func);
+ line = duk_hobject_pc2line_query(thr, -1, pc);
+ duk_pop(thr);
return line;
}
DUK_INTERNAL void duk_debug_send_status(duk_hthread *thr) {
- duk_context *ctx = (duk_context *) thr;
duk_activation *act;
duk_debug_write_notify(thr, DUK_DBG_CMD_STATUS);
duk_debug_write_int(thr, (DUK_HEAP_HAS_DEBUGGER_PAUSED(thr->heap) ? 1 : 0));
- DUK_ASSERT_DISABLE(thr->callstack_top >= 0); /* unsigned */
act = thr->callstack_curr;
if (act == NULL) {
duk_debug_write_undefined(thr);
@@ -41596,15 +42930,14 @@ DUK_INTERNAL void duk_debug_send_status(duk_hthread *thr) {
duk_debug_write_int(thr, 0);
duk_debug_write_int(thr, 0);
} else {
- duk_push_tval(ctx, &act->tv_func);
- duk_get_prop_string(ctx, -1, "fileName");
+ duk_push_tval(thr, &act->tv_func);
+ duk_get_prop_string(thr, -1, "fileName");
duk__debug_write_hstring_safe_top(thr);
- duk_get_prop_string(ctx, -2, "name");
+ duk_get_prop_string(thr, -2, "name");
duk__debug_write_hstring_safe_top(thr);
- duk_pop_3(ctx);
+ duk_pop_3(thr);
/* Report next pc/line to be executed. */
duk_debug_write_uint(thr, (duk_uint32_t) duk_debug_curr_line(thr));
- act = thr->callstack_curr;
duk_debug_write_uint(thr, (duk_uint32_t) duk_hthread_get_act_curr_pc(thr, act));
}
@@ -41617,27 +42950,26 @@ 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);
+ duk_debug_write_int(thr, (duk_int32_t) fatal);
/* Report thrown value to client coerced to string */
- duk_dup_top(ctx);
+ duk_dup_top(thr);
duk__debug_write_hstring_safe_top(thr);
- duk_pop(ctx);
+ duk_pop(thr);
- if (duk_is_error(ctx, -1)) {
+ if (duk_is_error(thr, -1)) {
/* Error instance, use augmented error data directly */
- duk_get_prop_stridx_short(ctx, -1, DUK_STRIDX_FILE_NAME);
+ duk_get_prop_stridx_short(thr, -1, DUK_STRIDX_FILE_NAME);
duk__debug_write_hstring_safe_top(thr);
- duk_get_prop_stridx_short(ctx, -2, DUK_STRIDX_LINE_NUMBER);
- duk_debug_write_uint(thr, duk_get_uint(ctx, -1));
- duk_pop_2(ctx);
+ duk_get_prop_stridx_short(thr, -2, DUK_STRIDX_LINE_NUMBER);
+ duk_debug_write_uint(thr, duk_get_uint(thr, -1));
+ duk_pop_2(thr);
} else {
/* For anything other than an Error instance, we calculate the
* error location directly from the current activation if one
@@ -41645,13 +42977,12 @@ DUK_INTERNAL void duk_debug_send_throw(duk_hthread *thr, duk_bool_t fatal) {
*/
act = thr->callstack_curr;
if (act != NULL) {
- duk_push_tval(ctx, &act->tv_func);
- duk_get_prop_string(ctx, -1, "fileName");
+ duk_push_tval(thr, &act->tv_func);
+ duk_get_prop_string(thr, -1, "fileName");
duk__debug_write_hstring_safe_top(thr);
- act = thr->callstack_curr;
- 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);
+ pc = (duk_uint32_t) duk_hthread_get_act_prev_pc(thr, act);
+ duk_debug_write_uint(thr, (duk_uint32_t) duk_hobject_pc2line_query(thr, -2, pc));
+ duk_pop_2(thr);
} else {
/* Can happen if duk_throw() is called on an empty
* callstack.
@@ -41684,7 +43015,7 @@ DUK_LOCAL duk_bool_t duk__debug_skip_dvalue(duk_hthread *thr) {
return 0;
}
if (x >= 0x60) {
- duk_debug_skip_bytes(thr, x - 0x60);
+ duk_debug_skip_bytes(thr, (duk_size_t) (x - 0x60));
return 0;
}
switch(x) {
@@ -41752,6 +43083,9 @@ DUK_LOCAL void duk__debug_skip_to_eom(duk_hthread *thr) {
}
}
+/* Read and validate a call stack index. If index is invalid, write out an
+ * error message and return zero.
+ */
DUK_LOCAL duk_int32_t duk__debug_read_validate_csindex(duk_hthread *thr) {
duk_int32_t level;
level = duk_debug_read_int(thr);
@@ -41762,6 +43096,21 @@ DUK_LOCAL duk_int32_t duk__debug_read_validate_csindex(duk_hthread *thr) {
return level;
}
+/* Read a call stack index and lookup the corresponding duk_activation.
+ * If index is invalid, write out an error message and return NULL.
+ */
+DUK_LOCAL duk_activation *duk__debug_read_level_get_activation(duk_hthread *thr) {
+ duk_activation *act;
+ duk_int32_t level;
+
+ level = duk_debug_read_int(thr);
+ act = duk_hthread_get_activation_for_level(thr, level);
+ if (act == NULL) {
+ duk_debug_write_error_eom(thr, DUK_DBG_ERR_NOTFOUND, "invalid callstack index");
+ }
+ return act;
+}
+
/*
* Simple commands
*/
@@ -41798,50 +43147,61 @@ 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"));
-
- if (duk_debug_is_paused(heap)) {
- DUK_D(DUK_DPRINT("Pause requested when already paused, ignore"));
- } else {
- duk_debug_set_paused(heap);
- }
+ duk_debug_set_paused(heap);
duk_debug_write_reply(thr);
duk_debug_write_eom(thr);
}
DUK_LOCAL void duk__debug_handle_resume(duk_hthread *thr, duk_heap *heap) {
+ duk_small_uint_t pause_flags;
+
DUK_D(DUK_DPRINT("debug command Resume"));
duk_debug_clear_paused(heap);
+
+ pause_flags = 0;
+#if 0 /* manual testing */
+ pause_flags |= DUK_PAUSE_FLAG_ONE_OPCODE;
+ pause_flags |= DUK_PAUSE_FLAG_CAUGHT_ERROR;
+ pause_flags |= DUK_PAUSE_FLAG_UNCAUGHT_ERROR;
+#endif
+#if defined(DUK_USE_DEBUGGER_PAUSE_UNCAUGHT)
+ pause_flags |= DUK_PAUSE_FLAG_UNCAUGHT_ERROR;
+#endif
+
+ duk__debug_set_pause_state(thr, heap, pause_flags);
+
duk_debug_write_reply(thr);
duk_debug_write_eom(thr);
}
DUK_LOCAL void duk__debug_handle_step(duk_hthread *thr, duk_heap *heap, duk_int32_t cmd) {
- duk_small_uint_t step_type;
- duk_uint_fast32_t line;
+ duk_small_uint_t pause_flags;
DUK_D(DUK_DPRINT("debug command StepInto/StepOver/StepOut: %d", (int) cmd));
if (cmd == DUK_DBG_CMD_STEPINTO) {
- step_type = DUK_STEP_TYPE_INTO;
+ pause_flags = DUK_PAUSE_FLAG_LINE_CHANGE |
+ DUK_PAUSE_FLAG_FUNC_ENTRY |
+ DUK_PAUSE_FLAG_FUNC_EXIT;
} else if (cmd == DUK_DBG_CMD_STEPOVER) {
- step_type = DUK_STEP_TYPE_OVER;
+ pause_flags = DUK_PAUSE_FLAG_LINE_CHANGE |
+ DUK_PAUSE_FLAG_FUNC_EXIT;
} else {
DUK_ASSERT(cmd == DUK_DBG_CMD_STEPOUT);
- step_type = DUK_STEP_TYPE_OUT;
+ pause_flags = DUK_PAUSE_FLAG_FUNC_EXIT;
}
+#if defined(DUK_USE_DEBUGGER_PAUSE_UNCAUGHT)
+ pause_flags |= DUK_PAUSE_FLAG_UNCAUGHT_ERROR;
+#endif
+
+ /* If current activation doesn't have line information, line-based
+ * pause flags are automatically disabled. As a result, e.g.
+ * StepInto will then pause on (native) function entry or exit.
+ */
+ duk_debug_clear_paused(heap);
+ duk__debug_set_pause_state(thr, heap, pause_flags);
- line = duk_debug_curr_line(thr);
- if (line > 0) {
- duk_debug_clear_paused(heap); /* XXX: overlap with fields below; separate macro/helper? */
- heap->dbg_step_type = step_type;
- heap->dbg_step_thread = thr;
- heap->dbg_step_csindex = thr->callstack_top - 1;
- heap->dbg_step_startline = line;
- heap->dbg_state_dirty = 1;
- } else {
- DUK_D(DUK_DPRINT("cannot determine current line, stepinto/stepover/stepout ignored"));
- }
duk_debug_write_reply(thr);
duk_debug_write_eom(thr);
}
@@ -41894,40 +43254,27 @@ DUK_LOCAL void duk__debug_handle_del_break(duk_hthread *thr, duk_heap *heap) {
}
DUK_LOCAL void duk__debug_handle_get_var(duk_hthread *thr, duk_heap *heap) {
- duk_context *ctx = (duk_context *) thr;
+ duk_activation *act;
duk_hstring *str;
duk_bool_t rc;
- duk_int32_t level;
DUK_UNREF(heap);
DUK_D(DUK_DPRINT("debug command GetVar"));
- level = duk__debug_read_validate_csindex(thr);
- if (level == 0) {
+ act = duk__debug_read_level_get_activation(thr);
+ if (act == NULL) {
return;
}
str = duk_debug_read_hstring(thr); /* push to stack */
DUK_ASSERT(str != NULL);
- if (thr->callstack_top > 0) {
- rc = duk_js_getvar_activation(thr,
- thr->callstack + thr->callstack_top + level,
- str,
- 0);
- } else {
- /* No activation, no variable access. Could also pretend
- * we're in the global program context and read stuff off
- * the global object.
- */
- DUK_D(DUK_DPRINT("callstack empty, no activation -> ignore getvar"));
- rc = 0;
- }
+ rc = duk_js_getvar_activation(thr, act, str, 0);
duk_debug_write_reply(thr);
if (rc) {
duk_debug_write_int(thr, 1);
- DUK_ASSERT(duk_get_tval(ctx, -2) != NULL);
- duk_debug_write_tval(thr, duk_get_tval(ctx, -2));
+ DUK_ASSERT(duk_get_tval(thr, -2) != NULL);
+ duk_debug_write_tval(thr, duk_get_tval(thr, -2));
} else {
duk_debug_write_int(thr, 0);
duk_debug_write_unused(thr);
@@ -41936,15 +43283,15 @@ DUK_LOCAL void duk__debug_handle_get_var(duk_hthread *thr, duk_heap *heap) {
}
DUK_LOCAL void duk__debug_handle_put_var(duk_hthread *thr, duk_heap *heap) {
+ duk_activation *act;
duk_hstring *str;
duk_tval *tv;
- duk_int32_t level;
DUK_UNREF(heap);
DUK_D(DUK_DPRINT("debug command PutVar"));
- level = duk__debug_read_validate_csindex(thr);
- if (level == 0) {
+ act = duk__debug_read_level_get_activation(thr);
+ if (act == NULL) {
return;
}
str = duk_debug_read_hstring(thr); /* push to stack */
@@ -41955,15 +43302,7 @@ DUK_LOCAL void duk__debug_handle_put_var(duk_hthread *thr, duk_heap *heap) {
return;
}
- if (thr->callstack_top > 0) {
- duk_js_putvar_activation(thr,
- thr->callstack + thr->callstack_top + level,
- str,
- tv,
- 0);
- } else {
- DUK_D(DUK_DPRINT("callstack empty, no activation -> ignore putvar"));
- }
+ duk_js_putvar_activation(thr, act, str, tv, 0);
/* XXX: Current putvar implementation doesn't have a success flag,
* add one and send to debug client?
@@ -41973,23 +43312,17 @@ DUK_LOCAL void duk__debug_handle_put_var(duk_hthread *thr, duk_heap *heap) {
}
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;
DUK_ASSERT(thr != NULL);
DUK_UNREF(heap);
duk_debug_write_reply(thr);
while (curr_thr != NULL) {
- i = curr_thr->callstack_top;
- while (i > 0) {
- i--;
- curr_act = curr_thr->callstack + i;
-
+ for (curr_act = curr_thr->callstack_curr; curr_act != NULL; curr_act = curr_act->parent) {
/* PC/line semantics here are:
* - For callstack top we're conceptually between two
* opcodes and current PC indicates next line to
@@ -42003,19 +43336,19 @@ DUK_LOCAL void duk__debug_handle_get_call_stack(duk_hthread *thr, duk_heap *heap
/* XXX: optimize to use direct reads, i.e. avoid
* value stack operations.
*/
- duk_push_tval(ctx, &curr_act->tv_func);
- duk_get_prop_stridx_short(ctx, -1, DUK_STRIDX_FILE_NAME);
+ duk_push_tval(thr, &curr_act->tv_func);
+ duk_get_prop_stridx_short(thr, -1, DUK_STRIDX_FILE_NAME);
duk__debug_write_hstring_safe_top(thr);
- duk_get_prop_stridx_short(ctx, -2, DUK_STRIDX_NAME);
+ duk_get_prop_stridx_short(thr, -2, DUK_STRIDX_NAME);
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) {
+ if (curr_act != curr_thr->callstack_curr && pc > 0) {
pc--;
}
- line = duk_hobject_pc2line_query(ctx, -3, pc);
+ line = duk_hobject_pc2line_query(thr, -3, pc);
duk_debug_write_uint(thr, (duk_uint32_t) line);
duk_debug_write_uint(thr, (duk_uint32_t) pc);
- duk_pop_3(ctx);
+ duk_pop_3(thr);
}
curr_thr = curr_thr->resumer;
}
@@ -42026,20 +43359,17 @@ DUK_LOCAL void duk__debug_handle_get_call_stack(duk_hthread *thr, duk_heap *heap
}
DUK_LOCAL void duk__debug_handle_get_locals(duk_hthread *thr, duk_heap *heap) {
- duk_context *ctx = (duk_context *) thr;
- duk_activation *curr_act;
- duk_int32_t level;
+ duk_activation *act;
duk_hstring *varname;
DUK_UNREF(heap);
- level = duk__debug_read_validate_csindex(thr);
- if (level == 0) {
+ act = duk__debug_read_level_get_activation(thr);
+ if (act == NULL) {
return;
}
- duk_debug_write_reply(thr);
- curr_act = thr->callstack + thr->callstack_top + level;
+ duk_debug_write_reply(thr);
/* XXX: several nice-to-have improvements here:
* - Use direct reads avoiding value stack operations
@@ -42047,18 +43377,18 @@ DUK_LOCAL void duk__debug_handle_get_locals(duk_hthread *thr, duk_heap *heap) {
* - If side effects are possible, add error catching
*/
- duk_push_tval(ctx, &curr_act->tv_func);
- duk_get_prop_stridx_short(ctx, -1, DUK_STRIDX_INT_VARMAP);
- if (duk_is_object(ctx, -1)) {
- duk_enum(ctx, -1, 0 /*enum_flags*/);
- while (duk_next(ctx, -1 /*enum_index*/, 0 /*get_value*/)) {
- varname = duk_known_hstring(ctx, -1);
+ duk_push_tval(thr, &act->tv_func);
+ duk_get_prop_stridx_short(thr, -1, DUK_STRIDX_INT_VARMAP);
+ if (duk_is_object(thr, -1)) {
+ duk_enum(thr, -1, 0 /*enum_flags*/);
+ while (duk_next(thr, -1 /*enum_index*/, 0 /*get_value*/)) {
+ varname = duk_known_hstring(thr, -1);
- duk_js_getvar_activation(thr, curr_act, varname, 0 /*throw_flag*/);
+ duk_js_getvar_activation(thr, act, varname, 0 /*throw_flag*/);
/* [ ... func varmap enum key value this ] */
- duk_debug_write_hstring(thr, duk_get_hstring(ctx, -3));
- duk_debug_write_tval(thr, duk_get_tval(ctx, -2));
- duk_pop_3(ctx); /* -> [ ... func varmap enum ] */
+ duk_debug_write_hstring(thr, duk_get_hstring(thr, -3));
+ duk_debug_write_tval(thr, duk_get_tval(thr, -2));
+ duk_pop_3(thr); /* -> [ ... func varmap enum ] */
}
} else {
DUK_D(DUK_DPRINT("varmap is not an object in GetLocals, ignore"));
@@ -42068,13 +43398,12 @@ DUK_LOCAL void duk__debug_handle_get_locals(duk_hthread *thr, duk_heap *heap) {
}
DUK_LOCAL void duk__debug_handle_eval(duk_hthread *thr, duk_heap *heap) {
- duk_context *ctx = (duk_context *) thr;
duk_small_uint_t call_flags;
duk_int_t call_ret;
duk_small_int_t eval_err;
- duk_int_t num_eval_args;
duk_bool_t direct_eval;
duk_int32_t level;
+ duk_idx_t idx_func;
DUK_UNREF(heap);
@@ -42089,8 +43418,9 @@ DUK_LOCAL void duk__debug_handle_eval(duk_hthread *thr, duk_heap *heap) {
*/
/* nargs == 2 so we can pass a callstack index to eval(). */
- duk_push_c_function(ctx, duk_bi_global_object_eval, 2 /*nargs*/);
- duk_push_undefined(ctx); /* 'this' binding shouldn't matter here */
+ idx_func = duk_get_top(thr);
+ duk_push_c_function(thr, duk_bi_global_object_eval, 2 /*nargs*/);
+ duk_push_undefined(thr); /* 'this' binding shouldn't matter here */
/* Read callstack index, if non-null. */
if (duk_debug_peek_byte(thr) == DUK_DBG_IB_NULL) {
@@ -42110,32 +43440,31 @@ DUK_LOCAL void duk__debug_handle_eval(duk_hthread *thr, duk_heap *heap) {
(void) duk_debug_read_hstring(thr);
if (direct_eval) {
- num_eval_args = 2;
- duk_push_int(ctx, level - 1); /* compensate for eval() call */
- } else {
- num_eval_args = 1;
+ duk_push_int(thr, level - 1); /* compensate for eval() call */
}
- /* [ ... eval "eval" eval_input level ] */
+ /* [ ... eval "eval" eval_input level? ] */
call_flags = 0;
- if (direct_eval && thr->callstack_top >= (duk_size_t) -level) {
+ if (direct_eval) {
duk_activation *act;
duk_hobject *fun;
- act = thr->callstack + thr->callstack_top + level;
- fun = DUK_ACT_GET_FUNC(act);
- if (fun != NULL && DUK_HOBJECT_IS_COMPFUNC(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
- * call we'll need to do an indirect eval instead.
- */
- call_flags |= DUK_CALL_FLAG_DIRECT_EVAL;
+ act = duk_hthread_get_activation_for_level(thr, level);
+ if (act != NULL) {
+ fun = DUK_ACT_GET_FUNC(act);
+ if (fun != NULL && DUK_HOBJECT_IS_COMPFUNC(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
+ * call we'll need to do an indirect eval instead.
+ */
+ call_flags |= DUK_CALL_FLAG_DIRECT_EVAL;
+ }
}
}
- call_ret = duk_handle_call_protected(thr, num_eval_args, call_flags);
+ call_ret = duk_pcall_method_flags(thr, duk_get_top(thr) - (idx_func + 2), call_flags);
if (call_ret == DUK_EXEC_SUCCESS) {
eval_err = 0;
@@ -42146,15 +43475,15 @@ DUK_LOCAL void duk__debug_handle_eval(duk_hthread *thr, duk_heap *heap) {
* to traverse the error object.
*/
eval_err = 1;
- duk_safe_to_string(ctx, -1);
+ duk_safe_to_string(thr, -1);
}
/* [ ... result ] */
duk_debug_write_reply(thr);
duk_debug_write_int(thr, (duk_int32_t) eval_err);
- DUK_ASSERT(duk_get_tval(ctx, -1) != NULL);
- duk_debug_write_tval(thr, duk_get_tval(ctx, -1));
+ DUK_ASSERT(duk_get_tval(thr, -1) != NULL);
+ duk_debug_write_tval(thr, duk_get_tval(thr, -1));
duk_debug_write_eom(thr);
}
@@ -42170,12 +43499,11 @@ DUK_LOCAL void duk__debug_handle_detach(duk_hthread *thr, duk_heap *heap) {
}
DUK_LOCAL void duk__debug_handle_apprequest(duk_hthread *thr, duk_heap *heap) {
- duk_context *ctx = (duk_context *) thr;
duk_idx_t old_top;
DUK_D(DUK_DPRINT("debug command AppRequest"));
- old_top = duk_get_top(ctx); /* save stack top */
+ old_top = duk_get_top(thr); /* save stack top */
if (heap->dbg_request_cb != NULL) {
duk_idx_t nrets;
@@ -42187,7 +43515,7 @@ DUK_LOCAL void duk__debug_handle_apprequest(duk_hthread *thr, duk_heap *heap) {
*/
while (duk_debug_peek_byte(thr) != DUK_DBG_IB_EOM) {
duk_tval *tv;
- if (!duk_check_stack(ctx, 1)) {
+ if (!duk_check_stack(thr, 1)) {
DUK_D(DUK_DPRINT("failed to allocate space for request dvalue(s)"));
goto fail;
}
@@ -42198,41 +43526,41 @@ DUK_LOCAL void duk__debug_handle_apprequest(duk_hthread *thr, duk_heap *heap) {
}
nvalues++;
}
- DUK_ASSERT(duk_get_top(ctx) == old_top + nvalues);
+ DUK_ASSERT(duk_get_top(thr) == old_top + nvalues);
/* Request callback should push values for reply to client onto valstack */
DUK_D(DUK_DPRINT("calling into AppRequest request_cb with nvalues=%ld, old_top=%ld, top=%ld",
- (long) nvalues, (long) old_top, (long) duk_get_top(ctx)));
- nrets = heap->dbg_request_cb(ctx, heap->dbg_udata, nvalues);
+ (long) nvalues, (long) old_top, (long) duk_get_top(thr)));
+ nrets = heap->dbg_request_cb(thr, heap->dbg_udata, nvalues);
DUK_D(DUK_DPRINT("returned from AppRequest request_cb; nvalues=%ld -> nrets=%ld, old_top=%ld, top=%ld",
- (long) nvalues, (long) nrets, (long) old_top, (long) duk_get_top(ctx)));
+ (long) nvalues, (long) nrets, (long) old_top, (long) duk_get_top(thr)));
if (nrets >= 0) {
- DUK_ASSERT(duk_get_top(ctx) >= old_top + nrets);
- if (duk_get_top(ctx) < old_top + nrets) {
+ DUK_ASSERT(duk_get_top(thr) >= old_top + nrets);
+ if (duk_get_top(thr) < old_top + nrets) {
DUK_D(DUK_DPRINT("AppRequest callback doesn't match value stack configuration, "
"top=%ld < old_top=%ld + nrets=%ld; "
"this might mean it's unsafe to continue!",
- (long) duk_get_top(ctx), (long) old_top, (long) nrets));
+ (long) duk_get_top(thr), (long) old_top, (long) nrets));
goto fail;
}
/* Reply with tvals pushed by request callback */
duk_debug_write_byte(thr, DUK_DBG_IB_REPLY);
- top = duk_get_top(ctx);
+ top = duk_get_top(thr);
for (idx = top - nrets; idx < top; idx++) {
- duk_debug_write_tval(thr, DUK_GET_TVAL_POSIDX(ctx, idx));
+ duk_debug_write_tval(thr, DUK_GET_TVAL_POSIDX(thr, idx));
}
duk_debug_write_eom(thr);
} else {
- DUK_ASSERT(duk_get_top(ctx) >= old_top + 1);
- if (duk_get_top(ctx) < old_top + 1) {
+ DUK_ASSERT(duk_get_top(thr) >= old_top + 1);
+ if (duk_get_top(thr) < old_top + 1) {
DUK_D(DUK_DPRINT("request callback return value doesn't match value stack configuration"));
goto fail;
}
- duk_debug_write_error_eom(thr, DUK_DBG_ERR_APPLICATION, duk_get_string(ctx, -1));
+ duk_debug_write_error_eom(thr, DUK_DBG_ERR_APPLICATION, duk_get_string(thr, -1));
}
- duk_set_top(ctx, old_top); /* restore stack top */
+ duk_set_top(thr, old_top); /* restore stack top */
} else {
DUK_D(DUK_DPRINT("no request callback, treat AppRequest as unsupported"));
duk_debug_write_error_eom(thr, DUK_DBG_ERR_UNSUPPORTED, "AppRequest unsupported by target");
@@ -42241,7 +43569,7 @@ DUK_LOCAL void duk__debug_handle_apprequest(duk_hthread *thr, duk_heap *heap) {
return;
fail:
- duk_set_top(ctx, old_top); /* restore stack top */
+ duk_set_top(thr, old_top); /* restore stack top */
DUK__SET_CONN_BROKEN(thr, 1);
}
@@ -42269,9 +43597,9 @@ DUK_LOCAL void duk__debug_dump_heaphdr(duk_hthread *thr, duk_heap *heap, duk_hea
case DUK_HTYPE_STRING: {
duk_hstring *h = (duk_hstring *) hdr;
- duk_debug_write_uint(thr, (duk_int32_t) DUK_HSTRING_GET_BYTELEN(h));
- duk_debug_write_uint(thr, (duk_int32_t) DUK_HSTRING_GET_CHARLEN(h));
- duk_debug_write_uint(thr, (duk_int32_t) DUK_HSTRING_GET_HASH(h));
+ duk_debug_write_uint(thr, (duk_uint32_t) DUK_HSTRING_GET_BYTELEN(h));
+ duk_debug_write_uint(thr, (duk_uint32_t) DUK_HSTRING_GET_CHARLEN(h));
+ duk_debug_write_uint(thr, (duk_uint32_t) DUK_HSTRING_GET_HASH(h));
duk_debug_write_hstring(thr, h);
break;
}
@@ -42398,11 +43726,10 @@ DUK_LOCAL void duk__debug_handle_get_bytecode(duk_hthread *thr, duk_heap *heap)
}
if (fun == NULL) {
- if (level >= 0 || -level > (duk_int32_t) thr->callstack_top) {
- DUK_D(DUK_DPRINT("invalid callstack index for GetBytecode"));
+ act = duk_hthread_get_activation_for_level(thr, level);
+ if (act == NULL) {
goto fail_index;
}
- act = thr->callstack + thr->callstack_top + level;
fun = (duk_hcompfunc *) DUK_ACT_GET_FUNC(act);
}
@@ -42494,6 +43821,7 @@ DUK_LOCAL duk_uint_t duk__debug_getinfo_hstring_masks[] = {
DUK_LOCAL const char * const duk__debug_getinfo_hobject_keys[] = {
"extensible",
"constructable",
+ "callable",
"boundfunc",
"compfunc",
"natfunc",
@@ -42505,17 +43833,18 @@ DUK_LOCAL const char * const duk__debug_getinfo_hobject_keys[] = {
"newenv",
"namebinding",
"createargs",
- "have_finalizer"
+ "have_finalizer",
"exotic_array",
"exotic_stringobj",
"exotic_arguments",
- "exotic_dukfunc",
- "exotic_proxyobj"
+ "exotic_proxyobj",
+ "special_call"
/* NULL not needed here */
};
DUK_LOCAL duk_uint_t duk__debug_getinfo_hobject_masks[] = {
DUK_HOBJECT_FLAG_EXTENSIBLE,
DUK_HOBJECT_FLAG_CONSTRUCTABLE,
+ DUK_HOBJECT_FLAG_CALLABLE,
DUK_HOBJECT_FLAG_BOUNDFUNC,
DUK_HOBJECT_FLAG_COMPFUNC,
DUK_HOBJECT_FLAG_NATFUNC,
@@ -42531,8 +43860,8 @@ DUK_LOCAL duk_uint_t duk__debug_getinfo_hobject_masks[] = {
DUK_HOBJECT_FLAG_EXOTIC_ARRAY,
DUK_HOBJECT_FLAG_EXOTIC_STRINGOBJ,
DUK_HOBJECT_FLAG_EXOTIC_ARGUMENTS,
- DUK_HOBJECT_FLAG_EXOTIC_DUKFUNC,
DUK_HOBJECT_FLAG_EXOTIC_PROXYOBJ,
+ DUK_HOBJECT_FLAG_SPECIAL_CALL,
0 /* terminator */
};
DUK_LOCAL const char * const duk__debug_getinfo_hbuffer_keys[] = {
@@ -42575,7 +43904,7 @@ DUK_LOCAL void duk__debug_getinfo_bitmask(duk_hthread *thr, const char * const *
for (;;) {
mask = *masks++;
- if (!mask) {
+ if (mask == 0) {
break;
}
key = *keys++;
@@ -42657,6 +43986,10 @@ DUK_LOCAL void duk__debug_handle_get_heap_obj_info(duk_hthread *thr, duk_heap *h
DUK_D(DUK_DPRINT("debug command GetHeapObjInfo"));
DUK_UNREF(heap);
+ DUK_ASSERT(sizeof(duk__debug_getinfo_hstring_keys) / sizeof(const char *) == sizeof(duk__debug_getinfo_hstring_masks) / sizeof(duk_uint_t) - 1);
+ DUK_ASSERT(sizeof(duk__debug_getinfo_hobject_keys) / sizeof(const char *) == sizeof(duk__debug_getinfo_hobject_masks) / sizeof(duk_uint_t) - 1);
+ DUK_ASSERT(sizeof(duk__debug_getinfo_hbuffer_keys) / sizeof(const char *) == sizeof(duk__debug_getinfo_hbuffer_masks) / sizeof(duk_uint_t) - 1);
+
h = duk_debug_read_any_ptr(thr);
if (!h) {
duk_debug_write_error_eom(thr, DUK_DBG_ERR_UNKNOWN, "invalid target");
@@ -42734,7 +44067,7 @@ DUK_LOCAL void duk__debug_handle_get_heap_obj_info(duk_hthread *thr, duk_heap *h
duk_harray *h_arr;
h_arr = (duk_harray *) h_obj;
- duk__debug_getinfo_prop_int(thr, "length", h_arr->length);
+ duk__debug_getinfo_prop_uint(thr, "length", (duk_uint_t) h_arr->length);
duk__debug_getinfo_prop_bool(thr, "length_nonwritable", h_arr->length_nonwritable);
}
@@ -42786,6 +44119,19 @@ DUK_LOCAL void duk__debug_handle_get_heap_obj_info(duk_hthread *thr, duk_heap *h
}
}
+ if (DUK_HOBJECT_IS_BOUNDFUNC(h_obj)) {
+ duk_hboundfunc *h_bfun;
+ h_bfun = (duk_hboundfunc *) h_obj;
+
+ duk__debug_getinfo_flags_key(thr, "target");
+ duk_debug_write_tval(thr, &h_bfun->target);
+ duk__debug_getinfo_flags_key(thr, "this_binding");
+ duk_debug_write_tval(thr, &h_bfun->this_binding);
+ duk__debug_getinfo_flags_key(thr, "nargs");
+ duk_debug_write_int(thr, h_bfun->nargs);
+ /* h_bfun->args not exposed now */
+ }
+
if (DUK_HOBJECT_IS_THREAD(h_obj)) {
/* XXX: Currently no inspection of threads, e.g. value stack, call
* stack, catch stack, etc.
@@ -42803,7 +44149,7 @@ DUK_LOCAL void duk__debug_handle_get_heap_obj_info(duk_hthread *thr, duk_heap *h
duk_debug_write_heapptr(thr, (duk_heaphdr *) (h_env->thread));
duk__debug_getinfo_flags_key(thr, "varmap");
duk_debug_write_heapptr(thr, (duk_heaphdr *) (h_env->varmap));
- duk__debug_getinfo_prop_uint(thr, "regbase", (duk_uint_t) h_env->regbase);
+ duk__debug_getinfo_prop_uint(thr, "regbase", (duk_uint_t) h_env->regbase_byteoff);
}
if (DUK_HOBJECT_IS_OBJENV(h_obj)) {
@@ -42909,8 +44255,8 @@ DUK_LOCAL void duk__debug_handle_get_obj_prop_desc_range(duk_hthread *thr, duk_h
DUK_UNREF(heap);
h = duk_debug_read_any_ptr(thr);
- idx_start = duk_debug_read_int(thr);
- idx_end = duk_debug_read_int(thr);
+ idx_start = (duk_uint_t) duk_debug_read_int(thr);
+ idx_end = (duk_uint_t) duk_debug_read_int(thr);
if (h == NULL || DUK_HEAPHDR_GET_TYPE(h) != DUK_HTYPE_OBJECT) {
goto fail_args;
}
@@ -42951,7 +44297,6 @@ DUK_LOCAL void duk__debug_handle_get_obj_prop_desc_range(duk_hthread *thr, duk_h
* stack handling which is convenient.
*/
DUK_LOCAL void duk__debug_process_message(duk_hthread *thr) {
- duk_context *ctx = (duk_context *) thr;
duk_heap *heap;
duk_uint8_t x;
duk_int32_t cmd;
@@ -42960,9 +44305,8 @@ DUK_LOCAL void duk__debug_process_message(duk_hthread *thr) {
DUK_ASSERT(thr != NULL);
heap = thr->heap;
DUK_ASSERT(heap != NULL);
- DUK_UNREF(ctx);
- entry_top = duk_get_top(ctx);
+ entry_top = duk_get_top(thr);
x = duk_debug_read_byte(thr);
switch (x) {
@@ -43084,14 +44428,14 @@ DUK_LOCAL void duk__debug_process_message(duk_hthread *thr) {
}
} /* switch initial byte */
- DUK_ASSERT(duk_get_top(ctx) >= entry_top);
- duk_set_top(ctx, entry_top);
+ DUK_ASSERT(duk_get_top(thr) >= entry_top);
+ duk_set_top(thr, entry_top);
duk__debug_skip_to_eom(thr);
return;
fail:
- DUK_ASSERT(duk_get_top(ctx) >= entry_top);
- duk_set_top(ctx, entry_top);
+ DUK_ASSERT(duk_get_top(thr) >= entry_top);
+ duk_set_top(thr, entry_top);
DUK__SET_CONN_BROKEN(thr, 1);
return;
}
@@ -43104,23 +44448,21 @@ DUK_LOCAL void duk__check_resend_status(duk_hthread *thr) {
}
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)
duk_idx_t entry_top;
#endif
duk_bool_t retval = 0;
DUK_ASSERT(thr != NULL);
- DUK_UNREF(ctx);
DUK_ASSERT(thr->heap != NULL);
#if defined(DUK_USE_ASSERTIONS)
- entry_top = duk_get_top(ctx);
+ entry_top = duk_get_top(thr);
#endif
DUK_D(DUK_DPRINT("process debug messages: read_cb=%s, no_block=%ld, detaching=%ld, processing=%ld",
thr->heap->dbg_read_cb ? "not NULL" : "NULL", (long) no_block,
(long) thr->heap->dbg_detaching, (long) thr->heap->dbg_processing));
- DUK_DD(DUK_DDPRINT("top at entry: %ld", (long) duk_get_top(ctx)));
+ DUK_DD(DUK_DDPRINT("top at entry: %ld", (long) duk_get_top(thr)));
/* thr->heap->dbg_detaching may be != 0 if a debugger write outside
* the message loop caused a transport error and detach1() to run.
@@ -43139,7 +44481,7 @@ DUK_INTERNAL duk_bool_t duk_debug_process_messages(duk_hthread *thr, duk_bool_t
/* Process messages until we're no longer paused or we peek
* and see there's nothing to read right now.
*/
- DUK_DD(DUK_DDPRINT("top at loop top: %ld", (long) duk_get_top(ctx)));
+ DUK_DD(DUK_DDPRINT("top at loop top: %ld", (long) duk_get_top(thr)));
DUK_ASSERT(thr->heap->dbg_processing == 1);
while (thr->heap->dbg_read_cb == NULL && thr->heap->dbg_detaching) {
@@ -43210,11 +44552,11 @@ DUK_INTERNAL duk_bool_t duk_debug_process_messages(duk_hthread *thr, duk_bool_t
duk_debug_read_flush(thr); /* this cannot initiate a detach */
DUK_ASSERT(thr->heap->dbg_detaching == 0);
- DUK_DD(DUK_DDPRINT("top at exit: %ld", (long) duk_get_top(ctx)));
+ DUK_DD(DUK_DDPRINT("top at exit: %ld", (long) duk_get_top(thr)));
#if defined(DUK_USE_ASSERTIONS)
/* Easy to get wrong, so assert for it. */
- DUK_ASSERT(entry_top == duk_get_top(ctx));
+ DUK_ASSERT(entry_top == duk_get_top(thr));
#endif
return retval;
@@ -43322,7 +44664,7 @@ DUK_INTERNAL duk_small_int_t duk_debug_add_breakpoint(duk_hthread *thr, duk_hstr
b->line = line;
DUK_HSTRING_INCREF(thr, filename);
- return heap->dbg_breakpoint_count - 1; /* index */
+ return (duk_small_int_t) (heap->dbg_breakpoint_count - 1); /* index */
}
DUK_INTERNAL duk_bool_t duk_debug_remove_breakpoint(duk_hthread *thr, duk_small_uint_t breakpoint_index) {
@@ -43386,7 +44728,7 @@ DUK_INTERNAL void duk_debug_set_paused(duk_heap *heap) {
} else {
DUK_HEAP_SET_DEBUGGER_PAUSED(heap);
heap->dbg_state_dirty = 1;
- duk_debug_clear_step_state(heap);
+ duk_debug_clear_pause_state(heap);
DUK_ASSERT(heap->ms_running == 0); /* debugger can't be triggered within mark-and-sweep */
heap->ms_running = 1; /* prevent mark-and-sweep, prevent refzero queueing */
heap->ms_prevent_count++;
@@ -43399,7 +44741,7 @@ DUK_INTERNAL void duk_debug_clear_paused(duk_heap *heap) {
if (duk_debug_is_paused(heap)) {
DUK_HEAP_CLEAR_DEBUGGER_PAUSED(heap);
heap->dbg_state_dirty = 1;
- duk_debug_clear_step_state(heap);
+ duk_debug_clear_pause_state(heap);
DUK_ASSERT(heap->ms_running == 1);
DUK_ASSERT(heap->ms_prevent_count > 0);
heap->ms_prevent_count--;
@@ -43410,11 +44752,10 @@ DUK_INTERNAL void duk_debug_clear_paused(duk_heap *heap) {
}
}
-DUK_INTERNAL void duk_debug_clear_step_state(duk_heap *heap) {
- heap->dbg_step_type = DUK_STEP_TYPE_NONE;
- heap->dbg_step_thread = NULL;
- heap->dbg_step_csindex = 0;
- heap->dbg_step_startline = 0;
+DUK_INTERNAL void duk_debug_clear_pause_state(duk_heap *heap) {
+ heap->dbg_pause_flags = 0;
+ heap->dbg_pause_act = NULL;
+ heap->dbg_pause_startline = 0;
}
#else /* DUK_USE_DEBUGGER_SUPPORT */
@@ -43424,6 +44765,8 @@ DUK_INTERNAL void duk_debug_clear_step_state(duk_heap *heap) {
#endif /* DUK_USE_DEBUGGER_SUPPORT */
/* automatic undefs */
+#undef DUK__DBG_TPORT_ENTER
+#undef DUK__DBG_TPORT_EXIT
#undef DUK__SET_CONN_BROKEN
/*
* Augmenting errors at their creation site and their throw site.
@@ -43487,17 +44830,15 @@ DUK_INTERNAL void duk_debug_clear_step_state(duk_heap *heap) {
#if defined(DUK_USE_ERRTHROW) || defined(DUK_USE_ERRCREATE)
DUK_LOCAL void duk__err_augment_user(duk_hthread *thr, duk_small_uint_t stridx_cb) {
- duk_context *ctx = (duk_context *) thr;
duk_tval *tv_hnd;
- duk_small_uint_t call_flags;
duk_int_t rc;
DUK_ASSERT(thr != NULL);
DUK_ASSERT(thr->heap != NULL);
DUK_ASSERT_STRIDX_VALID(stridx_cb);
- if (DUK_HEAP_HAS_ERRHANDLER_RUNNING(thr->heap)) {
- DUK_DD(DUK_DDPRINT("recursive call to error handler, ignore"));
+ if (thr->heap->augmenting_error) {
+ DUK_D(DUK_DPRINT("recursive call to error augmentation, ignore"));
return;
}
@@ -43532,45 +44873,33 @@ DUK_LOCAL void duk__err_augment_user(duk_hthread *thr, duk_small_uint_t stridx_c
}
DUK_DDD(DUK_DDDPRINT("error handler dump (callability not checked): %!T",
(duk_tval *) tv_hnd));
- duk_push_tval(ctx, tv_hnd);
+ duk_push_tval(thr, tv_hnd);
/* [ ... errval errhandler ] */
- duk_insert(ctx, -2); /* -> [ ... errhandler errval ] */
- duk_push_undefined(ctx);
- duk_insert(ctx, -2); /* -> [ ... errhandler undefined(= this) errval ] */
+ duk_insert(thr, -2); /* -> [ ... errhandler errval ] */
+ duk_push_undefined(thr);
+ duk_insert(thr, -2); /* -> [ ... errhandler undefined(= this) errval ] */
/* [ ... errhandler undefined errval ] */
/*
- * DUK_CALL_FLAG_IGNORE_RECLIMIT causes duk_handle_call() to ignore C
- * recursion depth limit (and won't increase it either). This is
- * dangerous, but useful because it allows the error handler to run
- * even if the original error is caused by C recursion depth limit.
- *
- * The heap level DUK_HEAP_FLAG_ERRHANDLER_RUNNING is set for the
- * duration of the error handler and cleared afterwards. This flag
- * prevents the error handler from running recursively. The flag is
- * heap level so that the flag properly controls even coroutines
- * launched by an error handler. Since the flag is heap level, it is
- * critical to restore it correctly.
+ * heap->augmenting_error prevents recursive re-entry and also causes
+ * call handling to use a larger (but not unbounded) call stack limit
+ * for the duration of error augmentation.
*
* We ignore errors now: a success return and an error value both
* replace the original error value. (This would be easy to change.)
*/
- DUK_ASSERT(!DUK_HEAP_HAS_ERRHANDLER_RUNNING(thr->heap)); /* since no recursive error handler calls */
- DUK_HEAP_SET_ERRHANDLER_RUNNING(thr->heap);
+ DUK_ASSERT(thr->heap->augmenting_error == 0);
+ thr->heap->augmenting_error = 1;
- call_flags = DUK_CALL_FLAG_IGNORE_RECLIMIT; /* ignore reclimit, not constructor */
-
- rc = duk_handle_call_protected(thr,
- 1, /* num args */
- call_flags); /* call_flags */
+ rc = duk_pcall_method(thr, 1);
DUK_UNREF(rc); /* no need to check now: both success and error are OK */
- DUK_ASSERT(DUK_HEAP_HAS_ERRHANDLER_RUNNING(thr->heap));
- DUK_HEAP_CLEAR_ERRHANDLER_RUNNING(thr->heap);
+ DUK_ASSERT(thr->heap->augmenting_error == 1);
+ thr->heap->augmenting_error = 0;
/* [ ... errval ] */
}
@@ -43581,12 +44910,10 @@ DUK_LOCAL void duk__err_augment_user(duk_hthread *thr, duk_small_uint_t stridx_c
*/
#if defined(DUK_USE_TRACEBACKS)
-DUK_LOCAL void duk__add_traceback(duk_hthread *thr, duk_hthread *thr_callstack, const char *c_filename, duk_int_t c_line, duk_bool_t noblame_fileline) {
- duk_context *ctx = (duk_context *) thr;
- duk_small_uint_t depth;
- duk_int_t i, i_min;
+DUK_LOCAL void duk__add_traceback(duk_hthread *thr, duk_hthread *thr_callstack, const char *c_filename, duk_int_t c_line, duk_small_uint_t flags) {
+ duk_activation *act;
+ duk_int_t depth;
duk_int_t arr_size;
- duk_harray *a;
duk_tval *tv;
duk_hstring *s;
duk_uint32_t u32;
@@ -43594,7 +44921,6 @@ DUK_LOCAL void duk__add_traceback(duk_hthread *thr, duk_hthread *thr_callstack,
DUK_ASSERT(thr != NULL);
DUK_ASSERT(thr_callstack != NULL);
- DUK_ASSERT(ctx != NULL);
/* [ ... error ] */
@@ -43607,13 +44933,25 @@ DUK_LOCAL void duk__add_traceback(duk_hthread *thr, duk_hthread *thr_callstack,
*/
DUK_DDD(DUK_DDDPRINT("adding traceback to object: %!T",
- (duk_tval *) duk_get_tval(ctx, -1)));
+ (duk_tval *) duk_get_tval(thr, -1)));
/* Preallocate array to correct size, so that we can just write out
* the _Tracedata values into the array part.
*/
+ act = thr->callstack_curr;
depth = DUK_USE_TRACEBACK_DEPTH;
- arr_size = (duk_int_t) (thr_callstack->callstack_top <= depth ? thr_callstack->callstack_top : depth) * 2;
+ DUK_ASSERT(thr_callstack->callstack_top <= DUK_INT_MAX); /* callstack limits */
+ if (depth > (duk_int_t) thr_callstack->callstack_top) {
+ depth = (duk_int_t) thr_callstack->callstack_top;
+ }
+ if (depth > 0) {
+ if (flags & DUK_AUGMENT_FLAG_SKIP_ONE) {
+ DUK_ASSERT(act != NULL);
+ act = act->parent;
+ depth--;
+ }
+ }
+ arr_size = depth * 2;
if (thr->compile_ctx != NULL && thr->compile_ctx->h_filename != NULL) {
arr_size += 2;
}
@@ -43622,15 +44960,14 @@ DUK_LOCAL void duk__add_traceback(duk_hthread *thr, duk_hthread *thr_callstack,
* array part pointer to avoid any GC interference while the
* array part is populated.
*/
- duk_push_string(ctx, c_filename);
+ duk_push_string(thr, c_filename);
arr_size += 2;
}
+ /* XXX: uninitialized would be OK */
DUK_D(DUK_DPRINT("preallocated _Tracedata to %ld items", (long) arr_size));
- a = duk_push_harray_with_size(ctx, (duk_uint32_t) arr_size); /* XXX: call which returns array part pointer directly */
- DUK_ASSERT(a != NULL);
- tv = DUK_HOBJECT_A_GET_BASE(thr->heap, (duk_hobject *) a);
- DUK_ASSERT(tv != NULL || arr_size == 0);
+ tv = duk_push_harray_with_size_outptr(thr, (duk_uint32_t) arr_size);
+ DUK_ASSERT(arr_size == 0 || tv != NULL);
/* Compiler SyntaxErrors (and other errors) come first, and are
* blamed by default (not flagged "noblame").
@@ -43661,40 +44998,26 @@ DUK_LOCAL void duk__add_traceback(duk_hthread *thr, duk_hthread *thr_callstack,
DUK_HSTRING_INCREF(thr, s);
tv++;
- d = (noblame_fileline ? ((duk_double_t) DUK_TB_FLAG_NOBLAME_FILELINE) * DUK_DOUBLE_2TO32 : 0.0) +
+ d = ((flags & DUK_AUGMENT_FLAG_NOBLAME_FILELINE) ? ((duk_double_t) DUK_TB_FLAG_NOBLAME_FILELINE) * DUK_DOUBLE_2TO32 : 0.0) +
(duk_double_t) c_line;
DUK_TVAL_SET_DOUBLE(tv, d);
tv++;
}
- /* traceback depth doesn't take into account the filename/line
- * special handling above (intentional)
+ /* Traceback depth doesn't take into account the filename/line
+ * special handling above (intentional).
*/
- depth = DUK_USE_TRACEBACK_DEPTH;
- i_min = (thr_callstack->callstack_top > (duk_size_t) depth ? (duk_int_t) (thr_callstack->callstack_top - depth) : 0);
- DUK_ASSERT(i_min >= 0);
-
- /* [ ... error c_filename? arr ] */
-
- DUK_ASSERT(thr_callstack->callstack_top <= DUK_INT_MAX); /* callstack limits */
- for (i = (duk_int_t) (thr_callstack->callstack_top - 1); i >= i_min; i--) {
+ for (; depth-- > 0; act = act->parent) {
duk_uint32_t pc;
duk_tval *tv_src;
- /*
- * Note: each API operation potentially resizes the callstack,
- * so be careful to re-lookup after every operation. Currently
- * these is no issue because we don't store a temporary 'act'
- * pointer at all. (This would be a non-issue if we operated
- * directly on the array part.)
- */
-
/* [... arr] */
- DUK_ASSERT_DISABLE(thr_callstack->callstack[i].pc >= 0); /* unsigned */
+ DUK_ASSERT(act != NULL); /* depth check above, assumes book-keeping is correct */
+ DUK_ASSERT_DISABLE(act->pc >= 0); /* unsigned */
/* Add function object. */
- tv_src = &(thr_callstack->callstack + i)->tv_func; /* object (function) or lightfunc */
+ tv_src = &act->tv_func; /* object (function) or lightfunc */
DUK_ASSERT(DUK_TVAL_IS_OBJECT(tv_src) || DUK_TVAL_IS_LIGHTFUNC(tv_src));
DUK_TVAL_SET_TVAL(tv, tv_src);
DUK_TVAL_INCREF(thr, tv);
@@ -43705,26 +45028,33 @@ 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 = duk_hthread_get_act_prev_pc(thr_callstack, thr_callstack->callstack + i);
+ pc = (duk_uint32_t) duk_hthread_get_act_prev_pc(thr_callstack, 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 */
- d = ((duk_double_t) thr_callstack->callstack[i].flags) * DUK_DOUBLE_2TO32 + (duk_double_t) pc;
+ d = ((duk_double_t) act->flags) * DUK_DOUBLE_2TO32 + (duk_double_t) pc;
DUK_TVAL_SET_DOUBLE(tv, d);
tv++;
}
- DUK_ASSERT((duk_uint32_t) (tv - DUK_HOBJECT_A_GET_BASE(thr->heap, (duk_hobject *) a)) == a->length);
- DUK_ASSERT(a->length == (duk_uint32_t) arr_size);
+#if defined(DUK_USE_ASSERTIONS)
+ {
+ duk_harray *a;
+ a = (duk_harray *) duk_known_hobject(thr, -1);
+ DUK_ASSERT(a != NULL);
+ DUK_ASSERT((duk_uint32_t) (tv - DUK_HOBJECT_A_GET_BASE(thr->heap, (duk_hobject *) a)) == a->length);
+ DUK_ASSERT(a->length == (duk_uint32_t) arr_size);
+ }
+#endif
/* [ ... error c_filename? arr ] */
if (c_filename) {
- duk_remove_m2(ctx);
+ duk_remove_m2(thr);
}
/* [ ... error arr ] */
- duk_xdef_prop_stridx_short_wec(ctx, -2, DUK_STRIDX_INT_TRACEDATA); /* -> [ ... error ] */
+ duk_xdef_prop_stridx_short_wec(thr, -2, DUK_STRIDX_INT_TRACEDATA); /* -> [ ... error ] */
}
#endif /* DUK_USE_TRACEBACKS */
@@ -43733,15 +45063,13 @@ DUK_LOCAL void duk__add_traceback(duk_hthread *thr, duk_hthread *thr_callstack,
*/
#if defined(DUK_USE_AUGMENT_ERROR_CREATE) && !defined(DUK_USE_TRACEBACKS)
-DUK_LOCAL void duk__add_fileline(duk_hthread *thr, duk_hthread *thr_callstack, const char *c_filename, duk_int_t c_line, duk_bool_t noblame_fileline) {
- duk_context *ctx;
+DUK_LOCAL void duk__add_fileline(duk_hthread *thr, duk_hthread *thr_callstack, const char *c_filename, duk_int_t c_line, duk_small_uint_t flags) {
#if defined(DUK_USE_ASSERTIONS)
duk_int_t entry_top;
#endif
- ctx = (duk_context *) thr;
#if defined(DUK_USE_ASSERTIONS)
- entry_top = duk_get_top(ctx);
+ entry_top = duk_get_top(thr);
#endif
/*
@@ -43756,37 +45084,33 @@ DUK_LOCAL void duk__add_fileline(duk_hthread *thr, duk_hthread *thr_callstack, c
/* Compiler SyntaxError (or other error) gets the primary blame.
* Currently no flag to prevent blaming.
*/
- duk_push_uint(ctx, (duk_uint_t) thr->compile_ctx->curr_token.start_line);
- duk_push_hstring(ctx, thr->compile_ctx->h_filename);
- } else if (c_filename && !noblame_fileline) {
+ duk_push_uint(thr, (duk_uint_t) thr->compile_ctx->curr_token.start_line);
+ duk_push_hstring(thr, thr->compile_ctx->h_filename);
+ } else if (c_filename && (flags & DUK_AUGMENT_FLAG_NOBLAME_FILELINE) == 0) {
/* C call site gets blamed next, unless flagged not to do so.
* XXX: file/line is disabled in minimal builds, so disable this
* too when appropriate.
*/
- duk_push_int(ctx, c_line);
- duk_push_string(ctx, c_filename);
+ duk_push_int(thr, c_line);
+ duk_push_string(thr, c_filename);
} else {
/* Finally, blame the innermost callstack entry which has a
* .fileName property.
*/
duk_small_uint_t depth;
- duk_int_t i, i_min;
duk_uint32_t ecma_line;
-
- depth = DUK_USE_TRACEBACK_DEPTH;
- i_min = (thr_callstack->callstack_top > (duk_size_t) depth ? (duk_int_t) (thr_callstack->callstack_top - depth) : 0);
- DUK_ASSERT(i_min >= 0);
+ duk_activation *act;
DUK_ASSERT(thr_callstack->callstack_top <= DUK_INT_MAX); /* callstack limits */
- for (i = (duk_int_t) (thr_callstack->callstack_top - 1); i >= i_min; i--) {
- duk_activation *act;
+ depth = DUK_USE_TRACEBACK_DEPTH;
+ if (depth > thr_callstack->callstack_top) {
+ depth = thr_callstack->callstack_top;
+ }
+ for (act = thr_callstack->callstack_curr; depth-- > 0; act = act->parent) {
duk_hobject *func;
duk_uint32_t pc;
- DUK_UNREF(pc);
- act = thr_callstack->callstack + i;
- DUK_ASSERT(act >= thr_callstack->callstack && act < thr_callstack->callstack + thr_callstack->callstack_size);
-
+ DUK_ASSERT(act != NULL);
func = DUK_ACT_GET_FUNC(act);
if (func == NULL) {
/* Lightfunc, not blamed now. */
@@ -43797,17 +45121,18 @@ DUK_LOCAL void duk__add_fileline(duk_hthread *thr, duk_hthread *thr_callstack, c
* PC == 0 for native code.
*/
pc = duk_hthread_get_act_prev_pc(thr, act); /* thr argument only used for thr->heap, so specific thread doesn't matter */
+ DUK_UNREF(pc);
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 */
- duk_push_hobject(ctx, func);
+ duk_push_hobject(thr, func);
/* [ ... error func ] */
- duk_get_prop_stridx_short(ctx, -1, DUK_STRIDX_FILE_NAME);
- if (!duk_is_string_notsymbol(ctx, -1)) {
- duk_pop_2(ctx);
+ duk_get_prop_stridx_short(thr, -1, DUK_STRIDX_FILE_NAME);
+ if (!duk_is_string_notsymbol(thr, -1)) {
+ duk_pop_2(thr);
continue;
}
@@ -43816,16 +45141,16 @@ DUK_LOCAL void duk__add_fileline(duk_hthread *thr, duk_hthread *thr_callstack, c
ecma_line = 0;
#if defined(DUK_USE_PC2LINE)
if (DUK_HOBJECT_IS_COMPFUNC(func)) {
- ecma_line = duk_hobject_pc2line_query(ctx, -2, (duk_uint_fast32_t) pc);
+ ecma_line = duk_hobject_pc2line_query(thr, -2, (duk_uint_fast32_t) pc);
} else {
/* Native function, no relevant lineNumber. */
}
#endif /* DUK_USE_PC2LINE */
- duk_push_u32(ctx, ecma_line);
+ duk_push_u32(thr, ecma_line);
/* [ ... error func fileName lineNumber ] */
- duk_replace(ctx, -3);
+ duk_replace(thr, -3);
/* [ ... error lineNumber fileName ] */
goto define_props;
@@ -43835,17 +45160,17 @@ DUK_LOCAL void duk__add_fileline(duk_hthread *thr, duk_hthread *thr_callstack, c
* .lineNumber (matches what we do with a _Tracedata based
* no-match lookup.
*/
- duk_push_undefined(ctx);
- duk_push_undefined(ctx);
+ duk_push_undefined(thr);
+ duk_push_undefined(thr);
}
define_props:
/* [ ... error lineNumber fileName ] */
#if defined(DUK_USE_ASSERTIONS)
- DUK_ASSERT(duk_get_top(ctx) == entry_top + 2);
+ DUK_ASSERT(duk_get_top(thr) == entry_top + 2);
#endif
- duk_xdef_prop_stridx_short(ctx, -3, DUK_STRIDX_FILE_NAME, DUK_PROPDESC_FLAGS_C | DUK_PROPDESC_FLAG_NO_OVERWRITE);
- duk_xdef_prop_stridx_short(ctx, -2, DUK_STRIDX_LINE_NUMBER, DUK_PROPDESC_FLAGS_C | DUK_PROPDESC_FLAG_NO_OVERWRITE);
+ duk_xdef_prop_stridx_short(thr, -3, DUK_STRIDX_FILE_NAME, DUK_PROPDESC_FLAGS_C | DUK_PROPDESC_FLAG_NO_OVERWRITE);
+ duk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_LINE_NUMBER, DUK_PROPDESC_FLAGS_C | DUK_PROPDESC_FLAG_NO_OVERWRITE);
}
#endif /* DUK_USE_AUGMENT_ERROR_CREATE && !DUK_USE_TRACEBACKS */
@@ -43855,7 +45180,6 @@ DUK_LOCAL void duk__add_fileline(duk_hthread *thr, duk_hthread *thr_callstack, c
#if defined(DUK_USE_AUGMENT_ERROR_CREATE)
DUK_LOCAL void duk__add_compiler_error_line(duk_hthread *thr) {
- duk_context *ctx;
/* Append a "(line NNN)" to the "message" property of any error
* thrown during compilation. Usually compilation errors are
@@ -43865,26 +45189,25 @@ DUK_LOCAL void duk__add_compiler_error_line(duk_hthread *thr) {
/* [ ... error ] */
- ctx = (duk_context *) thr;
- DUK_ASSERT(duk_is_object(ctx, -1));
+ DUK_ASSERT(duk_is_object(thr, -1));
if (!(thr->compile_ctx != NULL && thr->compile_ctx->h_filename != NULL)) {
return;
}
DUK_DDD(DUK_DDDPRINT("compile error, before adding line info: %!T",
- (duk_tval *) duk_get_tval(ctx, -1)));
+ (duk_tval *) duk_get_tval(thr, -1)));
- if (duk_get_prop_stridx_short(ctx, -1, DUK_STRIDX_MESSAGE)) {
- duk_push_sprintf(ctx, " (line %ld)", (long) thr->compile_ctx->curr_token.start_line);
- duk_concat(ctx, 2);
- duk_put_prop_stridx_short(ctx, -2, DUK_STRIDX_MESSAGE);
+ if (duk_get_prop_stridx_short(thr, -1, DUK_STRIDX_MESSAGE)) {
+ duk_push_sprintf(thr, " (line %ld)", (long) thr->compile_ctx->curr_token.start_line);
+ duk_concat(thr, 2);
+ duk_put_prop_stridx_short(thr, -2, DUK_STRIDX_MESSAGE);
} else {
- duk_pop(ctx);
+ duk_pop(thr);
}
DUK_DDD(DUK_DDDPRINT("compile error, after adding line info: %!T",
- (duk_tval *) duk_get_tval(ctx, -1)));
+ (duk_tval *) duk_get_tval(thr, -1)));
}
#endif /* DUK_USE_AUGMENT_ERROR_CREATE */
@@ -43894,19 +45217,17 @@ DUK_LOCAL void duk__add_compiler_error_line(duk_hthread *thr) {
*/
#if defined(DUK_USE_AUGMENT_ERROR_CREATE)
-DUK_LOCAL void duk__err_augment_builtin_create(duk_hthread *thr, duk_hthread *thr_callstack, const char *c_filename, duk_int_t c_line, duk_small_int_t noblame_fileline, duk_hobject *obj) {
- duk_context *ctx = (duk_context *) thr;
+DUK_LOCAL void duk__err_augment_builtin_create(duk_hthread *thr, duk_hthread *thr_callstack, const char *c_filename, duk_int_t c_line, duk_hobject *obj, duk_small_uint_t flags) {
#if defined(DUK_USE_ASSERTIONS)
duk_int_t entry_top;
#endif
#if defined(DUK_USE_ASSERTIONS)
- entry_top = duk_get_top(ctx);
+ entry_top = duk_get_top(thr);
#endif
DUK_ASSERT(obj != NULL);
DUK_UNREF(obj); /* unreferenced w/o tracebacks */
- DUK_UNREF(ctx); /* unreferenced w/o asserts */
duk__add_compiler_error_line(thr);
@@ -43918,17 +45239,17 @@ DUK_LOCAL void duk__err_augment_builtin_create(duk_hthread *thr, duk_hthread *th
if (duk_hobject_hasprop_raw(thr, obj, DUK_HTHREAD_STRING_INT_TRACEDATA(thr))) {
DUK_DDD(DUK_DDDPRINT("error value already has a '_Tracedata' property, not modifying it"));
} else {
- duk__add_traceback(thr, thr_callstack, c_filename, c_line, noblame_fileline);
+ duk__add_traceback(thr, thr_callstack, c_filename, c_line, flags);
}
#else
/* Without tracebacks the concrete .fileName and .lineNumber need
* to be added directly.
*/
- duk__add_fileline(thr, thr_callstack, c_filename, c_line, noblame_fileline);
+ duk__add_fileline(thr, thr_callstack, c_filename, c_line, flags);
#endif
#if defined(DUK_USE_ASSERTIONS)
- DUK_ASSERT(duk_get_top(ctx) == entry_top);
+ DUK_ASSERT(duk_get_top(thr) == entry_top);
#endif
}
#endif /* DUK_USE_AUGMENT_ERROR_CREATE */
@@ -43942,22 +45263,18 @@ DUK_LOCAL void duk__err_augment_builtin_create(duk_hthread *thr, duk_hthread *th
* thr_callstack: thread which should be used for generating callstack etc.
* c_filename: C __FILE__ related to the error
* c_line: C __LINE__ related to the error
- * noblame_fileline: if true, don't fileName/line as error source, otherwise use traceback
- * (needed because user code filename/line are reported but internal ones
- * are not)
- *
- * XXX: rename noblame_fileline to flags field; combine it to some existing
- * field (there are only a few call sites so this may not be worth it).
+ * flags & DUK_AUGMENT_FLAG_NOBLAME_FILELINE:
+ * if true, don't fileName/line as error source, otherwise use traceback
+ * (needed because user code filename/line are reported but internal ones
+ * are not)
*/
#if defined(DUK_USE_AUGMENT_ERROR_CREATE)
-DUK_INTERNAL void duk_err_augment_error_create(duk_hthread *thr, duk_hthread *thr_callstack, const char *c_filename, duk_int_t c_line, duk_bool_t noblame_fileline) {
- duk_context *ctx = (duk_context *) thr;
+DUK_INTERNAL void duk_err_augment_error_create(duk_hthread *thr, duk_hthread *thr_callstack, const char *c_filename, duk_int_t c_line, duk_small_uint_t flags) {
duk_hobject *obj;
DUK_ASSERT(thr != NULL);
DUK_ASSERT(thr_callstack != NULL);
- DUK_ASSERT(ctx != NULL);
/* [ ... error ] */
@@ -43973,7 +45290,7 @@ DUK_INTERNAL void duk_err_augment_error_create(duk_hthread *thr, duk_hthread *th
* - error value is an extensible object
*/
- obj = duk_get_hobject(ctx, -1);
+ obj = duk_get_hobject(thr, -1);
if (!obj) {
DUK_DDD(DUK_DDDPRINT("value is not an object, skip both built-in and user augment"));
return;
@@ -43988,7 +45305,7 @@ DUK_INTERNAL void duk_err_augment_error_create(duk_hthread *thr, duk_hthread *th
}
if (DUK_HOBJECT_HAS_EXTENSIBLE(obj)) {
DUK_DDD(DUK_DDDPRINT("error meets criteria, built-in augment"));
- duk__err_augment_builtin_create(thr, thr_callstack, c_filename, c_line, noblame_fileline, obj);
+ duk__err_augment_builtin_create(thr, thr_callstack, c_filename, c_line, obj, flags);
} else {
DUK_DDD(DUK_DDDPRINT("error does not meet criteria, no built-in augment"));
}
@@ -44023,32 +45340,32 @@ DUK_INTERNAL void duk_err_augment_error_throw(duk_hthread *thr) {
#if defined(DUK_USE_PREFER_SIZE)
DUK_LOCAL void duk__uncaught_minimal(duk_hthread *thr) {
- (void) duk_fatal((duk_context *) thr, "uncaught error");
+ (void) duk_fatal(thr, "uncaught error");
}
#endif
#if 0
DUK_LOCAL void duk__uncaught_readable(duk_hthread *thr) {
const char *summary;
- char buf[64];
+ char buf[DUK_USE_FATAL_MAXLEN];
- summary = duk_push_string_tval_readable((duk_context *) thr, &thr->heap->lj.value1);
+ summary = duk_push_string_tval_readable(thr, &thr->heap->lj.value1);
DUK_SNPRINTF(buf, sizeof(buf), "uncaught: %s", summary);
buf[sizeof(buf) - 1] = (char) 0;
- (void) duk_fatal((duk_context *) thr, (const char *) buf);
+ (void) duk_fatal(thr, (const char *) buf);
}
#endif
#if !defined(DUK_USE_PREFER_SIZE)
DUK_LOCAL void duk__uncaught_error_aware(duk_hthread *thr) {
const char *summary;
- char buf[64];
+ char buf[DUK_USE_FATAL_MAXLEN];
- summary = duk_push_string_tval_readable_error((duk_context *) thr, &thr->heap->lj.value1);
+ summary = duk_push_string_tval_readable_error(thr, &thr->heap->lj.value1);
DUK_ASSERT(summary != NULL);
DUK_SNPRINTF(buf, sizeof(buf), "uncaught: %s", summary);
buf[sizeof(buf) - 1] = (char) 0;
- (void) duk_fatal((duk_context *) thr, (const char *) buf);
+ (void) duk_fatal(thr, (const char *) buf);
}
#endif
@@ -44131,32 +45448,31 @@ DUK_INTERNAL void duk_err_longjmp(duk_hthread *thr) {
* catcher. Protected calls or finally blocks aren't considered catching.
*/
-#if defined(DUK_USE_DEBUGGER_SUPPORT) && \
- (defined(DUK_USE_DEBUGGER_THROW_NOTIFY) || defined(DUK_USE_DEBUGGER_PAUSE_UNCAUGHT))
+#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?
+ /* 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_activation *act;
+ duk_catcher *cat;
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 */
+ for (; thr != NULL; thr = thr->resumer) {
+ for (act = thr->callstack_curr; act != NULL; act = act->parent) {
+ for (cat = act->cat; cat != NULL; cat = cat->parent) {
+ if (DUK_CAT_HAS_CATCH_ENABLED(cat)) {
+ return 1; /* all we need to know */
+ }
}
}
- thr = thr->resumer;
}
return 0;
}
-#endif /* DUK_USE_DEBUGGER_SUPPORT && (DUK_USE_DEBUGGER_THROW_NOTIFY || DUK_USE_DEBUGGER_PAUSE_UNCAUGHT) */
+#endif /* DUK_USE_DEBUGGER_SUPPORT */
/*
* Get prototype object for an integer error code.
@@ -44187,10 +45503,8 @@ DUK_INTERNAL duk_hobject *duk_error_prototype_from_code(duk_hthread *thr, duk_er
*/
#if defined(DUK_USE_DEBUGGER_SUPPORT)
-#if defined(DUK_USE_DEBUGGER_THROW_NOTIFY) || defined(DUK_USE_DEBUGGER_PAUSE_UNCAUGHT)
DUK_INTERNAL void duk_err_check_debugger_integration(duk_hthread *thr) {
- duk_context *ctx = (duk_context *) thr;
- duk_bool_t fatal;
+ duk_bool_t uncaught;
duk_tval *tv_obj;
/* If something is thrown with the debugger attached and nobody will
@@ -44228,14 +45542,14 @@ DUK_INTERNAL void duk_err_check_debugger_integration(duk_hthread *thr) {
return;
}
- fatal = !duk__have_active_catcher(thr);
+ uncaught = !duk__have_active_catcher(thr);
/* Debugger code expects the value at stack top. This also serves
* as a backup: we need to store/restore the longjmp state because
* when the debugger is paused Eval commands may be executed and
* they can arbitrarily clobber the longjmp state.
*/
- duk_push_tval(ctx, tv_obj);
+ duk_push_tval(thr, tv_obj);
/* Store and reset longjmp state. */
DUK_ASSERT_LJSTATE_SET(thr->heap);
@@ -44248,33 +45562,33 @@ DUK_INTERNAL void duk_err_check_debugger_integration(duk_hthread *thr) {
#if defined(DUK_USE_DEBUGGER_THROW_NOTIFY)
/* Report it to the debug client */
DUK_D(DUK_DPRINT("throw with debugger attached, report to client"));
- duk_debug_send_throw(thr, fatal);
+ duk_debug_send_throw(thr, uncaught);
#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*/);
+ if (uncaught) {
+ if (thr->heap->dbg_pause_flags & DUK_PAUSE_FLAG_UNCAUGHT_ERROR) {
+ DUK_D(DUK_DPRINT("PAUSE TRIGGERED by uncaught error"));
+ duk_debug_halt_execution(thr, 1 /*use_prev_pc*/);
+ }
+ } else {
+ if (thr->heap->dbg_pause_flags & DUK_PAUSE_FLAG_CAUGHT_ERROR) {
+ DUK_D(DUK_DPRINT("PAUSE TRIGGERED by caught error"));
+ duk_debug_halt_execution(thr, 1 /*use_prev_pc*/);
+ }
}
-#endif
/* Restore longjmp state. */
DUK_ASSERT_LJSTATE_UNSET(thr->heap);
thr->heap->lj.type = DUK_LJ_TYPE_THROW;
- tv_obj = DUK_GET_TVAL_NEGIDX(ctx, -1);
+ tv_obj = DUK_GET_TVAL_NEGIDX(thr, -1);
DUK_ASSERT(DUK_TVAL_IS_UNDEFINED(&thr->heap->lj.value1));
DUK_ASSERT(DUK_TVAL_IS_UNDEFINED(&thr->heap->lj.value2));
DUK_TVAL_SET_TVAL(&thr->heap->lj.value1, tv_obj);
DUK_TVAL_INCREF(thr, tv_obj);
DUK_ASSERT_LJSTATE_SET(thr->heap);
- duk_pop(ctx);
-}
-#else /* DUK_USE_DEBUGGER_THROW_NOTIFY || DUK_USE_DEBUGGER_PAUSE_UNCAUGHT */
-DUK_INTERNAL void duk_err_check_debugger_integration(duk_hthread *thr) {
- DUK_UNREF(thr);
+ duk_pop(thr);
}
-#endif /* DUK_USE_DEBUGGER_THROW_NOTIFY || DUK_USE_DEBUGGER_PAUSE_UNCAUGHT */
#endif /* DUK_USE_DEBUGGER_SUPPORT */
/*
@@ -44324,8 +45638,6 @@ DUK_INTERNAL void duk_err_create_and_throw(duk_hthread *thr, duk_errcode_t code,
#else
DUK_INTERNAL void duk_err_create_and_throw(duk_hthread *thr, duk_errcode_t code) {
#endif
- duk_context *ctx = (duk_context *) thr;
-
#if defined(DUK_USE_VERBOSE_ERRORS)
DUK_DD(DUK_DDPRINT("duk_err_create_and_throw(): code=%ld, msg=%s, filename=%s, line=%ld",
(long) code, (const char *) msg,
@@ -44335,7 +45647,6 @@ DUK_INTERNAL void duk_err_create_and_throw(duk_hthread *thr, duk_errcode_t code)
#endif
DUK_ASSERT(thr != NULL);
- DUK_ASSERT(ctx != NULL);
/* Even though nested call is possible because we throw an error when
* trying to create an error, the potential errors must happen before
@@ -44361,10 +45672,6 @@ DUK_INTERNAL void duk_err_create_and_throw(duk_hthread *thr, duk_errcode_t code)
duk_tval tv_val;
duk_hobject *h_err;
-#if 0 /* XXX: not always true because the second throw may come from a different coroutine */
- DUK_ASSERT(thr->callstack_max == DUK_CALLSTACK_DEFAULT_MAX + DUK_CALLSTACK_GROW_STEP + 11);
-#endif
- thr->callstack_max = DUK_CALLSTACK_DEFAULT_MAX;
thr->heap->creating_error = 0;
h_err = thr->builtins[DUK_BIDX_DOUBLE_ERROR];
@@ -44381,30 +45688,27 @@ DUK_INTERNAL void duk_err_create_and_throw(duk_hthread *thr, duk_errcode_t code)
/* No augmentation to avoid any allocations or side effects. */
} else {
- /* 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.
+ /* Prevent infinite recursion. Extra call stack and C
+ * recursion headroom (see GH-191) is added for augmentation.
+ * That is now signalled by heap->augmenting error and taken
+ * into account in call handling without an explicit limit bump.
*/
-#if 0 /* XXX: not always true, second throw may come from a different coroutine */
- DUK_ASSERT(thr->callstack_max == DUK_CALLSTACK_DEFAULT_MAX);
-#endif
- thr->callstack_max = DUK_CALLSTACK_DEFAULT_MAX + DUK_CALLSTACK_GROW_STEP + 11;
thr->heap->creating_error = 1;
- duk_require_stack(ctx, 1);
+ duk_require_stack(thr, 1);
/* XXX: usually unnecessary '%s' formatting here, but cannot
* use 'msg' as a format string directly.
*/
#if defined(DUK_USE_VERBOSE_ERRORS)
- duk_push_error_object_raw(ctx,
+ duk_push_error_object_raw(thr,
code | DUK_ERRCODE_FLAG_NOBLAME_FILELINE,
filename,
line,
"%s",
(const char *) msg);
#else
- duk_push_error_object_raw(ctx,
+ duk_push_error_object_raw(thr,
code | DUK_ERRCODE_FLAG_NOBLAME_FILELINE,
NULL,
0,
@@ -44419,12 +45723,11 @@ DUK_INTERNAL void duk_err_create_and_throw(duk_hthread *thr, duk_errcode_t code)
*/
#if defined(DUK_USE_AUGMENT_ERROR_THROW)
DUK_DDD(DUK_DDDPRINT("THROW ERROR (INTERNAL): %!iT (before throw augment)",
- (duk_tval *) duk_get_tval(ctx, -1)));
+ (duk_tval *) duk_get_tval(thr, -1)));
duk_err_augment_error_throw(thr);
#endif
- duk_err_setup_ljstate1(thr, DUK_LJ_TYPE_THROW, DUK_GET_TVAL_NEGIDX(ctx, -1));
- thr->callstack_max = DUK_CALLSTACK_DEFAULT_MAX;
+ duk_err_setup_ljstate1(thr, DUK_LJ_TYPE_THROW, DUK_GET_TVAL_NEGIDX(thr, -1));
thr->heap->creating_error = 0;
/* Error is now created and we assume no errors can occur any
@@ -44454,8 +45757,6 @@ DUK_INTERNAL void duk_err_create_and_throw(duk_hthread *thr, duk_errcode_t code)
*/
DUK_INTERNAL void duk_error_throw_from_negative_rc(duk_hthread *thr, duk_ret_t rc) {
- duk_context *ctx = (duk_context *) thr;
-
DUK_ASSERT(thr != NULL);
DUK_ASSERT(rc < 0);
@@ -44469,7 +45770,7 @@ DUK_INTERNAL void duk_error_throw_from_negative_rc(duk_hthread *thr, duk_ret_t r
* minimal: they're only really useful for low memory targets.
*/
- duk_error_raw(ctx, -rc, NULL, 0, "error (rc %ld)", (long) rc);
+ duk_error_raw(thr, -rc, NULL, 0, "error (rc %ld)", (long) rc);
DUK_UNREACHABLE();
}
/*
@@ -44607,12 +45908,6 @@ DUK_INTERNAL void *duk_hbuffer_get_dynalloc_ptr(duk_heap *heap, void *ud) {
/*
* duk_hbuffer operations such as resizing and inserting/appending data to
* a dynamic buffer.
- *
- * Append operations append to the end of the buffer and they are relatively
- * efficient: the buffer is grown with a "spare" part relative to the buffer
- * size to minimize reallocations. Insert operations need to move existing
- * data forward in the buffer with memmove() and are not very efficient.
- * They are used e.g. by the regexp compiler to "backpatch" regexp bytecode.
*/
/* #include duk_internal.h -> already included */
@@ -44742,19 +46037,43 @@ DUK_INTERNAL void duk_free_hobject(duk_heap *heap, duk_hobject *h) {
/* Currently nothing to free */
} else if (DUK_HOBJECT_IS_THREAD(h)) {
duk_hthread *t = (duk_hthread *) h;
+ duk_activation *act;
+
DUK_FREE(heap, t->valstack);
- DUK_FREE(heap, t->callstack);
- DUK_FREE(heap, t->catchstack);
+
/* Don't free h->resumer because it exists in the heap.
* Callstack entries also contain function pointers which
- * are not freed for the same reason.
+ * are not freed for the same reason. They are decref
+ * finalized and the targets are freed if necessary based
+ * on their refcount (or reachability).
*/
+ for (act = t->callstack_curr; act != NULL;) {
+ duk_activation *act_next;
+ duk_catcher *cat;
+
+ for (cat = act->cat; cat != NULL;) {
+ duk_catcher *cat_next;
+
+ cat_next = cat->parent;
+ DUK_FREE(heap, (void *) cat);
+ cat = cat_next;
+ }
+
+ act_next = act->parent;
+ DUK_FREE(heap, (void *) act);
+ act = act_next;
+ }
/* XXX: with 'caller' property the callstack would need
* to be unwound to update the 'caller' properties of
* functions in the callstack.
*/
+ } else if (DUK_HOBJECT_IS_BOUNDFUNC(h)) {
+ duk_hboundfunc *f = (duk_hboundfunc *) h;
+
+ DUK_FREE(heap, f->args);
}
+
DUK_FREE(heap, (void *) h);
}
@@ -44820,6 +46139,63 @@ DUK_INTERNAL void duk_heap_free_heaphdr_raw(duk_heap *heap, duk_heaphdr *hdr) {
* after this call.
*/
+#if defined(DUK_USE_CACHE_ACTIVATION)
+DUK_LOCAL duk_size_t duk__heap_free_activation_freelist(duk_heap *heap) {
+ duk_activation *act;
+ duk_activation *act_next;
+ duk_size_t count_act = 0;
+
+ for (act = heap->activation_free; act != NULL;) {
+ act_next = act->parent;
+ DUK_FREE(heap, (void *) act);
+ act = act_next;
+#if defined(DUK_USE_DEBUG)
+ count_act++;
+#endif
+ }
+ heap->activation_free = NULL; /* needed when called from mark-and-sweep */
+ return count_act;
+}
+#endif /* DUK_USE_CACHE_ACTIVATION */
+
+#if defined(DUK_USE_CACHE_CATCHER)
+DUK_LOCAL duk_size_t duk__heap_free_catcher_freelist(duk_heap *heap) {
+ duk_catcher *cat;
+ duk_catcher *cat_next;
+ duk_size_t count_cat = 0;
+
+ for (cat = heap->catcher_free; cat != NULL;) {
+ cat_next = cat->parent;
+ DUK_FREE(heap, (void *) cat);
+ cat = cat_next;
+#if defined(DUK_USE_DEBUG)
+ count_cat++;
+#endif
+ }
+ heap->catcher_free = NULL; /* needed when called from mark-and-sweep */
+
+ return count_cat;
+}
+#endif /* DUK_USE_CACHE_CATCHER */
+
+DUK_INTERNAL void duk_heap_free_freelists(duk_heap *heap) {
+ duk_size_t count_act = 0;
+ duk_size_t count_cat = 0;
+
+#if defined(DUK_USE_CACHE_ACTIVATION)
+ count_act = duk__heap_free_activation_freelist(heap);
+#endif
+#if defined(DUK_USE_CACHE_CATCHER)
+ count_cat = duk__heap_free_catcher_freelist(heap);
+#endif
+ DUK_UNREF(heap);
+ DUK_UNREF(count_act);
+ DUK_UNREF(count_cat);
+
+ DUK_D(DUK_DPRINT("freed %ld activation freelist entries, %ld catcher freelist entries",
+ (long) count_act, (long) count_cat));
+}
+
DUK_LOCAL void duk__free_allocated(duk_heap *heap) {
duk_heaphdr *curr;
duk_heaphdr *next;
@@ -45025,6 +46401,9 @@ DUK_INTERNAL void duk_heap_free(duk_heap *heap) {
* are on the heap allocated list.
*/
+ DUK_D(DUK_DPRINT("freeing temporary freelists"));
+ duk_heap_free_freelists(heap);
+
DUK_D(DUK_DPRINT("freeing heap_allocated of heap: %p", (void *) heap));
duk__free_allocated(heap);
@@ -45181,8 +46560,8 @@ DUK_LOCAL duk_bool_t duk__init_heap_thread(duk_heap *heap) {
/* XXX: this may now fail, and is not handled correctly */
duk_hthread_create_builtin_objects(thr);
- /* default prototype (Note: 'thr' must be reachable) */
- DUK_HOBJECT_SET_PROTOTYPE_UPDREF(thr, (duk_hobject *) thr, thr->builtins[DUK_BIDX_THREAD_PROTOTYPE]);
+ /* default prototype */
+ DUK_HOBJECT_SET_PROTOTYPE_INIT_INCREF(thr, (duk_hobject *) thr, thr->builtins[DUK_BIDX_THREAD_PROTOTYPE]);
return 1;
}
@@ -45298,6 +46677,7 @@ DUK_LOCAL void duk__dump_type_sizes(void) {
#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)
DUK__DUMPSZ(duk_hbufobj);
#endif
+ DUK__DUMPSZ(duk_hproxy);
DUK__DUMPSZ(duk_hbuffer);
DUK__DUMPSZ(duk_hbuffer_fixed);
DUK__DUMPSZ(duk_hbuffer_dynamic);
@@ -45535,6 +46915,12 @@ duk_heap *duk_heap_alloc(duk_alloc_function alloc_func,
res->currently_finalizing = NULL;
#endif
#endif
+#if defined(DUK_USE_CACHE_ACTIVATION)
+ res->activation_free = NULL;
+#endif
+#if defined(DUK_USE_CACHE_CATCHER)
+ res->catcher_free = NULL;
+#endif
res->heap_thread = NULL;
res->curr_thread = NULL;
res->heap_object = NULL;
@@ -45565,7 +46951,7 @@ duk_heap *duk_heap_alloc(duk_alloc_function alloc_func,
res->dbg_write_flush_cb = NULL;
res->dbg_request_cb = NULL;
res->dbg_udata = NULL;
- res->dbg_step_thread = NULL;
+ res->dbg_pause_act = NULL;
#endif
#endif /* DUK_USE_EXPLICIT_NULL_INIT */
@@ -45727,14 +47113,14 @@ duk_heap *duk_heap_alloc(duk_alloc_function alloc_func,
#if !defined(DUK_USE_GET_RANDOM_DOUBLE)
#if defined(DUK_USE_PREFER_SIZE) || !defined(DUK_USE_64BIT_OPS)
- res->rnd_state = (duk_uint32_t) DUK_USE_DATE_GET_NOW((duk_context *) res->heap_thread);
+ res->rnd_state = (duk_uint32_t) duk_time_get_ecmascript_time(res->heap_thread);
duk_util_tinyrandom_prepare_seed(res->heap_thread);
#else
- res->rnd_state[0] = (duk_uint64_t) DUK_USE_DATE_GET_NOW((duk_context *) res->heap_thread);
+ res->rnd_state[0] = (duk_uint64_t) duk_time_get_ecmascript_time(res->heap_thread);
DUK_ASSERT(res->rnd_state[1] == 0); /* Not filled here, filled in by seed preparation. */
#if 0 /* Manual test values matching misc/xoroshiro128plus_test.c. */
- res->rnd_state[0] = 0xdeadbeef12345678ULL;
- res->rnd_state[1] = 0xcafed00d12345678ULL;
+ res->rnd_state[0] = DUK_U64_CONSTANT(0xdeadbeef12345678);
+ res->rnd_state[1] = DUK_U64_CONSTANT(0xcafed00d12345678);
#endif
duk_util_tinyrandom_prepare_seed(res->heap_thread);
/* Mix in heap pointer: this ensures that if two Duktape heaps are
@@ -45831,21 +47217,19 @@ duk_heap *duk_heap_alloc(duk_alloc_function alloc_func,
*/
#if defined(DUK_USE_FINALIZER_TORTURE)
-DUK_LOCAL duk_ret_t duk__fake_global_finalizer(duk_context *ctx) {
+DUK_LOCAL duk_ret_t duk__fake_global_finalizer(duk_hthread *thr) {
DUK_DD(DUK_DDPRINT("fake global torture finalizer executed"));
/* Require a lot of stack to force a value stack grow/shrink. */
- duk_require_stack(ctx, 100000);
+ duk_require_stack(thr, 100000);
- /* Force a reallocation with pointer change for value, call, and
- * catch stacks to maximize side effects.
+ /* Force a reallocation with pointer change for value stack
+ * to maximize side effects.
*/
- duk_hthread_valstack_torture_realloc((duk_hthread *) ctx);
- duk_hthread_callstack_torture_realloc((duk_hthread *) ctx);
- duk_hthread_catchstack_torture_realloc((duk_hthread *) ctx);
+ duk_hthread_valstack_torture_realloc(thr);
/* Inner function call, error throw. */
- duk_eval_string_noresult(ctx,
+ duk_eval_string_noresult(thr,
"(function dummy() {\n"
" dummy.prototype = null; /* break reference loop */\n"
" try {\n"
@@ -45870,19 +47254,20 @@ DUK_LOCAL duk_ret_t duk__fake_global_finalizer(duk_context *ctx) {
DUK_LOCAL void duk__run_global_torture_finalizer(duk_hthread *thr) {
DUK_ASSERT(thr != NULL);
- /* Avoid fake finalization when callstack limit has been reached.
- * Otherwise a callstack limit error will be created, then refzero'ed.
+ /* Avoid fake finalization when callstack limit is near. Otherwise
+ * a callstack limit error will be created, then refzero'ed. The
+ * +5 headroom is conservative.
*/
- 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("skip global torture finalizer because of call recursion or call stack size limit"));
+ if (thr->heap->call_recursion_depth + 5 >= thr->heap->call_recursion_limit ||
+ thr->callstack_top + 5 >= DUK_USE_CALLSTACK_LIMIT) {
+ DUK_D(DUK_DPRINT("skip global torture finalizer, too little headroom for call recursion or call stack size"));
return;
}
/* Run fake finalizer. Avoid creating unnecessary garbage. */
- duk_push_c_function((duk_context *) thr, duk__fake_global_finalizer, 0 /*nargs*/);
- (void) duk_pcall((duk_context *) thr, 0 /*nargs*/);
- duk_pop((duk_context *) thr);
+ duk_push_c_function(thr, duk__fake_global_finalizer, 0 /*nargs*/);
+ (void) duk_pcall(thr, 0 /*nargs*/);
+ duk_pop(thr);
}
#endif /* DUK_USE_FINALIZER_TORTURE */
@@ -45964,8 +47349,6 @@ DUK_INTERNAL void duk_heap_process_finalize_list(duk_heap *heap) {
DUK_ASSERT(heap != NULL);
DUK_ASSERT(heap->heap_thread != NULL);
DUK_ASSERT(heap->heap_thread->valstack != NULL);
- DUK_ASSERT(heap->heap_thread->callstack != NULL);
- DUK_ASSERT(heap->heap_thread->catchstack != NULL);
#if defined(DUK_USE_REFERENCE_COUNTING)
DUK_ASSERT(heap->refzero_list == NULL);
#endif
@@ -46160,11 +47543,8 @@ DUK_INTERNAL void duk_heap_process_finalize_list(duk_heap *heap) {
* left on the finalizer stack).
*/
-DUK_LOCAL duk_ret_t duk__finalize_helper(duk_context *ctx, void *udata) {
- duk_hthread *thr;
-
- DUK_ASSERT(ctx != NULL);
- thr = (duk_hthread *) ctx;
+DUK_LOCAL duk_ret_t duk__finalize_helper(duk_hthread *thr, void *udata) {
+ DUK_ASSERT(thr != NULL);
DUK_UNREF(udata);
DUK_DDD(DUK_DDDPRINT("protected finalization helper running"));
@@ -46181,11 +47561,11 @@ DUK_LOCAL duk_ret_t duk__finalize_helper(duk_context *ctx, void *udata) {
* caller must ensure that this function is not called if the target is
* a Proxy.
*/
- duk_get_prop_stridx_short(ctx, -1, DUK_STRIDX_INT_FINALIZER); /* -> [... obj finalizer] */
- duk_dup_m2(ctx);
- duk_push_boolean(ctx, DUK_HEAP_HAS_FINALIZER_NORESCUE(thr->heap));
+ duk_get_prop_stridx_short(thr, -1, DUK_STRIDX_INT_FINALIZER); /* -> [... obj finalizer] */
+ duk_dup_m2(thr);
+ duk_push_boolean(thr, DUK_HEAP_HAS_FINALIZER_NORESCUE(thr->heap));
DUK_DDD(DUK_DDDPRINT("calling finalizer"));
- duk_call(ctx, 2); /* [ ... obj finalizer obj heapDestruct ] -> [ ... obj retval ] */
+ duk_call(thr, 2); /* [ ... obj finalizer obj heapDestruct ] -> [ ... obj retval ] */
DUK_DDD(DUK_DDDPRINT("finalizer returned successfully"));
return 0;
@@ -46196,7 +47576,7 @@ DUK_LOCAL duk_ret_t duk__finalize_helper(duk_context *ctx, void *udata) {
}
DUK_INTERNAL void duk_heap_run_finalizer(duk_heap *heap, duk_hobject *obj) {
- duk_context *ctx;
+ duk_hthread *thr;
duk_ret_t rc;
#if defined(DUK_USE_ASSERTIONS)
duk_idx_t entry_top;
@@ -46206,12 +47586,12 @@ DUK_INTERNAL void duk_heap_run_finalizer(duk_heap *heap, duk_hobject *obj) {
DUK_ASSERT(heap != NULL);
DUK_ASSERT(heap->heap_thread != NULL);
- ctx = (duk_context *) heap->heap_thread;
+ thr = heap->heap_thread;
DUK_ASSERT(obj != NULL);
DUK_ASSERT_VALSTACK_SPACE(heap->heap_thread, 1);
#if defined(DUK_USE_ASSERTIONS)
- entry_top = duk_get_top(ctx);
+ entry_top = duk_get_top(thr);
#endif
/*
* Get and call the finalizer. All of this must be wrapped
@@ -46236,30 +47616,32 @@ DUK_INTERNAL void duk_heap_run_finalizer(duk_heap *heap, duk_hobject *obj) {
#endif
DUK_HEAPHDR_SET_FINALIZED((duk_heaphdr *) obj); /* ensure never re-entered until rescue cycle complete */
- if (DUK_HOBJECT_HAS_EXOTIC_PROXYOBJ(obj)) {
+#if defined(DUK_USE_ES6_PROXY)
+ if (DUK_HOBJECT_IS_PROXY(obj)) {
/* This may happen if duk_set_finalizer() or Duktape.fin() is
* called for a Proxy object. In such cases the fast finalizer
* flag will be set on the Proxy, not the target, and neither
* will be finalized.
*/
- DUK_D(DUK_DPRINT("object is a proxy, skip finalizer call"));
+ DUK_D(DUK_DPRINT("object is a Proxy, skip finalizer call"));
return;
}
+#endif /* DUK_USE_ES6_PROXY */
- duk_push_hobject(ctx, obj); /* this also increases refcount by one */
- rc = duk_safe_call(ctx, duk__finalize_helper, NULL /*udata*/, 0 /*nargs*/, 1 /*nrets*/); /* -> [... obj retval/error] */
- DUK_ASSERT_TOP(ctx, entry_top + 2); /* duk_safe_call discipline */
+ duk_push_hobject(thr, obj); /* this also increases refcount by one */
+ rc = duk_safe_call(thr, duk__finalize_helper, NULL /*udata*/, 0 /*nargs*/, 1 /*nrets*/); /* -> [... obj retval/error] */
+ DUK_ASSERT_TOP(thr, entry_top + 2); /* duk_safe_call discipline */
if (rc != DUK_EXEC_SUCCESS) {
/* Note: we ask for one return value from duk_safe_call to get this
* error debugging here.
*/
DUK_D(DUK_DPRINT("wrapped finalizer call failed for object %p (ignored); error: %!T",
- (void *) obj, (duk_tval *) duk_get_tval(ctx, -1)));
+ (void *) obj, (duk_tval *) duk_get_tval(thr, -1)));
}
- duk_pop_2(ctx); /* -> [...] */
+ duk_pop_2(thr); /* -> [...] */
- DUK_ASSERT_TOP(ctx, entry_top);
+ DUK_ASSERT_TOP(thr, entry_top);
}
#else /* DUK_USE_FINALIZER_SUPPORT */
@@ -46395,7 +47777,9 @@ DUK_INTERNAL duk_uint32_t duk_heap_hashstring(duk_heap *heap, const duk_uint8_t
/* #include duk_internal.h -> already included */
DUK_LOCAL_DECL void duk__mark_heaphdr(duk_heap *heap, duk_heaphdr *h);
+DUK_LOCAL_DECL void duk__mark_heaphdr_nonnull(duk_heap *heap, duk_heaphdr *h);
DUK_LOCAL_DECL void duk__mark_tval(duk_heap *heap, duk_tval *tv);
+DUK_LOCAL_DECL void duk__mark_tvals(duk_heap *heap, duk_tval *tv, duk_idx_t count);
/*
* Marking functions for heap types: mark children recursively.
@@ -46425,7 +47809,7 @@ DUK_LOCAL void duk__mark_hobject(duk_heap *heap, duk_hobject *h) {
if (key == NULL) {
continue;
}
- duk__mark_heaphdr(heap, (duk_heaphdr *) key);
+ duk__mark_heaphdr_nonnull(heap, (duk_heaphdr *) key);
if (DUK_HOBJECT_E_SLOT_IS_ACCESSOR(heap, h, i)) {
duk__mark_heaphdr(heap, (duk_heaphdr *) DUK_HOBJECT_E_GET_VALUE_PTR(heap, h, i)->a.get);
duk__mark_heaphdr(heap, (duk_heaphdr *) DUK_HOBJECT_E_GET_VALUE_PTR(heap, h, i)->a.set);
@@ -46451,11 +47835,14 @@ DUK_LOCAL void duk__mark_hobject(duk_heap *heap, duk_hobject *h) {
}
DUK_ASSERT(DUK_HOBJECT_PROHIBITS_FASTREFS(h));
+ /* XXX: reorg, more common first */
if (DUK_HOBJECT_IS_COMPFUNC(h)) {
duk_hcompfunc *f = (duk_hcompfunc *) h;
duk_tval *tv, *tv_end;
duk_hobject **fn, **fn_end;
+ DUK_ASSERT_HCOMPFUNC_VALID(f);
+
/* 'data' is reachable through every compiled function which
* contains a reference.
*/
@@ -46475,19 +47862,13 @@ DUK_LOCAL void duk__mark_hobject(duk_heap *heap, duk_hobject *h) {
fn = DUK_HCOMPFUNC_GET_FUNCS_BASE(heap, f);
fn_end = DUK_HCOMPFUNC_GET_FUNCS_END(heap, f);
while (fn < fn_end) {
- duk__mark_heaphdr(heap, (duk_heaphdr *) *fn);
+ duk__mark_heaphdr_nonnull(heap, (duk_heaphdr *) *fn);
fn++;
}
} else {
/* May happen in some out-of-memory corner cases. */
DUK_D(DUK_DPRINT("duk_hcompfunc 'data' is NULL, skipping marking"));
}
-#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)
- } else if (DUK_HOBJECT_IS_BUFOBJ(h)) {
- duk_hbufobj *b = (duk_hbufobj *) h;
- duk__mark_heaphdr(heap, (duk_heaphdr *) b->buf);
- duk__mark_heaphdr(heap, (duk_heaphdr *) b->buf_prop);
-#endif /* DUK_USE_BUFFEROBJECT_SUPPORT */
} else if (DUK_HOBJECT_IS_DECENV(h)) {
duk_hdecenv *e = (duk_hdecenv *) h;
DUK_ASSERT_HDECENV_VALID(e);
@@ -46496,32 +47877,52 @@ DUK_LOCAL void duk__mark_hobject(duk_heap *heap, duk_hobject *h) {
} else if (DUK_HOBJECT_IS_OBJENV(h)) {
duk_hobjenv *e = (duk_hobjenv *) h;
DUK_ASSERT_HOBJENV_VALID(e);
- duk__mark_heaphdr(heap, (duk_heaphdr *) e->target);
+ duk__mark_heaphdr_nonnull(heap, (duk_heaphdr *) e->target);
+#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)
+ } else if (DUK_HOBJECT_IS_BUFOBJ(h)) {
+ duk_hbufobj *b = (duk_hbufobj *) h;
+ DUK_ASSERT_HBUFOBJ_VALID(b);
+ duk__mark_heaphdr(heap, (duk_heaphdr *) b->buf);
+ duk__mark_heaphdr(heap, (duk_heaphdr *) b->buf_prop);
+#endif /* DUK_USE_BUFFEROBJECT_SUPPORT */
+ } else if (DUK_HOBJECT_IS_BOUNDFUNC(h)) {
+ duk_hboundfunc *f = (duk_hboundfunc *) h;
+ DUK_ASSERT_HBOUNDFUNC_VALID(f);
+ duk__mark_tval(heap, &f->target);
+ duk__mark_tval(heap, &f->this_binding);
+ duk__mark_tvals(heap, f->args, f->nargs);
+#if defined(DUK_USE_ES6_PROXY)
+ } else if (DUK_HOBJECT_IS_PROXY(h)) {
+ duk_hproxy *p = (duk_hproxy *) h;
+ DUK_ASSERT_HPROXY_VALID(p);
+ duk__mark_heaphdr_nonnull(heap, (duk_heaphdr *) p->target);
+ duk__mark_heaphdr_nonnull(heap, (duk_heaphdr *) p->handler);
+#endif /* DUK_USE_ES6_PROXY */
} else if (DUK_HOBJECT_IS_THREAD(h)) {
duk_hthread *t = (duk_hthread *) h;
+ duk_activation *act;
duk_tval *tv;
+ DUK_ASSERT_HTHREAD_VALID(t);
+
tv = t->valstack;
while (tv < t->valstack_top) {
duk__mark_tval(heap, tv);
tv++;
}
- for (i = 0; i < (duk_uint_fast32_t) t->callstack_top; i++) {
- duk_activation *act = t->callstack + i;
+ for (act = t->callstack_curr; act != NULL; act = act->parent) {
duk__mark_heaphdr(heap, (duk_heaphdr *) DUK_ACT_GET_FUNC(act));
duk__mark_heaphdr(heap, (duk_heaphdr *) act->var_env);
duk__mark_heaphdr(heap, (duk_heaphdr *) act->lex_env);
#if defined(DUK_USE_NONSTD_FUNC_CALLER_PROPERTY)
duk__mark_heaphdr(heap, (duk_heaphdr *) act->prev_caller);
#endif
- }
-
#if 0 /* nothing now */
- for (i = 0; i < (duk_uint_fast32_t) t->catchstack_top; i++) {
- duk_catcher *cat = t->catchstack + i;
- }
+ for (cat = act->cat; cat != NULL; cat = cat->parent) {
+ }
#endif
+ }
duk__mark_heaphdr(heap, (duk_heaphdr *) t->resumer);
@@ -46543,22 +47944,30 @@ DUK_LOCAL void duk__mark_heaphdr(duk_heap *heap, duk_heaphdr *h) {
DUK_DDD(DUK_DDDPRINT("duk__mark_heaphdr %p, type %ld",
(void *) h,
(h != NULL ? (long) DUK_HEAPHDR_GET_TYPE(h) : (long) -1)));
+
+ /* XXX: add non-null variant? */
if (h == NULL) {
return;
}
-#if defined(DUK_USE_ROM_OBJECTS)
- if (DUK_HEAPHDR_HAS_READONLY(h)) {
- DUK_DDD(DUK_DDDPRINT("readonly object %p, skip", (void *) h));
- return;
- }
-#endif
+
+ DUK_ASSERT(!DUK_HEAPHDR_HAS_READONLY(h) || DUK_HEAPHDR_HAS_REACHABLE(h));
+
#if defined(DUK_USE_ASSERTIONS) && defined(DUK_USE_REFERENCE_COUNTING)
- h->h_assert_refcount++; /* Comparison refcount: bump even if already reachable. */
+ if (!DUK_HEAPHDR_HAS_READONLY(h)) {
+ h->h_assert_refcount++; /* Comparison refcount: bump even if already reachable. */
+ }
#endif
if (DUK_HEAPHDR_HAS_REACHABLE(h)) {
DUK_DDD(DUK_DDDPRINT("already marked reachable, skip"));
return;
}
+#if defined(DUK_USE_ROM_OBJECTS)
+ /* READONLY objects always have REACHABLE set, so the check above
+ * will prevent READONLY objects from being marked here.
+ */
+ DUK_ASSERT(!DUK_HEAPHDR_HAS_READONLY(h));
+#endif
+
DUK_HEAPHDR_SET_REACHABLE(h);
if (heap->ms_recursion_depth >= DUK_USE_MARK_AND_SWEEP_RECLIMIT) {
@@ -46596,10 +48005,35 @@ DUK_LOCAL void duk__mark_tval(duk_heap *heap, duk_tval *tv) {
return;
}
if (DUK_TVAL_IS_HEAP_ALLOCATED(tv)) {
- duk__mark_heaphdr(heap, DUK_TVAL_GET_HEAPHDR(tv));
+ duk_heaphdr *h;
+ h = DUK_TVAL_GET_HEAPHDR(tv);
+ DUK_ASSERT(h != NULL);
+ duk__mark_heaphdr_nonnull(heap, h);
+ }
+}
+
+DUK_LOCAL void duk__mark_tvals(duk_heap *heap, duk_tval *tv, duk_idx_t count) {
+ DUK_ASSERT(count == 0 || tv != NULL);
+
+ while (count-- > 0) {
+ if (DUK_TVAL_IS_HEAP_ALLOCATED(tv)) {
+ duk_heaphdr *h;
+ h = DUK_TVAL_GET_HEAPHDR(tv);
+ DUK_ASSERT(h != NULL);
+ duk__mark_heaphdr_nonnull(heap, h);
+ }
+ tv++;
}
}
+/* Mark any duk_heaphdr type, caller guarantees a non-NULL pointer. */
+DUK_LOCAL void duk__mark_heaphdr_nonnull(duk_heap *heap, duk_heaphdr *h) {
+ /* For now, just call the generic handler. Change when call sites
+ * are changed too.
+ */
+ duk__mark_heaphdr(heap, h);
+}
+
/*
* Mark the heap.
*/
@@ -46690,7 +48124,7 @@ DUK_LOCAL void duk__mark_finalizable(duk_heap *heap) {
hdr = heap->heap_allocated;
while (hdr != NULL) {
if (DUK_HEAPHDR_HAS_FINALIZABLE(hdr)) {
- duk__mark_heaphdr(heap, hdr);
+ duk__mark_heaphdr_nonnull(heap, hdr);
}
hdr = DUK_HEAPHDR_GET_NEXT(heap, hdr);
@@ -46715,7 +48149,7 @@ DUK_LOCAL void duk__mark_finalize_list(duk_heap *heap) {
hdr = heap->finalize_list;
while (hdr != NULL) {
- duk__mark_heaphdr(heap, hdr);
+ duk__mark_heaphdr_nonnull(heap, hdr);
hdr = DUK_HEAPHDR_GET_NEXT(heap, hdr);
#if defined(DUK_USE_DEBUG)
count_finalize_list++;
@@ -46753,6 +48187,8 @@ DUK_LOCAL void duk__handle_temproot(duk_heap *heap, duk_heaphdr *hdr, duk_size_t
#else
DUK_LOCAL void duk__handle_temproot(duk_heap *heap, duk_heaphdr *hdr) {
#endif
+ DUK_ASSERT(hdr != NULL);
+
if (!DUK_HEAPHDR_HAS_TEMPROOT(hdr)) {
DUK_DDD(DUK_DDDPRINT("not a temp root: %p", (void *) hdr));
return;
@@ -46764,7 +48200,7 @@ DUK_LOCAL void duk__handle_temproot(duk_heap *heap, duk_heaphdr *hdr) {
#if defined(DUK_USE_ASSERTIONS) && defined(DUK_USE_REFERENCE_COUNTING)
hdr->h_assert_refcount--; /* Same node visited twice. */
#endif
- duk__mark_heaphdr(heap, hdr);
+ duk__mark_heaphdr_nonnull(heap, hdr);
#if defined(DUK_USE_DEBUG)
(*count)++;
@@ -46972,7 +48408,7 @@ DUK_LOCAL void duk__sweep_stringtable(duk_heap *heap, duk_size_t *out_count_keep
* Sweep heap.
*/
-DUK_LOCAL void duk__sweep_heap(duk_heap *heap, duk_int_t flags, duk_size_t *out_count_keep) {
+DUK_LOCAL void duk__sweep_heap(duk_heap *heap, duk_small_uint_t flags, duk_size_t *out_count_keep) {
duk_heaphdr *prev; /* last element that was left in the heap */
duk_heaphdr *curr;
duk_heaphdr *next;
@@ -46983,7 +48419,6 @@ DUK_LOCAL void duk__sweep_heap(duk_heap *heap, duk_int_t flags, duk_size_t *out_
#endif
duk_size_t count_keep = 0;
- DUK_UNREF(flags);
DUK_DD(DUK_DDPRINT("duk__sweep_heap: %p", (void *) heap));
prev = NULL;
@@ -47063,6 +48498,18 @@ DUK_LOCAL void duk__sweep_heap(duk_heap *heap, duk_int_t flags, duk_size_t *out_
prev = curr;
}
+ /*
+ * Shrink check for value stacks here. We're inside
+ * ms_prevent_count protection which prevents recursive
+ * mark-and-sweep and refzero finalizers, so there are
+ * no side effects that would affect the heap lists.
+ */
+ if (DUK_HEAPHDR_IS_OBJECT(curr) && DUK_HOBJECT_IS_THREAD((duk_hobject *) curr)) {
+ duk_hthread *thr_curr = (duk_hthread *) curr;
+ DUK_DD(DUK_DDPRINT("value stack shrink check for thread: %!O", curr));
+ duk_valstack_shrink_check_nothrow(thr_curr, flags & DUK_MS_FLAG_EMERGENCY /*snug*/);
+ }
+
DUK_HEAPHDR_CLEAR_REACHABLE(curr);
/* Keep FINALIZED if set, used if rescue decisions are postponed. */
/* Keep FINALIZABLE for objects on finalize_list. */
@@ -47137,13 +48584,13 @@ DUK_LOCAL void duk__sweep_heap(duk_heap *heap, duk_int_t flags, duk_size_t *out_
* Compaction is assumed to never throw an error.
*/
-DUK_LOCAL int duk__protected_compact_object(duk_context *ctx, void *udata) {
+DUK_LOCAL int duk__protected_compact_object(duk_hthread *thr, void *udata) {
duk_hobject *obj;
- /* XXX: for threads, compact value stack, call stack, catch stack? */
+ /* XXX: for threads, compact stacks? */
DUK_UNREF(udata);
- obj = duk_known_hobject(ctx, -1);
- duk_hobject_compact_props((duk_hthread *) ctx, obj);
+ obj = duk_known_hobject(thr, -1);
+ duk_hobject_compact_props(thr, obj);
return 0;
}
@@ -47176,9 +48623,9 @@ DUK_LOCAL void duk__compact_object_list(duk_heap *heap, duk_hthread *thr, duk_he
#endif
DUK_DD(DUK_DDPRINT("compact object: %p", (void *) obj));
- duk_push_hobject((duk_context *) thr, obj);
+ duk_push_hobject(thr, obj);
/* XXX: disable error handlers for duration of compaction? */
- duk_safe_call((duk_context *) thr, duk__protected_compact_object, NULL, 1, 0);
+ duk_safe_call(thr, duk__protected_compact_object, NULL, 1, 0);
#if defined(DUK_USE_DEBUG)
new_size = DUK_HOBJECT_P_COMPUTE_SIZE(DUK_HOBJECT_GET_ESIZE(obj),
@@ -47371,6 +48818,56 @@ DUK_LOCAL void duk__check_assert_refcounts(duk_heap *heap) {
#endif /* DUK_USE_ASSERTIONS */
/*
+ * Stats dump.
+ */
+
+#if defined(DUK_USE_DEBUG)
+DUK_LOCAL void duk__dump_stats(duk_heap *heap) {
+ DUK_D(DUK_DPRINT("stats executor: opcodes=%ld, interrupt=%ld, throw=%ld",
+ (long) heap->stats_exec_opcodes, (long) heap->stats_exec_interrupt,
+ (long) heap->stats_exec_throw));
+ DUK_D(DUK_DPRINT("stats call: all=%ld, tailcall=%ld, ecmatoecma=%ld",
+ (long) heap->stats_call_all, (long) heap->stats_call_tailcall,
+ (long) heap->stats_call_ecmatoecma));
+ DUK_D(DUK_DPRINT("stats safecall: all=%ld, nothrow=%ld, throw=%ld",
+ (long) heap->stats_safecall_all, (long) heap->stats_safecall_nothrow,
+ (long) heap->stats_safecall_throw));
+ DUK_D(DUK_DPRINT("stats mark-and-sweep: try_count=%ld, skip_count=%ld, emergency_count=%ld",
+ (long) heap->stats_ms_try_count, (long) heap->stats_ms_skip_count,
+ (long) heap->stats_ms_emergency_count));
+ DUK_D(DUK_DPRINT("stats stringtable: intern_hit=%ld, intern_miss=%ld, resize_check=%ld, resize_grow=%ld, resize_shrink=%ld",
+ (long) heap->stats_strtab_intern_hit, (long) heap->stats_strtab_intern_miss,
+ (long) heap->stats_strtab_resize_check, (long) heap->stats_strtab_resize_grow,
+ (long) heap->stats_strtab_resize_shrink));
+ DUK_D(DUK_DPRINT("stats object: realloc_props=%ld, abandon_array=%ld",
+ (long) heap->stats_object_realloc_props, (long) heap->stats_object_abandon_array));
+ DUK_D(DUK_DPRINT("stats getownpropdesc: count=%ld, hit=%ld, miss=%ld",
+ (long) heap->stats_getownpropdesc_count, (long) heap->stats_getownpropdesc_hit,
+ (long) heap->stats_getownpropdesc_miss));
+ DUK_D(DUK_DPRINT("stats getpropdesc: count=%ld, hit=%ld, miss=%ld",
+ (long) heap->stats_getpropdesc_count, (long) heap->stats_getpropdesc_hit,
+ (long) heap->stats_getpropdesc_miss));
+ DUK_D(DUK_DPRINT("stats getprop: all=%ld, arrayidx=%ld, bufobjidx=%ld, "
+ "bufferidx=%ld, bufferlen=%ld, stringidx=%ld, stringlen=%ld, "
+ "proxy=%ld, arguments=%ld",
+ (long) heap->stats_getprop_all, (long) heap->stats_getprop_arrayidx,
+ (long) heap->stats_getprop_bufobjidx, (long) heap->stats_getprop_bufferidx,
+ (long) heap->stats_getprop_bufferlen, (long) heap->stats_getprop_stringidx,
+ (long) heap->stats_getprop_stringlen, (long) heap->stats_getprop_proxy,
+ (long) heap->stats_getprop_arguments));
+ DUK_D(DUK_DPRINT("stats putprop: all=%ld, arrayidx=%ld, bufobjidx=%ld, "
+ "bufferidx=%ld, proxy=%ld",
+ (long) heap->stats_putprop_all, (long) heap->stats_putprop_arrayidx,
+ (long) heap->stats_putprop_bufobjidx, (long) heap->stats_putprop_bufferidx,
+ (long) heap->stats_putprop_proxy));
+ DUK_D(DUK_DPRINT("stats getvar: all=%ld",
+ (long) heap->stats_getvar_all));
+ DUK_D(DUK_DPRINT("stats putvar: all=%ld",
+ (long) heap->stats_putvar_all));
+}
+#endif /* DUK_USE_DEBUG */
+
+/*
* Main mark-and-sweep function.
*
* 'flags' represents the features requested by the caller. The current
@@ -47385,6 +48882,13 @@ DUK_INTERNAL void duk_heap_mark_and_sweep(duk_heap *heap, duk_small_uint_t flags
duk_size_t tmp;
#endif
+ DUK_STATS_INC(heap, stats_ms_try_count);
+#if defined(DUK_USE_DEBUG)
+ if (flags & DUK_MS_FLAG_EMERGENCY) {
+ DUK_STATS_INC(heap, stats_ms_emergency_count);
+ }
+#endif
+
/* If debugger is paused, garbage collection is disabled by default.
* This is achieved by bumping ms_prevent_count when becoming paused.
*/
@@ -47396,6 +48900,7 @@ DUK_INTERNAL void duk_heap_mark_and_sweep(duk_heap *heap, duk_small_uint_t flags
*/
if (heap->ms_prevent_count != 0) {
DUK_DD(DUK_DDPRINT("reject recursive mark-and-sweep"));
+ DUK_STATS_INC(heap, stats_ms_skip_count);
return;
}
DUK_ASSERT(heap->ms_running == 0); /* ms_prevent_count is bumped when ms_running is set */
@@ -47407,8 +48912,6 @@ DUK_INTERNAL void duk_heap_mark_and_sweep(duk_heap *heap, duk_small_uint_t flags
*/
DUK_ASSERT(heap->heap_thread != NULL);
DUK_ASSERT(heap->heap_thread->valstack != NULL);
- DUK_ASSERT(heap->heap_thread->callstack != NULL);
- DUK_ASSERT(heap->heap_thread->catchstack != NULL);
DUK_D(DUK_DPRINT("garbage collect (mark-and-sweep) starting, requested flags: 0x%08lx, effective flags: 0x%08lx",
(unsigned long) flags, (unsigned long) (flags | heap->ms_base_flags)));
@@ -47449,6 +48952,15 @@ DUK_INTERNAL void duk_heap_mark_and_sweep(duk_heap *heap, duk_small_uint_t flags
heap->ms_running = 1;
/*
+ * Free activation/catcher freelists on every mark-and-sweep for now.
+ * This is an initial rough draft; ideally we'd keep count of the
+ * freelist size and free only excess entries.
+ */
+
+ DUK_D(DUK_DPRINT("freeing temporary freelists"));
+ duk_heap_free_freelists(heap);
+
+ /*
* Mark roots, hoping that recursion limit is not normally hit.
* If recursion limit is hit, run additional reachability rounds
* starting from "temproots" until marking is complete.
@@ -47591,6 +49103,14 @@ DUK_INTERNAL void duk_heap_mark_and_sweep(duk_heap *heap, duk_small_uint_t flags
#endif
/*
+ * Stats dump
+ */
+
+#if defined(DUK_USE_DEBUG)
+ duk__dump_stats(heap);
+#endif
+
+ /*
* Finalize objects in the finalization work list. Finalized
* objects are queued back to heap_allocated with FINALIZED set.
*
@@ -47679,7 +49199,9 @@ DUK_INTERNAL void *duk_heap_mem_alloc(duk_heap *heap, duk_size_t size) {
*/
#if defined(DUK_USE_GC_TORTURE)
- /* simulate alloc failure on every alloc (except when mark-and-sweep is running) */
+ /* Simulate alloc failure on every alloc, except when mark-and-sweep
+ * is running.
+ */
if (heap->ms_prevent_count == 0) {
DUK_DDD(DUK_DDDPRINT("gc torture enabled, pretend that first alloc attempt fails"));
res = NULL;
@@ -47689,7 +49211,7 @@ DUK_INTERNAL void *duk_heap_mem_alloc(duk_heap *heap, duk_size_t size) {
#endif
res = heap->alloc_func(heap->heap_udata, size);
if (DUK_LIKELY(res || size == 0)) {
- /* for zero size allocations NULL is allowed */
+ /* For zero size allocations NULL is allowed. */
return res;
}
#if defined(DUK_USE_GC_TORTURE)
@@ -47804,7 +49326,9 @@ DUK_INTERNAL void *duk_heap_mem_realloc(duk_heap *heap, void *ptr, duk_size_t ne
*/
#if defined(DUK_USE_GC_TORTURE)
- /* simulate alloc failure on every realloc (except when mark-and-sweep is running) */
+ /* Simulate alloc failure on every realloc, except when mark-and-sweep
+ * is running.
+ */
if (heap->ms_prevent_count == 0) {
DUK_DDD(DUK_DDDPRINT("gc torture enabled, pretend that first realloc attempt fails"));
res = NULL;
@@ -47814,7 +49338,7 @@ DUK_INTERNAL void *duk_heap_mem_realloc(duk_heap *heap, void *ptr, duk_size_t ne
#endif
res = heap->realloc_func(heap->heap_udata, ptr, newsize);
if (DUK_LIKELY(res || newsize == 0)) {
- /* for zero size allocations NULL is allowed */
+ /* For zero size allocations NULL is allowed. */
return res;
}
#if defined(DUK_USE_GC_TORTURE)
@@ -47886,7 +49410,9 @@ DUK_INTERNAL void *duk_heap_mem_realloc_indirect(duk_heap *heap, duk_mem_getptr
*/
#if defined(DUK_USE_GC_TORTURE)
- /* simulate alloc failure on every realloc (except when mark-and-sweep is running) */
+ /* Simulate alloc failure on every realloc, except when mark-and-sweep
+ * is running.
+ */
if (heap->ms_prevent_count == 0) {
DUK_DDD(DUK_DDDPRINT("gc torture enabled, pretend that first indirect realloc attempt fails"));
res = NULL;
@@ -47896,7 +49422,7 @@ DUK_INTERNAL void *duk_heap_mem_realloc_indirect(duk_heap *heap, duk_mem_getptr
#endif
res = heap->realloc_func(heap->heap_udata, cb(heap, ud), newsize);
if (DUK_LIKELY(res || newsize == 0)) {
- /* for zero size allocations NULL is allowed */
+ /* For zero size allocations NULL is allowed. */
return res;
}
#if defined(DUK_USE_GC_TORTURE)
@@ -47925,12 +49451,12 @@ DUK_INTERNAL void *duk_heap_mem_realloc_indirect(duk_heap *heap, duk_mem_getptr
for (i = 0; i < DUK_HEAP_ALLOC_FAIL_MARKANDSWEEP_LIMIT; i++) {
duk_small_uint_t flags;
-#if defined(DUK_USE_ASSERTIONS)
- void *ptr_pre; /* ptr before mark-and-sweep */
+#if defined(DUK_USE_DEBUG)
+ void *ptr_pre;
void *ptr_post;
#endif
-#if defined(DUK_USE_ASSERTIONS)
+#if defined(DUK_USE_DEBUG)
ptr_pre = cb(heap, ud);
#endif
flags = 0;
@@ -47939,11 +49465,10 @@ DUK_INTERNAL void *duk_heap_mem_realloc_indirect(duk_heap *heap, duk_mem_getptr
}
duk_heap_mark_and_sweep(heap, flags);
-#if defined(DUK_USE_ASSERTIONS)
+#if defined(DUK_USE_DEBUG)
ptr_post = cb(heap, ud);
if (ptr_pre != ptr_post) {
- /* useful for debugging */
- DUK_DD(DUK_DDPRINT("note: base pointer changed by mark-and-sweep: %p -> %p",
+ DUK_DD(DUK_DDPRINT("realloc base pointer changed by mark-and-sweep: %p -> %p",
(void *) ptr_pre, (void *) ptr_post));
}
#endif
@@ -48200,6 +49725,15 @@ DUK_INTERNAL void duk_heap_switch_thread(duk_heap *heap, duk_hthread *new_thr) {
* actual references.
*/
+DUK_LOCAL void duk__decref_tvals_norz(duk_hthread *thr, duk_tval *tv, duk_idx_t count) {
+ DUK_ASSERT(count == 0 || tv != NULL);
+
+ while (count-- > 0) {
+ DUK_TVAL_DECREF_NORZ(thr, tv);
+ tv++;
+ }
+}
+
DUK_INTERNAL void duk_hobject_refcount_finalize_norz(duk_heap *heap, duk_hobject *h) {
duk_hthread *thr;
duk_uint_fast32_t i;
@@ -48277,11 +49811,14 @@ DUK_INTERNAL void duk_hobject_refcount_finalize_norz(duk_heap *heap, duk_hobject
/* Slow path: special object, start bit checks from most likely. */
+ /* XXX: reorg, more common first */
if (DUK_HOBJECT_IS_COMPFUNC(h)) {
duk_hcompfunc *f = (duk_hcompfunc *) h;
duk_tval *tv, *tv_end;
duk_hobject **funcs, **funcs_end;
+ DUK_ASSERT_HCOMPFUNC_VALID(f);
+
if (DUK_LIKELY(DUK_HCOMPFUNC_GET_DATA(heap, f) != NULL)) {
tv = DUK_HCOMPFUNC_GET_CONSTS_BASE(heap, f);
tv_end = DUK_HCOMPFUNC_GET_CONSTS_END(heap, f);
@@ -48321,34 +49858,49 @@ DUK_INTERNAL void duk_hobject_refcount_finalize_norz(duk_heap *heap, duk_hobject
#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)
} else if (DUK_HOBJECT_IS_BUFOBJ(h)) {
duk_hbufobj *b = (duk_hbufobj *) h;
+ DUK_ASSERT_HBUFOBJ_VALID(b);
DUK_HBUFFER_DECREF_NORZ_ALLOWNULL(thr, (duk_hbuffer *) b->buf);
DUK_HOBJECT_DECREF_NORZ_ALLOWNULL(thr, (duk_hobject *) b->buf_prop);
#endif /* DUK_USE_BUFFEROBJECT_SUPPORT */
+ } else if (DUK_HOBJECT_IS_BOUNDFUNC(h)) {
+ duk_hboundfunc *f = (duk_hboundfunc *) h;
+ DUK_ASSERT_HBOUNDFUNC_VALID(f);
+ DUK_TVAL_DECREF_NORZ(thr, &f->target);
+ DUK_TVAL_DECREF_NORZ(thr, &f->this_binding);
+ duk__decref_tvals_norz(thr, f->args, f->nargs);
+#if defined(DUK_USE_ES6_PROXY)
+ } else if (DUK_HOBJECT_IS_PROXY(h)) {
+ duk_hproxy *p = (duk_hproxy *) h;
+ DUK_ASSERT_HPROXY_VALID(p);
+ DUK_HOBJECT_DECREF_NORZ(thr, p->target);
+ DUK_HOBJECT_DECREF_NORZ(thr, p->handler);
+#endif /* DUK_USE_ES6_PROXY */
} else if (DUK_HOBJECT_IS_THREAD(h)) {
duk_hthread *t = (duk_hthread *) h;
+ duk_activation *act;
duk_tval *tv;
+ DUK_ASSERT_HTHREAD_VALID(t);
+
tv = t->valstack;
while (tv < t->valstack_top) {
DUK_TVAL_DECREF_NORZ(thr, tv);
tv++;
}
- for (i = 0; i < (duk_uint_fast32_t) t->callstack_top; i++) {
- duk_activation *act = t->callstack + i;
+ for (act = t->callstack_curr; act != NULL; act = act->parent) {
DUK_HOBJECT_DECREF_NORZ_ALLOWNULL(thr, (duk_hobject *) DUK_ACT_GET_FUNC(act));
DUK_HOBJECT_DECREF_NORZ_ALLOWNULL(thr, (duk_hobject *) act->var_env);
DUK_HOBJECT_DECREF_NORZ_ALLOWNULL(thr, (duk_hobject *) act->lex_env);
#if defined(DUK_USE_NONSTD_FUNC_CALLER_PROPERTY)
DUK_HOBJECT_DECREF_NORZ_ALLOWNULL(thr, (duk_hobject *) act->prev_caller);
#endif
- }
-
#if 0 /* nothing now */
- for (i = 0; i < (duk_uint_fast32_t) t->catchstack_top; i++) {
- duk_catcher *cat = t->catchstack + i;
- }
+ for (cat = act->cat; cat != NULL; cat = cat->parent) {
+ }
#endif
+ }
+
for (i = 0; i < DUK_NUM_BUILTINS; i++) {
DUK_HOBJECT_DECREF_NORZ_ALLOWNULL(thr, (duk_hobject *) t->builtins[i]);
@@ -48496,7 +50048,7 @@ DUK_LOCAL DUK_INLINE void duk__refcount_refzero_hobject(duk_heap *heap, duk_hobj
/* This finalizer check MUST BE side effect free. It should also be
* as fast as possible because it's applied to every object freed.
*/
- if (DUK_UNLIKELY(DUK_HOBJECT_HAS_FINALIZER_FAST(heap, (duk_hobject *) hdr))) {
+ if (DUK_UNLIKELY(DUK_HOBJECT_HAS_FINALIZER_FAST(heap, (duk_hobject *) hdr) != 0U)) {
/* Special case: FINALIZED may be set if mark-and-sweep queued
* object for finalization, the finalizer was executed (and
* FINALIZED set), mark-and-sweep hasn't yet processed the
@@ -49513,11 +51065,10 @@ DUK_LOCAL duk_hstring *duk__strtable_alloc_hstring(duk_heap *heap,
* checks will be false.
*/
if (DUK_UNLIKELY(data[0] >= 0x80U)) {
- if (data[0] == 0xffU) {
+ if (data[0] <= 0x81) {
DUK_HSTRING_SET_SYMBOL(res);
+ } else if (data[0] == 0x82U || data[0] == 0xffU) {
DUK_HSTRING_SET_HIDDEN(res);
- } else if (data[0] <= 0xbf) {
- /* Check equivalent to: (data[0] & 0xc0U) == 0x80U. */
DUK_HSTRING_SET_SYMBOL(res);
}
}
@@ -49529,6 +51080,12 @@ DUK_LOCAL duk_hstring *duk__strtable_alloc_hstring(duk_heap *heap,
* The flag is set lazily for RAM strings.
*/
DUK_ASSERT(!DUK_HSTRING_HAS_ASCII(res));
+
+#if defined(DUK_USE_HSTRING_LAZY_CLEN)
+ /* Charlen initialized to 0, updated on-the-fly. */
+#else
+ duk_hstring_init_charlen(res); /* Also sets ASCII flag. */
+#endif
}
DUK_DDD(DUK_DDDPRINT("interned string, hash=0x%08lx, blen=%ld, has_arridx=%ld, has_extdata=%ld",
@@ -49572,6 +51129,8 @@ DUK_LOCAL void duk__strtable_grow_inplace(duk_heap *heap) {
DUK_ASSERT((heap->st_size & (heap->st_size - 1)) == 0); /* 2^N */
DUK_ASSERT(DUK__GET_STRTABLE(heap) != NULL);
+ DUK_STATS_INC(heap, stats_strtab_resize_grow);
+
new_st_size = heap->st_size << 1U;
DUK_ASSERT(new_st_size > heap->st_size); /* No overflow. */
@@ -49688,6 +51247,8 @@ DUK_LOCAL void duk__strtable_shrink_inplace(duk_heap *heap) {
DUK_ASSERT((heap->st_size & (heap->st_size - 1)) == 0); /* 2^N */
DUK_ASSERT(DUK__GET_STRTABLE(heap) != NULL);
+ DUK_STATS_INC(heap, stats_strtab_resize_shrink);
+
new_st_size = heap->st_size >> 1U;
/* Combine two buckets into a single one. When we shrink, one hash
@@ -49758,8 +51319,10 @@ DUK_LOCAL DUK_COLD DUK_NOINLINE void duk__strtable_resize_check(duk_heap *heap)
DUK_ASSERT(heap->strtable != NULL);
#endif
+ DUK_STATS_INC(heap, stats_strtab_resize_check);
+
/* Prevent recursive resizing. */
- if (DUK_UNLIKELY(heap->st_resizing)) {
+ if (DUK_UNLIKELY(heap->st_resizing != 0U)) {
DUK_D(DUK_DPRINT("prevent recursive strtable resize"));
return;
}
@@ -50011,6 +51574,7 @@ DUK_INTERNAL duk_hstring *duk_heap_strtable_intern(duk_heap *heap, const duk_uin
DUK_HSTRING_GET_BYTELEN(h) == blen &&
DUK_MEMCMP((const void *) str, (const void *) DUK_HSTRING_GET_DATA(h), (size_t) blen) == 0) {
/* Found existing entry. */
+ DUK_STATS_INC(heap, stats_strtab_intern_hit);
return h;
}
h = h->hdr.h_next;
@@ -50024,12 +51588,14 @@ DUK_INTERNAL duk_hstring *duk_heap_strtable_intern(duk_heap *heap, const duk_uin
#if defined(DUK_USE_ROM_STRINGS)
h = duk__strtab_romstring_lookup(heap, str, blen, strhash);
if (h != NULL) {
+ DUK_STATS_INC(heap, stats_strtab_intern_hit);
return h;
}
#endif
/* Not found in string table; insert. */
+ DUK_STATS_INC(heap, stats_strtab_intern_miss);
h = duk__strtable_do_intern(heap, str, blen, strhash);
return h; /* may be NULL */
}
@@ -50043,8 +51609,8 @@ DUK_INTERNAL duk_hstring *duk_heap_strtable_intern(duk_heap *heap, const duk_uin
*/
DUK_INTERNAL duk_hstring *duk_heap_strtable_intern_u32(duk_heap *heap, duk_uint32_t val) {
- char buf[DUK__STRTAB_U32_MAX_STRLEN];
- char *p;
+ duk_uint8_t buf[DUK__STRTAB_U32_MAX_STRLEN];
+ duk_uint8_t *p;
DUK_ASSERT(heap != NULL);
@@ -50339,6 +51905,7 @@ DUK_INTERNAL duk_hobject *duk_hobject_alloc_unchecked(duk_heap *heap, duk_uint_t
/* different memory layout, alloc size, and init */
DUK_ASSERT((hobject_flags & DUK_HOBJECT_FLAG_COMPFUNC) == 0);
DUK_ASSERT((hobject_flags & DUK_HOBJECT_FLAG_NATFUNC) == 0);
+ DUK_ASSERT((hobject_flags & DUK_HOBJECT_FLAG_BOUNDFUNC) == 0);
res = (duk_hobject *) DUK_ALLOC_ZEROED(heap, sizeof(duk_hobject));
if (DUK_UNLIKELY(res == NULL)) {
@@ -50389,6 +51956,27 @@ DUK_INTERNAL duk_hnatfunc *duk_hnatfunc_alloc(duk_hthread *thr, duk_uint_t hobje
return res;
}
+DUK_INTERNAL duk_hboundfunc *duk_hboundfunc_alloc(duk_heap *heap, duk_uint_t hobject_flags) {
+ duk_hboundfunc *res;
+
+ res = (duk_hboundfunc *) DUK_ALLOC(heap, sizeof(duk_hboundfunc));
+ if (!res) {
+ return NULL;
+ }
+ DUK_MEMZERO(res, sizeof(duk_hboundfunc));
+
+ duk__init_object_parts(heap, hobject_flags, &res->obj);
+
+ DUK_TVAL_SET_UNDEFINED(&res->target);
+ DUK_TVAL_SET_UNDEFINED(&res->this_binding);
+
+#if defined(DUK_USE_EXPLICIT_NULL_INIT)
+ res->args = NULL;
+#endif
+
+ return res;
+}
+
#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)
DUK_INTERNAL duk_hbufobj *duk_hbufobj_alloc(duk_hthread *thr, duk_uint_t hobject_flags) {
duk_hbufobj *res;
@@ -50426,11 +52014,10 @@ DUK_INTERNAL duk_hthread *duk_hthread_alloc_unchecked(duk_heap *heap, duk_uint_t
res->heap = NULL;
res->valstack = NULL;
res->valstack_end = NULL;
+ res->valstack_alloc_end = NULL;
res->valstack_bottom = NULL;
res->valstack_top = NULL;
- res->callstack = NULL;
res->callstack_curr = NULL;
- res->catchstack = NULL;
res->resumer = NULL;
res->compile_ctx = NULL,
#if defined(DUK_USE_HEAPPTR16)
@@ -50445,14 +52032,12 @@ DUK_INTERNAL duk_hthread *duk_hthread_alloc_unchecked(duk_heap *heap, duk_uint_t
}
}
#endif
- /* when nothing is running, API calls are in non-strict mode */
+ /* When nothing is running, API calls are in non-strict mode. */
DUK_ASSERT(res->strict == 0);
res->heap = heap;
- res->valstack_max = DUK_VALSTACK_DEFAULT_MAX;
- res->callstack_max = DUK_CALLSTACK_DEFAULT_MAX;
- res->catchstack_max = DUK_CATCHSTACK_DEFAULT_MAX;
+ /* XXX: Any reason not to merge duk_hthread_alloc.c here? */
return res;
}
@@ -50487,7 +52072,7 @@ DUK_INTERNAL duk_hdecenv *duk_hdecenv_alloc(duk_hthread *thr, duk_uint_t hobject
DUK_ASSERT(res->thread == NULL);
DUK_ASSERT(res->varmap == NULL);
- DUK_ASSERT(res->regbase == 0);
+ DUK_ASSERT(res->regbase_byteoff == 0);
return res;
}
@@ -50504,6 +52089,18 @@ DUK_INTERNAL duk_hobjenv *duk_hobjenv_alloc(duk_hthread *thr, duk_uint_t hobject
return res;
}
+
+DUK_INTERNAL duk_hproxy *duk_hproxy_alloc(duk_hthread *thr, duk_uint_t hobject_flags) {
+ duk_hproxy *res;
+
+ res = (duk_hproxy *) duk__hobject_alloc_init(thr, hobject_flags, sizeof(duk_hproxy));
+
+ /* Leave ->target and ->handler uninitialized, as caller will always
+ * explicitly initialize them before any side effects are possible.
+ */
+
+ return res;
+}
/*
* Object enumeration support.
*
@@ -50532,7 +52129,6 @@ DUK_INTERNAL duk_hobjenv *duk_hobjenv_alloc(duk_hthread *thr, duk_uint_t hobject
*/
#define DUK__ENUM_START_INDEX 2
-#if 0
/* Current implementation suffices for ES2015 for now because there's no symbol
* sorting, so commented out for now.
*/
@@ -50541,55 +52137,72 @@ DUK_INTERNAL duk_hobjenv *duk_hobjenv_alloc(duk_hthread *thr, duk_uint_t hobject
* Helper to sort enumeration keys using a callback for pairwise duk_hstring
* comparisons. The keys are in the enumeration object entry part, starting
* from DUK__ENUM_START_INDEX, and the entry part is dense. Entry part values
- * are all "true", e.g. "1" -> true, "3" -> true, "foo" -> true "2" -> true,
+ * are all "true", e.g. "1" -> true, "3" -> true, "foo" -> true, "2" -> true,
* so it suffices to just switch keys without switching values.
*
+ * ES2015 [[OwnPropertyKeys]] enumeration order for ordinary objects:
+ * (1) array indices in ascending order,
+ * (2) non-array-index keys in insertion order, and
+ * (3) symbols in insertion order.
+ * http://www.ecma-international.org/ecma-262/6.0/#sec-ordinary-object-internal-methods-and-internal-slots-ownpropertykeys.
+ *
+ * This rule is applied to "own properties" at each inheritance level;
+ * non-duplicate parent keys always follow child keys. For example,
+ * an inherited array index will enumerate -after- a symbol in the
+ * child.
+ *
* Insertion sort is used because (1) it's simple and compact, (2) works
* in-place, (3) minimizes operations if data is already nearly sorted,
* (4) doesn't reorder elements considered equal.
* http://en.wikipedia.org/wiki/Insertion_sort
*/
-typedef duk_bool_t (*duk__sort_compare_fn)(duk_hstring *a, duk_hstring *b, duk_uarridx_t val_b);
+/* Sort key, must hold array indices, "not array index" marker, and one more
+ * higher value for symbols.
+ */
+#if !defined(DUK_USE_SYMBOL_BUILTIN)
+typedef duk_uint32_t duk__sort_key_t;
+#elif defined(DUK_USE_64BIT_OPS)
+typedef duk_uint64_t duk__sort_key_t;
+#else
+typedef duk_double_t duk__sort_key_t;
+#endif
+
+/* Get sort key for a duk_hstring. */
+DUK_LOCAL duk__sort_key_t duk__hstring_sort_key(duk_hstring *x) {
+ duk__sort_key_t val;
+
+ /* For array indices [0,0xfffffffe] use the array index as is.
+ * For strings, use 0xffffffff, the marker 'arridx' already in
+ * duk_hstring. For symbols, any value above 0xffffffff works,
+ * as long as it is the same for all symbols; currently just add
+ * the masked flag field into the arridx temporary.
+ */
+ DUK_ASSERT(x != NULL);
+ DUK_ASSERT(!DUK_HSTRING_HAS_SYMBOL(x) || DUK_HSTRING_GET_ARRIDX_FAST(x) == DUK_HSTRING_NO_ARRAY_INDEX);
+
+ val = (duk__sort_key_t) DUK_HSTRING_GET_ARRIDX_FAST(x);
+
+#if defined(DUK_USE_SYMBOL_BUILTIN)
+ val = val + (duk__sort_key_t) (DUK_HEAPHDR_GET_FLAGS_RAW((duk_heaphdr *) x) & DUK_HSTRING_FLAG_SYMBOL);
+#endif
-DUK_LOCAL duk_bool_t duk__sort_compare_es6(duk_hstring *a, duk_hstring *b, duk_uarridx_t val_b) {
- duk_uarridx_t val_a;
+ return (duk__sort_key_t) val;
+}
+
+/* Insert element 'b' after element 'a'? */
+DUK_LOCAL duk_bool_t duk__sort_compare_es6(duk_hstring *a, duk_hstring *b, duk__sort_key_t val_b) {
+ duk__sort_key_t val_a;
DUK_ASSERT(a != NULL);
DUK_ASSERT(b != NULL);
DUK_UNREF(b); /* Not actually needed now, val_b suffices. */
- /* ES2015 [[OwnPropertyKeys]] enumeration order for ordinary objects:
- * (1) array indices in ascending order, (2) non-array-index keys in
- * insertion order, symbols in insertion order:
- * http://www.ecma-international.org/ecma-262/6.0/#sec-ordinary-object-internal-methods-and-internal-slots-ownpropertykeys.
- *
- * This rule is applied to "own properties" at each inheritance level;
- * non-duplicate parent keys always follow child keys. For example,
- * an inherited array index will enumerate -after- a symbol in the
- * child.
- */
-
- val_a = DUK_HSTRING_GET_ARRIDX_FAST(a);
+ val_a = duk__hstring_sort_key(a);
- if (val_b < val_a) {
- /* Covers:
- * - Both keys are array indices and a > b: don't insert here.
- * - 'b' is array index, 'a' is not: don't insert here.
- */
+ if (val_a > val_b) {
return 0;
} else {
- /* Covers:
- * val_a < val_b where:
- * - Both keys are array indices and a < b: insert here.
- * - 'a' is array index, 'b' is not: insert here.
- * val_a == val_b where:
- * - Both keys are array indices and a == b: insert here
- * (shouldn't actually happen, can't have non-duplicate
- * identical array index keys).
- * - Neither key is an array index: insert here, keeps key
- * order regardless of the keys themselves.
- */
return 1;
}
}
@@ -50612,7 +52225,7 @@ DUK_LOCAL void duk__sort_enum_keys_es6(duk_hthread *thr, duk_hobject *h_obj, duk
for (idx = idx_start + 1; idx < idx_end; idx++) {
duk_hstring *h_curr;
duk_int_fast32_t idx_insert;
- duk_uarridx_t val_curr;
+ duk__sort_key_t val_curr;
h_curr = keys[idx];
DUK_ASSERT(h_curr != NULL);
@@ -50622,16 +52235,12 @@ DUK_LOCAL void duk__sort_enum_keys_es6(duk_hthread *thr, duk_hobject *h_obj, duk
* (and optimized for) case.
*/
- val_curr = DUK_HSTRING_GET_ARRIDX_FAST(h_curr); /* Remains same during scanning. */
+ val_curr = duk__hstring_sort_key(h_curr); /* Remains same during scanning. */
for (idx_insert = idx - 1; idx_insert >= idx_start; idx_insert--) {
duk_hstring *h_insert;
h_insert = keys[idx_insert];
DUK_ASSERT(h_insert != NULL);
- /* XXX: fixed callback rather than a callback argument; only
- * one argument used and using a callback argument doesn't
- * cause e.g. gcc to inline the callback.
- */
if (duk__sort_compare_es6(h_insert, h_curr, val_curr)) {
break;
}
@@ -50655,88 +52264,11 @@ DUK_LOCAL void duk__sort_enum_keys_es6(duk_hthread *thr, duk_hobject *h_obj, duk
if (idx != idx_insert) {
DUK_MEMMOVE((void *) (keys + idx_insert + 1),
(const void *) (keys + idx_insert),
- (size_t) ((idx - idx_insert) * sizeof(duk_hstring *)));
+ ((size_t) (idx - idx_insert) * sizeof(duk_hstring *)));
keys[idx_insert] = h_curr;
}
}
}
-#endif /* disabled */
-
-/*
- * Helper to sort keys into ES2015 [[OwnPropertyKeys]] enumeration order:
- * array keys in ascending order first, followed by keys in insertion
- * order, followed by symbols in insertion order (not handled here).
- * Insertion sort based.
- *
- * This algorithm nominally sorts array indices, but because the "no array
- * index" marker is higher than any array index, non-array-index keys are
- * sorted after array indices. Non-array-index keys are also considered
- * equal for sorting which means that their order is kept as is, so the end
- * result matches ES2015 [[OwnPropertyKeys]].
- *
- * Insertion sort is used because (1) it's simple and compact, (2) works
- * in-place, (3) minimizes operations if data is already nearly sorted,
- * (4) doesn't reorder elements considered equal.
- * http://en.wikipedia.org/wiki/Insertion_sort
- */
-
-DUK_LOCAL void duk__sort_enum_keys_es6(duk_hthread *thr, duk_hobject *h_obj, duk_int_fast32_t idx_start, duk_int_fast32_t idx_end) {
- duk_hstring **keys;
- duk_hstring **p_curr, **p_insert, **p_end;
- duk_hstring *h_curr;
- duk_uarridx_t val_highest, val_curr, val_insert;
-
- DUK_ASSERT(h_obj != NULL);
- DUK_ASSERT(idx_start >= DUK__ENUM_START_INDEX);
- DUK_ASSERT(idx_end >= idx_start);
- DUK_UNREF(thr);
-
- if (idx_end <= idx_start + 1) {
- return; /* Zero or one element(s). */
- }
-
- keys = DUK_HOBJECT_E_GET_KEY_BASE(thr->heap, h_obj);
- p_curr = keys + idx_start;
- val_highest = DUK_HSTRING_GET_ARRIDX_SLOW(*p_curr);
- for (p_curr++, p_end = keys + idx_end; p_curr < p_end; p_curr++) {
- DUK_ASSERT(*p_curr != NULL);
- val_curr = DUK_HSTRING_GET_ARRIDX_SLOW(*p_curr);
-
- if (val_curr >= val_highest) {
- val_highest = val_curr;
- continue;
- }
-
- /* Needs to be inserted; scan backwards, since we optimize
- * for the case where elements are nearly in order.
- */
-
- p_insert = p_curr;
- for (;;) {
- p_insert--; /* Start from p_curr - 1. */
- val_insert = DUK_HSTRING_GET_ARRIDX_SLOW(*p_insert);
- if (val_insert < val_curr) {
- p_insert++;
- break;
- }
- if (p_insert == keys + idx_start) {
- break;
- }
- }
-
- /* .-- p_insert .-- p_curr
- * v v
- * | ... | insert | ... | curr
- */
-
- h_curr = *p_curr;
- DUK_MEMMOVE((void *) (p_insert + 1),
- (const void *) p_insert,
- (size_t) ((p_curr - p_insert) * sizeof(duk_hstring *)));
- *p_insert = h_curr;
- /* keep val_highest */
- }
-}
/*
* Create an internal enumerator object E, which has its keys ordered
@@ -50747,21 +52279,20 @@ DUK_LOCAL void duk__sort_enum_keys_es6(duk_hthread *thr, duk_hobject *h_obj, duk
* scan would be needed to eliminate duplicates found in the prototype chain.
*/
-DUK_LOCAL void duk__add_enum_key(duk_context *ctx, duk_hstring *k) {
+DUK_LOCAL void duk__add_enum_key(duk_hthread *thr, duk_hstring *k) {
/* 'k' may be unreachable on entry so must push without any
* potential for GC.
*/
- duk_push_hstring(ctx, k);
- duk_push_true(ctx);
- duk_put_prop(ctx, -3);
+ duk_push_hstring(thr, k);
+ duk_push_true(thr);
+ duk_put_prop(thr, -3);
}
-DUK_LOCAL void duk__add_enum_key_stridx(duk_context *ctx, duk_small_uint_t stridx) {
- duk__add_enum_key(ctx, DUK_HTHREAD_GET_STRING((duk_hthread *) ctx, stridx));
+DUK_LOCAL void duk__add_enum_key_stridx(duk_hthread *thr, duk_small_uint_t stridx) {
+ duk__add_enum_key(thr, DUK_HTHREAD_GET_STRING(thr, stridx));
}
-DUK_INTERNAL void duk_hobject_enumerator_create(duk_context *ctx, duk_small_uint_t enum_flags) {
- duk_hthread *thr = (duk_hthread *) ctx;
+DUK_INTERNAL void duk_hobject_enumerator_create(duk_hthread *thr, duk_small_uint_t enum_flags) {
duk_hobject *enum_target;
duk_hobject *curr;
duk_hobject *res;
@@ -50773,13 +52304,13 @@ DUK_INTERNAL void duk_hobject_enumerator_create(duk_context *ctx, duk_small_uint
duk_uint_fast32_t i, len; /* used for array, stack, and entry indices */
duk_uint_fast32_t sort_start_index;
- DUK_ASSERT(ctx != NULL);
+ DUK_ASSERT(thr != NULL);
- enum_target = duk_require_hobject(ctx, -1);
+ enum_target = duk_require_hobject(thr, -1);
DUK_ASSERT(enum_target != NULL);
- duk_push_bare_object(ctx);
- res = duk_known_hobject(ctx, -1);
+ duk_push_bare_object(thr);
+ res = duk_known_hobject(thr, -1);
/* [enum_target res] */
@@ -50788,12 +52319,12 @@ DUK_INTERNAL void duk_hobject_enumerator_create(duk_context *ctx, duk_small_uint
* enumeration result comes from a proxy trap as there is no
* real object to check against.
*/
- duk_push_hobject(ctx, enum_target);
- duk_put_prop_stridx_short(ctx, -2, DUK_STRIDX_INT_TARGET);
+ duk_push_hobject(thr, enum_target);
+ duk_put_prop_stridx_short(thr, -2, DUK_STRIDX_INT_TARGET);
/* Initialize index so that we skip internal control keys. */
- duk_push_int(ctx, DUK__ENUM_START_INDEX);
- duk_put_prop_stridx_short(ctx, -2, DUK_STRIDX_INT_NEXT);
+ duk_push_int(thr, DUK__ENUM_START_INDEX);
+ duk_put_prop_stridx_short(thr, -2, DUK_STRIDX_INT_NEXT);
/*
* Proxy object handling
@@ -50803,8 +52334,7 @@ DUK_INTERNAL void duk_hobject_enumerator_create(duk_context *ctx, duk_small_uint
if (DUK_LIKELY((enum_flags & DUK_ENUM_NO_PROXY_BEHAVIOR) != 0)) {
goto skip_proxy;
}
- if (DUK_LIKELY(!duk_hobject_proxy_check(thr,
- enum_target,
+ if (DUK_LIKELY(!duk_hobject_proxy_check(enum_target,
&h_proxy_target,
&h_proxy_handler))) {
goto skip_proxy;
@@ -50816,8 +52346,8 @@ DUK_INTERNAL void duk_hobject_enumerator_create(duk_context *ctx, duk_small_uint
* has been obsoleted and "ownKeys" is used instead.
*/
DUK_DDD(DUK_DDDPRINT("proxy enumeration"));
- duk_push_hobject(ctx, h_proxy_handler);
- if (!duk_get_prop_stridx_short(ctx, -1, DUK_STRIDX_OWN_KEYS)) {
+ duk_push_hobject(thr, h_proxy_handler);
+ if (!duk_get_prop_stridx_short(thr, -1, DUK_STRIDX_OWN_KEYS)) {
/* No need to replace the 'enum_target' value in stack, only the
* enum_target reference. This also ensures that the original
* enum target is reachable, which keeps the proxy and the proxy
@@ -50827,38 +52357,38 @@ DUK_INTERNAL void duk_hobject_enumerator_create(duk_context *ctx, duk_small_uint
DUK_DDD(DUK_DDDPRINT("h_proxy_target=%!O", (duk_heaphdr *) h_proxy_target));
enum_target = h_proxy_target;
- duk_push_hobject(ctx, enum_target); /* -> [ ... enum_target res handler undefined target ] */
- duk_put_prop_stridx_short(ctx, -4, DUK_STRIDX_INT_TARGET);
+ duk_push_hobject(thr, enum_target); /* -> [ ... enum_target res handler undefined target ] */
+ duk_put_prop_stridx_short(thr, -4, DUK_STRIDX_INT_TARGET);
- duk_pop_2(ctx); /* -> [ ... enum_target res ] */
+ duk_pop_2(thr); /* -> [ ... enum_target res ] */
goto skip_proxy;
}
/* [ ... enum_target res handler trap ] */
- duk_insert(ctx, -2);
- duk_push_hobject(ctx, h_proxy_target); /* -> [ ... enum_target res trap handler target ] */
- duk_call_method(ctx, 1 /*nargs*/); /* -> [ ... enum_target res trap_result ] */
- h_trap_result = duk_require_hobject(ctx, -1);
+ duk_insert(thr, -2);
+ duk_push_hobject(thr, h_proxy_target); /* -> [ ... enum_target res trap handler target ] */
+ duk_call_method(thr, 1 /*nargs*/); /* -> [ ... enum_target res trap_result ] */
+ h_trap_result = duk_require_hobject(thr, -1);
DUK_UNREF(h_trap_result);
- duk_proxy_ownkeys_postprocess(ctx, h_proxy_target, enum_flags);
+ duk_proxy_ownkeys_postprocess(thr, h_proxy_target, enum_flags);
/* -> [ ... enum_target res trap_result keys_array ] */
/* Copy cleaned up trap result keys into the enumerator object. */
/* XXX: result is a dense array; could make use of that. */
- DUK_ASSERT(duk_is_array(ctx, -1));
- len = (duk_uint_fast32_t) duk_get_length(ctx, -1);
+ DUK_ASSERT(duk_is_array(thr, -1));
+ len = (duk_uint_fast32_t) duk_get_length(thr, -1);
for (i = 0; i < len; i++) {
- (void) duk_get_prop_index(ctx, -1, i);
- DUK_ASSERT(duk_is_string(ctx, -1)); /* postprocess cleaned up */
+ (void) duk_get_prop_index(thr, -1, (duk_uarridx_t) i);
+ DUK_ASSERT(duk_is_string(thr, -1)); /* postprocess cleaned up */
/* [ ... enum_target res trap_result keys_array val ] */
- duk_push_true(ctx);
+ duk_push_true(thr);
/* [ ... enum_target res trap_result keys_array val true ] */
- duk_put_prop(ctx, -5);
+ duk_put_prop(thr, -5);
}
/* [ ... enum_target res trap_result keys_array ] */
- duk_pop_2(ctx);
- duk_remove_m2(ctx);
+ duk_pop_2(thr);
+ duk_remove_m2(thr);
/* [ ... res ] */
@@ -50951,10 +52481,10 @@ DUK_INTERNAL void duk_hobject_enumerator_create(duk_context *ctx, duk_small_uint
/* This is a bit fragile: the string is not
* reachable until it is pushed by the helper.
*/
- k = duk_heap_strtable_intern_u32_checked(thr, i);
+ k = duk_heap_strtable_intern_u32_checked(thr, (duk_uint32_t) i);
DUK_ASSERT(k);
- duk__add_enum_key(ctx, k);
+ duk__add_enum_key(thr, k);
/* [enum_target res] */
}
@@ -50965,11 +52495,7 @@ DUK_INTERNAL void duk_hobject_enumerator_create(duk_context *ctx, duk_small_uint
*/
if (have_length && (enum_flags & DUK_ENUM_INCLUDE_NONENUMERABLE)) {
- duk__add_enum_key_stridx(ctx, DUK_STRIDX_LENGTH);
- }
- } else if (DUK_HOBJECT_HAS_EXOTIC_DUKFUNC(curr)) {
- if (enum_flags & DUK_ENUM_INCLUDE_NONENUMERABLE) {
- duk__add_enum_key_stridx(ctx, DUK_STRIDX_LENGTH);
+ duk__add_enum_key_stridx(thr, DUK_STRIDX_LENGTH);
}
}
@@ -50985,10 +52511,10 @@ DUK_INTERNAL void duk_hobject_enumerator_create(duk_context *ctx, duk_small_uint
if (DUK_TVAL_IS_UNUSED(tv)) {
continue;
}
- k = duk_heap_strtable_intern_u32_checked(thr, i); /* Fragile reachability. */
+ k = duk_heap_strtable_intern_u32_checked(thr, (duk_uint32_t) i); /* Fragile reachability. */
DUK_ASSERT(k);
- duk__add_enum_key(ctx, k);
+ duk__add_enum_key(thr, k);
/* [enum_target res] */
}
@@ -50996,7 +52522,7 @@ DUK_INTERNAL void duk_hobject_enumerator_create(duk_context *ctx, duk_small_uint
if (DUK_HOBJECT_HAS_EXOTIC_ARRAY(curr)) {
/* Array .length comes after numeric indices. */
if (enum_flags & DUK_ENUM_INCLUDE_NONENUMERABLE) {
- duk__add_enum_key_stridx(ctx, DUK_STRIDX_LENGTH);
+ duk__add_enum_key_stridx(thr, DUK_STRIDX_LENGTH);
}
}
@@ -51023,6 +52549,9 @@ DUK_INTERNAL void duk_hobject_enumerator_create(duk_context *ctx, duk_small_uint
if (!(enum_flags & DUK_ENUM_INCLUDE_SYMBOLS)) {
continue;
}
+#if !defined(DUK_USE_PREFER_SIZE)
+ need_sort = 1;
+#endif
} else {
DUK_ASSERT(!DUK_HSTRING_HAS_HIDDEN(k)); /* would also have symbol flag */
if (enum_flags & DUK_ENUM_EXCLUDE_STRINGS) {
@@ -51046,7 +52575,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_UNUSED(&DUK_HOBJECT_E_GET_VALUE_PTR(thr->heap, curr, i)->v));
- duk__add_enum_key(ctx, k);
+ duk__add_enum_key(thr, k);
/* [enum_target res] */
}
@@ -51069,11 +52598,11 @@ DUK_INTERNAL void duk_hobject_enumerator_create(duk_context *ctx, duk_small_uint
if (!(enum_flags & DUK_ENUM_SORT_ARRAY_INDICES)) {
#if defined(DUK_USE_PREFER_SIZE)
- duk__sort_enum_keys_es6(thr, res, sort_start_index, sort_end_index);
+ duk__sort_enum_keys_es6(thr, res, (duk_int_fast32_t) sort_start_index, (duk_int_fast32_t) sort_end_index);
#else
if (need_sort) {
DUK_DDD(DUK_DDDPRINT("need to sort"));
- duk__sort_enum_keys_es6(thr, res, sort_start_index, sort_end_index);
+ duk__sort_enum_keys_es6(thr, res, (duk_int_fast32_t) sort_start_index, (duk_int_fast32_t) sort_end_index);
} else {
DUK_DDD(DUK_DDDPRINT("no need to sort"));
}
@@ -51091,7 +52620,7 @@ DUK_INTERNAL void duk_hobject_enumerator_create(duk_context *ctx, duk_small_uint
/* [enum_target res] */
- duk_remove_m2(ctx);
+ duk_remove_m2(thr);
/* [res] */
@@ -51106,7 +52635,7 @@ DUK_INTERNAL void duk_hobject_enumerator_create(duk_context *ctx, duk_small_uint
/* Sort to ES2015 order which works for pure array incides but
* also for mixed keys.
*/
- duk__sort_enum_keys_es6(thr, res, DUK__ENUM_START_INDEX, DUK_HOBJECT_GET_ENEXT(res));
+ duk__sort_enum_keys_es6(thr, res, (duk_int_fast32_t) DUK__ENUM_START_INDEX, (duk_int_fast32_t) DUK_HOBJECT_GET_ENEXT(res));
}
#if defined(DUK_USE_ES6_PROXY)
@@ -51115,7 +52644,7 @@ DUK_INTERNAL void duk_hobject_enumerator_create(duk_context *ctx, duk_small_uint
/* compact; no need to seal because object is internal */
duk_hobject_compact_props(thr, res);
- DUK_DDD(DUK_DDDPRINT("created enumerator object: %!iT", (duk_tval *) duk_get_tval(ctx, -1)));
+ DUK_DDD(DUK_DDDPRINT("created enumerator object: %!iT", (duk_tval *) duk_get_tval(thr, -1)));
}
/*
@@ -51126,24 +52655,23 @@ DUK_INTERNAL void duk_hobject_enumerator_create(duk_context *ctx, duk_small_uint
*
* Returns zero without pushing anything on the stack otherwise.
*/
-DUK_INTERNAL duk_bool_t duk_hobject_enumerator_next(duk_context *ctx, duk_bool_t get_value) {
- duk_hthread *thr = (duk_hthread *) ctx;
+DUK_INTERNAL duk_bool_t duk_hobject_enumerator_next(duk_hthread *thr, duk_bool_t get_value) {
duk_hobject *e;
duk_hobject *enum_target;
duk_hstring *res = NULL;
duk_uint_fast32_t idx;
duk_bool_t check_existence;
- DUK_ASSERT(ctx != NULL);
+ DUK_ASSERT(thr != NULL);
/* [... enum] */
- e = duk_require_hobject(ctx, -1);
+ e = duk_require_hobject(thr, -1);
/* XXX use get tval ptr, more efficient */
- duk_get_prop_stridx_short(ctx, -1, DUK_STRIDX_INT_NEXT);
- idx = (duk_uint_fast32_t) duk_require_uint(ctx, -1);
- duk_pop(ctx);
+ duk_get_prop_stridx_short(thr, -1, DUK_STRIDX_INT_NEXT);
+ idx = (duk_uint_fast32_t) duk_require_uint(thr, -1);
+ duk_pop(thr);
DUK_DDD(DUK_DDDPRINT("enumeration: index is: %ld", (long) idx));
/* Enumeration keys are checked against the enumeration target (to see
@@ -51151,18 +52679,18 @@ DUK_INTERNAL duk_bool_t duk_hobject_enumerator_next(duk_context *ctx, duk_bool_t
* be the proxy, and checking key existence against the proxy is not
* required (or sensible, as the keys may be fully virtual).
*/
- duk_get_prop_stridx_short(ctx, -1, DUK_STRIDX_INT_TARGET);
- enum_target = duk_require_hobject(ctx, -1);
+ duk_get_prop_stridx_short(thr, -1, DUK_STRIDX_INT_TARGET);
+ enum_target = duk_require_hobject(thr, -1);
DUK_ASSERT(enum_target != NULL);
#if defined(DUK_USE_ES6_PROXY)
- check_existence = (!DUK_HOBJECT_HAS_EXOTIC_PROXYOBJ(enum_target));
+ check_existence = (!DUK_HOBJECT_IS_PROXY(enum_target));
#else
check_existence = 1;
#endif
- duk_pop(ctx); /* still reachable */
+ duk_pop(thr); /* still reachable */
DUK_DDD(DUK_DDDPRINT("getting next enum value, enum_target=%!iO, enumerator=%!iT",
- (duk_heaphdr *) enum_target, (duk_tval *) duk_get_tval(ctx, -1)));
+ (duk_heaphdr *) enum_target, (duk_tval *) duk_get_tval(thr, -1)));
/* no array part */
for (;;) {
@@ -51194,25 +52722,25 @@ DUK_INTERNAL duk_bool_t duk_hobject_enumerator_next(duk_context *ctx, duk_bool_t
DUK_DDD(DUK_DDDPRINT("enumeration: updating next index to %ld", (long) idx));
- duk_push_u32(ctx, (duk_uint32_t) idx);
- duk_put_prop_stridx_short(ctx, -2, DUK_STRIDX_INT_NEXT);
+ duk_push_u32(thr, (duk_uint32_t) idx);
+ duk_put_prop_stridx_short(thr, -2, DUK_STRIDX_INT_NEXT);
/* [... enum] */
if (res) {
- duk_push_hstring(ctx, res);
+ duk_push_hstring(thr, res);
if (get_value) {
- duk_push_hobject(ctx, enum_target);
- duk_dup_m2(ctx); /* -> [... enum key enum_target key] */
- duk_get_prop(ctx, -2); /* -> [... enum key enum_target val] */
- duk_remove_m2(ctx); /* -> [... enum key val] */
- duk_remove(ctx, -3); /* -> [... key val] */
+ duk_push_hobject(thr, enum_target);
+ duk_dup_m2(thr); /* -> [... enum key enum_target key] */
+ duk_get_prop(thr, -2); /* -> [... enum key enum_target val] */
+ duk_remove_m2(thr); /* -> [... enum key val] */
+ duk_remove(thr, -3); /* -> [... key val] */
} else {
- duk_remove_m2(ctx); /* -> [... key] */
+ duk_remove_m2(thr); /* -> [... key] */
}
return 1;
} else {
- duk_pop(ctx); /* -> [...] */
+ duk_pop(thr); /* -> [...] */
return 0;
}
}
@@ -51222,25 +52750,22 @@ DUK_INTERNAL duk_bool_t duk_hobject_enumerator_next(duk_context *ctx, duk_bool_t
* described in E5 Section 15.2.3.14.
*/
-DUK_INTERNAL duk_ret_t duk_hobject_get_enumerated_keys(duk_context *ctx, duk_small_uint_t enum_flags) {
- duk_hthread *thr = (duk_hthread *) ctx;
+DUK_INTERNAL duk_ret_t duk_hobject_get_enumerated_keys(duk_hthread *thr, duk_small_uint_t enum_flags) {
duk_hobject *e;
- duk_harray *a;
duk_hstring **keys;
duk_tval *tv;
duk_uint_fast32_t count;
- DUK_ASSERT(ctx != NULL);
- DUK_ASSERT(duk_get_hobject(ctx, -1) != NULL);
- DUK_UNREF(thr);
+ DUK_ASSERT(thr != NULL);
+ DUK_ASSERT(duk_get_hobject(thr, -1) != NULL);
/* Create a temporary enumerator to get the (non-duplicated) key list;
* the enumerator state is initialized without being needed, but that
* has little impact.
*/
- duk_hobject_enumerator_create(ctx, enum_flags);
- e = duk_known_hobject(ctx, -1);
+ duk_hobject_enumerator_create(thr, enum_flags);
+ e = duk_known_hobject(thr, -1);
/* [enum_target enum res] */
@@ -51248,11 +52773,9 @@ DUK_INTERNAL duk_ret_t duk_hobject_get_enumerated_keys(duk_context *ctx, duk_sma
DUK_ASSERT(DUK_HOBJECT_GET_ENEXT(e) >= DUK__ENUM_START_INDEX);
count = (duk_uint32_t) (DUK_HOBJECT_GET_ENEXT(e) - DUK__ENUM_START_INDEX);
- a = duk_push_harray_with_size(ctx, count);
- DUK_ASSERT(a != NULL);
- DUK_ASSERT(DUK_HOBJECT_GET_ASIZE((duk_hobject *) a) == count);
- DUK_ASSERT(a->length == count);
- tv = DUK_HOBJECT_A_GET_BASE(thr->heap, (duk_hobject *) a);
+ /* XXX: uninit would be OK */
+ tv = duk_push_harray_with_size_outptr(thr, (duk_uint32_t) count);
+ DUK_ASSERT(count == 0 || tv != NULL);
/* Fill result array, no side effects. */
@@ -51271,7 +52794,7 @@ DUK_INTERNAL duk_ret_t duk_hobject_get_enumerated_keys(duk_context *ctx, duk_sma
}
/* [enum_target enum res] */
- duk_remove_m2(ctx);
+ duk_remove_m2(thr);
/* [enum_target res] */
@@ -51347,7 +52870,6 @@ DUK_INTERNAL void duk_hobject_set_prototype_updref(duk_hthread *thr, duk_hobject
/* Generate pc2line data for an instruction sequence, leaving a buffer on stack top. */
DUK_INTERNAL void duk_hobject_pc2line_pack(duk_hthread *thr, duk_compiler_instr *instrs, duk_uint_fast32_t length) {
- duk_context *ctx = (duk_context *) thr;
duk_hbuffer_dynamic *h_buf;
duk_bitencoder_ctx be_ctx_alloc;
duk_bitencoder_ctx *be_ctx = &be_ctx_alloc;
@@ -51361,15 +52883,11 @@ DUK_INTERNAL void duk_hobject_pc2line_pack(duk_hthread *thr, duk_compiler_instr
DUK_ASSERT(length <= DUK_COMPILER_MAX_BYTECODE_LENGTH);
- /* XXX: add proper spare handling to dynamic buffer, to minimize
- * reallocs; currently there is no spare at all.
- */
-
num_header_entries = (length + DUK_PC2LINE_SKIP - 1) / DUK_PC2LINE_SKIP;
curr_offset = (duk_uint_fast32_t) (sizeof(duk_uint32_t) + num_header_entries * sizeof(duk_uint32_t) * 2);
- duk_push_dynamic_buffer(ctx, (duk_size_t) curr_offset);
- h_buf = (duk_hbuffer_dynamic *) duk_known_hbuffer(ctx, -1);
+ duk_push_dynamic_buffer(thr, (duk_size_t) curr_offset);
+ h_buf = (duk_hbuffer_dynamic *) duk_known_hbuffer(thr, -1);
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);
@@ -51421,17 +52939,17 @@ DUK_INTERNAL void duk_hobject_pc2line_pack(duk_hthread *thr, duk_compiler_instr
duk_be_encode(be_ctx, 0, 1);
} else if (diff_line >= 1 && diff_line <= 4) {
/* 1 0 <2 bits> */
- duk_be_encode(be_ctx, (0x02 << 2) + (diff_line - 1), 4);
+ duk_be_encode(be_ctx, (duk_uint32_t) ((0x02 << 2) + (diff_line - 1)), 4);
} else if (diff_line >= -0x80 && diff_line <= 0x7f) {
/* 1 1 0 <8 bits> */
DUK_ASSERT(diff_line + 0x80 >= 0 && diff_line + 0x80 <= 0xff);
- duk_be_encode(be_ctx, (0x06 << 8) + (diff_line + 0x80), 11);
+ duk_be_encode(be_ctx, (duk_uint32_t) ((0x06 << 8) + (diff_line + 0x80)), 11);
} else {
/* 1 1 1 <32 bits>
* Encode in two parts to avoid bitencode 24-bit limitation
*/
- duk_be_encode(be_ctx, (0x07 << 16) + ((next_line >> 16) & 0xffffU), 19);
- duk_be_encode(be_ctx, next_line & 0xffffU, 16);
+ duk_be_encode(be_ctx, (duk_uint32_t) ((0x07 << 16) + ((next_line >> 16) & 0xffff)), 19);
+ duk_be_encode(be_ctx, (duk_uint32_t) (next_line & 0xffff), 16);
}
curr_line = next_line;
@@ -51448,11 +52966,11 @@ DUK_INTERNAL void duk_hobject_pc2line_pack(duk_hthread *thr, duk_compiler_instr
new_size = (duk_size_t) curr_offset;
duk_hbuffer_resize(thr, h_buf, new_size);
- (void) duk_to_fixed_buffer(ctx, -1, NULL);
+ (void) duk_to_fixed_buffer(thr, -1, NULL);
DUK_DDD(DUK_DDDPRINT("final pc2line data: pc_limit=%ld, length=%ld, %lf bits/opcode --> %!ixT",
(long) length, (long) new_size, (double) new_size * 8.0 / (double) length,
- (duk_tval *) duk_get_tval(ctx, -1)));
+ (duk_tval *) duk_get_tval(thr, -1)));
}
/* PC is unsigned. If caller does PC arithmetic and gets a negative result,
@@ -51557,7 +53075,7 @@ DUK_LOCAL duk_uint_fast32_t duk__hobject_pc2line_query_raw(duk_hthread *thr, duk
return 0;
}
-DUK_INTERNAL duk_uint_fast32_t duk_hobject_pc2line_query(duk_context *ctx, duk_idx_t idx_func, duk_uint_fast32_t pc) {
+DUK_INTERNAL duk_uint_fast32_t duk_hobject_pc2line_query(duk_hthread *thr, duk_idx_t idx_func, duk_uint_fast32_t pc) {
duk_hbuffer_fixed *pc2line;
duk_uint_fast32_t line;
@@ -51567,15 +53085,15 @@ DUK_INTERNAL duk_uint_fast32_t duk_hobject_pc2line_query(duk_context *ctx, duk_i
* future work in debugger.rst).
*/
- duk_get_prop_stridx(ctx, idx_func, DUK_STRIDX_INT_PC2LINE);
- pc2line = (duk_hbuffer_fixed *) duk_get_hbuffer(ctx, -1);
+ duk_get_prop_stridx(thr, idx_func, DUK_STRIDX_INT_PC2LINE);
+ pc2line = (duk_hbuffer_fixed *) duk_get_hbuffer(thr, -1);
if (pc2line != NULL) {
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);
+ line = duk__hobject_pc2line_query_raw(thr, pc2line, (duk_uint_fast32_t) pc);
} else {
line = 0;
}
- duk_pop(ctx);
+ duk_pop(thr);
return line;
}
@@ -51631,17 +53149,17 @@ DUK_INTERNAL duk_uint_fast32_t duk_hobject_pc2line_query(duk_context *ctx, duk_i
#define DUK__NO_ARRAY_INDEX DUK_HSTRING_NO_ARRAY_INDEX
-/* marker values for hash part */
+/* Marker values for hash part. */
#define DUK__HASH_UNUSED DUK_HOBJECT_HASHIDX_UNUSED
#define DUK__HASH_DELETED DUK_HOBJECT_HASHIDX_DELETED
-/* valstack space that suffices for all local calls, including recursion
- * of other than Duktape calls (getters etc)
+/* Valstack space that suffices for all local calls, excluding any recursion
+ * into Ecmascript or Duktape/C calls (Proxy, getters, etc).
*/
#define DUK__VALSTACK_SPACE 10
-/* valstack space allocated especially for proxy lookup which does a
- * recursive property lookup
+/* Valstack space allocated especially for proxy lookup which does a
+ * recursive property lookup.
*/
#define DUK__VALSTACK_PROXY_LOOKUP 20
@@ -51700,7 +53218,7 @@ DUK_LOCAL duk_uint32_t duk__tval_fastint_to_arr_idx(duk_tval *tv) {
DUK_ASSERT(DUK_TVAL_IS_FASTINT(tv));
t = DUK_TVAL_GET_FASTINT(tv);
- if ((t & ~0xffffffffULL) != 0) {
+ if (((duk_uint64_t) t & ~DUK_U64_CONSTANT(0xffffffff)) != 0) {
/* Catches >0x100000000 and negative values. */
return DUK__NO_ARRAY_INDEX;
}
@@ -51719,14 +53237,14 @@ DUK_LOCAL duk_uint32_t duk__tval_fastint_to_arr_idx(duk_tval *tv) {
* Also check if it's a valid array index and return that (or DUK__NO_ARRAY_INDEX
* if not).
*/
-DUK_LOCAL duk_uint32_t duk__to_property_key(duk_context *ctx, duk_idx_t idx, duk_hstring **out_h) {
+DUK_LOCAL duk_uint32_t duk__to_property_key(duk_hthread *thr, duk_idx_t idx, duk_hstring **out_h) {
duk_uint32_t arr_idx;
duk_hstring *h;
duk_tval *tv_dst;
- DUK_ASSERT(ctx != NULL);
+ DUK_ASSERT(thr != NULL);
DUK_ASSERT(out_h != NULL);
- DUK_ASSERT(duk_is_valid_index(ctx, idx));
+ DUK_ASSERT(duk_is_valid_index(thr, idx));
DUK_ASSERT(idx < 0);
/* XXX: The revised ES2015 ToPropertyKey() handling (ES5.1 was just
@@ -51735,7 +53253,7 @@ DUK_LOCAL duk_uint32_t duk__to_property_key(duk_context *ctx, duk_idx_t idx, duk
* but still be compliant and share code.
*/
- tv_dst = DUK_GET_TVAL_NEGIDX((duk_hthread *) ctx, idx); /* intentionally unvalidated */
+ tv_dst = DUK_GET_TVAL_NEGIDX(thr, idx); /* intentionally unvalidated */
if (DUK_TVAL_IS_STRING(tv_dst)) {
/* Most important path: strings and plain symbols are used as
* is. For symbols the array index check below is unnecessary
@@ -51745,7 +53263,7 @@ DUK_LOCAL duk_uint32_t duk__to_property_key(duk_context *ctx, duk_idx_t idx, duk
*/
h = DUK_TVAL_GET_STRING(tv_dst);
} else {
- h = duk_to_property_key_hstring(ctx, idx);
+ h = duk_to_property_key_hstring(thr, idx);
}
DUK_ASSERT(h != NULL);
*out_h = h;
@@ -51754,16 +53272,9 @@ DUK_LOCAL duk_uint32_t duk__to_property_key(duk_context *ctx, duk_idx_t idx, duk
return arr_idx;
}
-DUK_LOCAL duk_uint32_t duk__push_tval_to_property_key(duk_context *ctx, duk_tval *tv_key, duk_hstring **out_h) {
- duk_push_tval(ctx, tv_key); /* XXX: could use an unsafe push here */
- return duk__to_property_key(ctx, -1, out_h);
-}
-
-/* String is an own (virtual) property of a lightfunc. */
-DUK_LOCAL duk_bool_t duk__key_is_lightfunc_ownprop(duk_hthread *thr, duk_hstring *key) {
- DUK_UNREF(thr);
- return (key == DUK_HTHREAD_STRING_LENGTH(thr) ||
- key == DUK_HTHREAD_STRING_NAME(thr));
+DUK_LOCAL duk_uint32_t duk__push_tval_to_property_key(duk_hthread *thr, duk_tval *tv_key, duk_hstring **out_h) {
+ duk_push_tval(thr, tv_key); /* XXX: could use an unsafe push here */
+ return duk__to_property_key(thr, -1, out_h);
}
/* String is an own (virtual) property of a plain buffer. */
@@ -51890,8 +53401,8 @@ DUK_LOCAL void duk__compute_a_stats(duk_hthread *thr, duk_hobject *obj, duk_uint
* for out_min_size as intended.
*/
- *out_used = used;
- *out_min_size = highest_idx + 1; /* 0 if no used entries */
+ *out_used = (duk_uint32_t) used;
+ *out_min_size = (duk_uint32_t) (highest_idx + 1); /* 0 if no used entries */
}
/* Check array density and indicate whether or not the array part should be abandoned. */
@@ -51946,13 +53457,9 @@ DUK_LOCAL duk_bool_t duk__abandon_array_slow_check_required(duk_uint32_t arr_idx
*/
#if defined(DUK_USE_ES6_PROXY)
-DUK_INTERNAL duk_bool_t duk_hobject_proxy_check(duk_hthread *thr, duk_hobject *obj, duk_hobject **out_target, duk_hobject **out_handler) {
- duk_tval *tv_target;
- duk_tval *tv_handler;
- duk_hobject *h_target;
- duk_hobject *h_handler;
+DUK_INTERNAL duk_bool_t duk_hobject_proxy_check(duk_hobject *obj, duk_hobject **out_target, duk_hobject **out_handler) {
+ duk_hproxy *h_proxy;
- DUK_ASSERT(thr != NULL);
DUK_ASSERT(obj != NULL);
DUK_ASSERT(out_target != NULL);
DUK_ASSERT(out_handler != NULL);
@@ -51960,31 +53467,16 @@ DUK_INTERNAL duk_bool_t duk_hobject_proxy_check(duk_hthread *thr, duk_hobject *o
/* Caller doesn't need to check exotic proxy behavior (but does so for
* some fast paths).
*/
- if (DUK_LIKELY(!DUK_HOBJECT_HAS_EXOTIC_PROXYOBJ(obj))) {
- return 0;
- }
-
- tv_handler = duk_hobject_find_existing_entry_tval_ptr(thr->heap, obj, DUK_HTHREAD_STRING_INT_HANDLER(thr));
- if (!tv_handler) {
- DUK_ERROR_TYPE(thr, DUK_STR_PROXY_REVOKED);
+ if (DUK_LIKELY(!DUK_HOBJECT_IS_PROXY(obj))) {
return 0;
}
- DUK_ASSERT(DUK_TVAL_IS_OBJECT(tv_handler));
- h_handler = DUK_TVAL_GET_OBJECT(tv_handler);
- DUK_ASSERT(h_handler != NULL);
- *out_handler = h_handler;
- tv_handler = NULL; /* avoid issues with relocation */
+ h_proxy = (duk_hproxy *) obj;
+ DUK_ASSERT_HPROXY_VALID(h_proxy);
- tv_target = duk_hobject_find_existing_entry_tval_ptr(thr->heap, obj, DUK_HTHREAD_STRING_INT_TARGET(thr));
- if (!tv_target) {
- DUK_ERROR_TYPE(thr, DUK_STR_PROXY_REVOKED);
- return 0;
- }
- DUK_ASSERT(DUK_TVAL_IS_OBJECT(tv_target));
- h_target = DUK_TVAL_GET_OBJECT(tv_target);
- DUK_ASSERT(h_target != NULL);
- *out_target = h_target;
- tv_target = NULL; /* avoid issues with relocation */
+ DUK_ASSERT(h_proxy->handler != NULL);
+ DUK_ASSERT(h_proxy->target != NULL);
+ *out_handler = h_proxy->handler;
+ *out_target = h_proxy->target;
return 1;
}
@@ -51994,25 +53486,21 @@ DUK_INTERNAL duk_bool_t duk_hobject_proxy_check(duk_hthread *thr, duk_hobject *o
* If a Proxy is revoked, an error is thrown.
*/
#if defined(DUK_USE_ES6_PROXY)
-DUK_INTERNAL duk_hobject *duk_hobject_resolve_proxy_target(duk_hthread *thr, duk_hobject *obj) {
- duk_hobject *h_target;
- duk_hobject *h_handler;
-
- DUK_ASSERT(thr != NULL);
+DUK_INTERNAL duk_hobject *duk_hobject_resolve_proxy_target(duk_hobject *obj) {
DUK_ASSERT(obj != NULL);
/* Resolve Proxy targets until Proxy chain ends. No explicit check for
- * a Proxy loop: user code cannot create such a loop without tweaking
- * internal properties directly.
+ * a Proxy loop: user code cannot create such a loop (it would only be
+ * possible by editing duk_hproxy references directly).
*/
- while (DUK_UNLIKELY(DUK_HOBJECT_HAS_EXOTIC_PROXYOBJ(obj))) {
- if (duk_hobject_proxy_check(thr, obj, &h_target, &h_handler)) {
- DUK_ASSERT(h_target != NULL);
- obj = h_target;
- } else {
- break;
- }
+ while (DUK_HOBJECT_IS_PROXY(obj)) {
+ duk_hproxy *h_proxy;
+
+ h_proxy = (duk_hproxy *) obj;
+ DUK_ASSERT_HPROXY_VALID(h_proxy);
+ obj = h_proxy->target;
+ DUK_ASSERT(obj != NULL);
}
DUK_ASSERT(obj != NULL);
@@ -52022,7 +53510,6 @@ DUK_INTERNAL duk_hobject *duk_hobject_resolve_proxy_target(duk_hthread *thr, duk
#if defined(DUK_USE_ES6_PROXY)
DUK_LOCAL duk_bool_t duk__proxy_check_prop(duk_hthread *thr, duk_hobject *obj, duk_small_uint_t stridx_trap, duk_tval *tv_key, duk_hobject **out_target) {
- duk_context *ctx = (duk_context *) thr;
duk_hobject *h_handler;
DUK_ASSERT(thr != NULL);
@@ -52030,7 +53517,7 @@ DUK_LOCAL duk_bool_t duk__proxy_check_prop(duk_hthread *thr, duk_hobject *obj, d
DUK_ASSERT(tv_key != NULL);
DUK_ASSERT(out_target != NULL);
- if (!duk_hobject_proxy_check(thr, obj, out_target, &h_handler)) {
+ if (!duk_hobject_proxy_check(obj, out_target, &h_handler)) {
return 0;
}
DUK_ASSERT(*out_target != NULL);
@@ -52072,16 +53559,16 @@ DUK_LOCAL duk_bool_t duk__proxy_check_prop(duk_hthread *thr, duk_hobject *obj, d
/* XXX: C recursion limit if proxies are allowed as handler/target values */
- duk_require_stack(ctx, DUK__VALSTACK_PROXY_LOOKUP);
- duk_push_hobject(ctx, h_handler);
- if (duk_get_prop_stridx_short(ctx, -1, stridx_trap)) {
+ duk_require_stack(thr, DUK__VALSTACK_PROXY_LOOKUP);
+ duk_push_hobject(thr, h_handler);
+ if (duk_get_prop_stridx_short(thr, -1, stridx_trap)) {
/* -> [ ... handler trap ] */
- duk_insert(ctx, -2); /* -> [ ... trap handler ] */
+ duk_insert(thr, -2); /* -> [ ... trap handler ] */
/* stack prepped for func call: [ ... trap handler ] */
return 1;
} else {
- duk_pop_2(ctx);
+ duk_pop_2_unsafe(thr);
return 0;
}
}
@@ -52122,7 +53609,6 @@ DUK_INTERNAL void duk_hobject_realloc_props(duk_hthread *thr,
duk_uint32_t new_a_size,
duk_uint32_t new_h_size,
duk_bool_t abandon_array) {
- duk_context *ctx = (duk_context *) thr;
duk_small_uint_t prev_ms_base_flags;
duk_uint32_t new_alloc_size;
duk_uint32_t new_e_size_adjusted;
@@ -52140,7 +53626,6 @@ DUK_INTERNAL void duk_hobject_realloc_props(duk_hthread *thr,
#endif
DUK_ASSERT(thr != NULL);
- DUK_ASSERT(ctx != NULL);
DUK_ASSERT(obj != NULL);
DUK_ASSERT(!abandon_array || new_a_size == 0); /* if abandon_array, new_a_size must be 0 */
DUK_ASSERT(DUK_HOBJECT_GET_PROPS(thr->heap, obj) != NULL || (DUK_HOBJECT_GET_ESIZE(obj) == 0 && DUK_HOBJECT_GET_ASIZE(obj) == 0));
@@ -52150,6 +53635,8 @@ DUK_INTERNAL void duk_hobject_realloc_props(duk_hthread *thr,
DUK_ASSERT(!DUK_HEAPHDR_HAS_READONLY((duk_heaphdr *) obj));
DUK_ASSERT_VALSTACK_SPACE(thr, DUK__VALSTACK_SPACE);
+ DUK_STATS_INC(thr->heap, stats_object_realloc_props);
+
/*
* Pre resize assertions.
*/
@@ -52174,7 +53661,8 @@ DUK_INTERNAL void duk_hobject_realloc_props(duk_hthread *thr,
DUK_DDD(DUK_DDDPRINT("using layout 1, but no need to pad e_size: %ld", (long) new_e_size));
new_e_size_adjusted = new_e_size;
#elif defined(DUK_USE_HOBJECT_LAYOUT_1) && ((DUK_HOBJECT_ALIGN_TARGET == 4) || (DUK_HOBJECT_ALIGN_TARGET == 8))
- new_e_size_adjusted = (new_e_size + DUK_HOBJECT_ALIGN_TARGET - 1) & (~(DUK_HOBJECT_ALIGN_TARGET - 1));
+ new_e_size_adjusted = (new_e_size + (duk_uint32_t) DUK_HOBJECT_ALIGN_TARGET - 1U) &
+ (~((duk_uint32_t) DUK_HOBJECT_ALIGN_TARGET - 1U));
DUK_DDD(DUK_DDDPRINT("using layout 1, and alignment target is %ld, adjusted e_size: %ld -> %ld",
(long) DUK_HOBJECT_ALIGN_TARGET, (long) new_e_size, (long) new_e_size_adjusted));
DUK_ASSERT(new_e_size_adjusted >= new_e_size);
@@ -52251,6 +53739,7 @@ DUK_INTERNAL void duk_hobject_realloc_props(duk_hthread *thr,
*/
#if 0 /* XXX: inject test */
if (1) {
+ new_p = NULL;
goto alloc_failed;
}
#endif
@@ -52305,6 +53794,8 @@ DUK_INTERNAL void duk_hobject_realloc_props(duk_hthread *thr,
*/
DUK_ASSERT(new_a_size == 0);
+ DUK_STATS_INC(thr->heap, stats_object_abandon_array);
+
for (i = 0; i < DUK_HOBJECT_GET_ASIZE(obj); i++) {
duk_tval *tv1;
duk_tval *tv2;
@@ -52338,15 +53829,15 @@ DUK_INTERNAL void duk_hobject_realloc_props(duk_hthread *thr,
/* Never shrinks; auto-adds DUK_VALSTACK_INTERNAL_EXTRA, which
* is generous.
*/
- if (!duk_check_stack(ctx, 1)) {
+ if (!duk_check_stack(thr, 1)) {
goto abandon_error;
}
DUK_ASSERT_VALSTACK_SPACE(thr, 1);
- key = duk_heap_strtable_intern_u32(thr->heap, i);
+ key = duk_heap_strtable_intern_u32(thr->heap, (duk_uint32_t) i);
if (key == NULL) {
goto abandon_error;
}
- duk_push_hstring(ctx, key); /* keep key reachable for GC etc; guaranteed not to fail */
+ duk_push_hstring(thr, key); /* keep key reachable for GC etc; guaranteed not to fail */
/* Key is now reachable in the valstack, don't INCREF
* the new allocation yet (we'll steal the refcounts
@@ -52368,7 +53859,7 @@ DUK_INTERNAL void duk_hobject_realloc_props(duk_hthread *thr,
/* Steal refcounts from value stack. */
DUK_DDD(DUK_DDDPRINT("abandon array: pop %ld key temps from valstack", (long) new_e_next));
- duk_pop_n_nodecref_unsafe(ctx, new_e_next);
+ duk_pop_n_nodecref_unsafe(thr, (duk_idx_t) new_e_next);
}
/*
@@ -52451,7 +53942,6 @@ DUK_INTERNAL void duk_hobject_realloc_props(duk_hthread *thr,
DUK_ASSERT(new_h != NULL);
/* fill new_h with u32 0xff = UNUSED */
- DUK_ASSERT(DUK_HOBJECT_GET_PROPS(thr->heap, obj) != NULL);
DUK_ASSERT(new_h_size > 0);
DUK_MEMSET(new_h, 0xff, sizeof(duk_uint32_t) * new_h_size);
@@ -52470,7 +53960,7 @@ DUK_INTERNAL void duk_hobject_realloc_props(duk_hthread *thr,
DUK_ASSERT(new_h[j] != DUK__HASH_DELETED); /* should never happen */
if (new_h[j] == DUK__HASH_UNUSED) {
DUK_DDD(DUK_DDDPRINT("rebuild hit %ld -> %ld", (long) j, (long) i));
- new_h[j] = i;
+ new_h[j] = (duk_uint32_t) i;
break;
}
DUK_DDD(DUK_DDDPRINT("rebuild miss %ld, step %ld", (long) j, (long) step));
@@ -52510,7 +54000,7 @@ DUK_INTERNAL void duk_hobject_realloc_props(duk_hthread *thr,
* All done, switch properties ('p') allocation to new one.
*/
- DUK_FREE(thr->heap, DUK_HOBJECT_GET_PROPS(thr->heap, obj)); /* NULL obj->p is OK */
+ DUK_FREE_CHECKED(thr, DUK_HOBJECT_GET_PROPS(thr->heap, obj)); /* NULL obj->p is OK */
DUK_HOBJECT_SET_PROPS(thr->heap, obj, new_p);
DUK_HOBJECT_SET_ESIZE(obj, new_e_size_adjusted);
DUK_HOBJECT_SET_ENEXT(obj, new_e_next);
@@ -52553,7 +54043,7 @@ DUK_INTERNAL void duk_hobject_realloc_props(duk_hthread *thr,
alloc_failed:
DUK_D(DUK_DPRINT("object property table resize failed"));
- DUK_FREE(thr->heap, new_p); /* OK for NULL. */
+ DUK_FREE_CHECKED(thr, new_p); /* OK for NULL. */
thr->heap->pf_prevent_count--;
thr->heap->ms_base_flags = prev_ms_base_flags;
@@ -52569,6 +54059,55 @@ DUK_INTERNAL void duk_hobject_realloc_props(duk_hthread *thr,
* Helpers to resize properties allocation on specific needs.
*/
+DUK_INTERNAL void duk_hobject_resize_entrypart(duk_hthread *thr,
+ duk_hobject *obj,
+ duk_uint32_t new_e_size) {
+ duk_uint32_t old_e_size;
+ duk_uint32_t new_a_size;
+ duk_uint32_t new_h_size;
+
+ DUK_ASSERT(thr != NULL);
+ DUK_ASSERT(obj != NULL);
+
+ old_e_size = DUK_HOBJECT_GET_ESIZE(obj);
+ if (old_e_size > new_e_size) {
+ new_e_size = old_e_size;
+ }
+#if defined(DUK_USE_HOBJECT_HASH_PART)
+ new_h_size = duk__get_default_h_size(new_e_size);
+#else
+ new_h_size = 0;
+#endif
+ new_a_size = DUK_HOBJECT_GET_ASIZE(obj);
+
+ duk_hobject_realloc_props(thr, obj, new_e_size, new_a_size, new_h_size, 0);
+}
+
+#if 0 /*unused */
+DUK_INTERNAL void duk_hobject_resize_arraypart(duk_hthread *thr,
+ duk_hobject *obj,
+ duk_uint32_t new_a_size) {
+ duk_uint32_t old_a_size;
+ duk_uint32_t new_e_size;
+ duk_uint32_t new_h_size;
+
+ DUK_ASSERT(thr != NULL);
+ DUK_ASSERT(obj != NULL);
+
+ if (!DUK_HOBJECT_HAS_ARRAY_PART(obj)) {
+ return;
+ }
+ old_a_size = DUK_HOBJECT_GET_ASIZE(obj);
+ if (old_a_size > new_a_size) {
+ new_a_size = old_a_size;
+ }
+ new_e_size = DUK_HOBJECT_GET_ESIZE(obj);
+ new_h_size = DUK_HOBJECT_GET_HSIZE(obj);
+
+ duk_hobject_realloc_props(thr, obj, new_e_size, new_a_size, new_h_size, 0);
+}
+#endif
+
/* Grow entry part allocation for one additional entry. */
DUK_LOCAL void duk__grow_props_for_new_entry_item(duk_hthread *thr, duk_hobject *obj) {
duk_uint32_t old_e_used; /* actually used, non-NULL entries */
@@ -52737,7 +54276,7 @@ DUK_INTERNAL void duk_hobject_compact_props(duk_hthread *thr, duk_hobject *obj)
* but there is no hash part, h_idx is set to -1.
*/
-DUK_INTERNAL void duk_hobject_find_existing_entry(duk_heap *heap, duk_hobject *obj, duk_hstring *key, duk_int_t *e_idx, duk_int_t *h_idx) {
+DUK_INTERNAL duk_bool_t duk_hobject_find_existing_entry(duk_heap *heap, duk_hobject *obj, duk_hstring *key, duk_int_t *e_idx, duk_int_t *h_idx) {
DUK_ASSERT(obj != NULL);
DUK_ASSERT(key != NULL);
DUK_ASSERT(e_idx != NULL);
@@ -52760,9 +54299,9 @@ DUK_INTERNAL void duk_hobject_find_existing_entry(duk_heap *heap, duk_hobject *o
n = DUK_HOBJECT_GET_ENEXT(obj);
for (i = 0; i < n; i++) {
if (h_keys_base[i] == key) {
- *e_idx = i;
+ *e_idx = (duk_int_t) i;
*h_idx = -1;
- return;
+ return 1;
}
}
}
@@ -52802,9 +54341,9 @@ DUK_INTERNAL void duk_hobject_find_existing_entry(duk_heap *heap, duk_hobject *o
if (DUK_HOBJECT_E_GET_KEY(heap, obj, t) == key) {
DUK_DDD(DUK_DDDPRINT("lookup hit i=%ld, t=%ld -> key %p",
(long) i, (long) t, (void *) key));
- *e_idx = t;
- *h_idx = i;
- return;
+ *e_idx = (duk_int_t) t;
+ *h_idx = (duk_int_t) i;
+ return 1;
}
DUK_DDD(DUK_DDDPRINT("lookup miss i=%ld, t=%ld",
(long) i, (long) t));
@@ -52816,9 +54355,8 @@ DUK_INTERNAL void duk_hobject_find_existing_entry(duk_heap *heap, duk_hobject *o
}
#endif /* DUK_USE_HOBJECT_HASH_PART */
- /* not found */
- *e_idx = -1;
- *h_idx = -1;
+ /* Not found, leave e_idx and h_idx unset. */
+ return 0;
}
/* For internal use: get non-accessor entry value */
@@ -52830,16 +54368,17 @@ DUK_INTERNAL duk_tval *duk_hobject_find_existing_entry_tval_ptr(duk_heap *heap,
DUK_ASSERT(key != NULL);
DUK_UNREF(heap);
- duk_hobject_find_existing_entry(heap, obj, key, &e_idx, &h_idx);
- if (e_idx >= 0 && !DUK_HOBJECT_E_SLOT_IS_ACCESSOR(heap, obj, e_idx)) {
- return DUK_HOBJECT_E_GET_VALUE_TVAL_PTR(heap, obj, e_idx);
- } else {
- return NULL;
+ if (duk_hobject_find_existing_entry(heap, obj, key, &e_idx, &h_idx)) {
+ DUK_ASSERT(e_idx >= 0);
+ if (!DUK_HOBJECT_E_SLOT_IS_ACCESSOR(heap, obj, e_idx)) {
+ return DUK_HOBJECT_E_GET_VALUE_TVAL_PTR(heap, obj, e_idx);
+ }
}
+ return NULL;
}
/* For internal use: get non-accessor entry value and attributes */
-DUK_INTERNAL duk_tval *duk_hobject_find_existing_entry_tval_ptr_and_attrs(duk_heap *heap, duk_hobject *obj, duk_hstring *key, duk_int_t *out_attrs) {
+DUK_INTERNAL duk_tval *duk_hobject_find_existing_entry_tval_ptr_and_attrs(duk_heap *heap, duk_hobject *obj, duk_hstring *key, duk_uint_t *out_attrs) {
duk_int_t e_idx;
duk_int_t h_idx;
@@ -52848,14 +54387,15 @@ DUK_INTERNAL duk_tval *duk_hobject_find_existing_entry_tval_ptr_and_attrs(duk_he
DUK_ASSERT(out_attrs != NULL);
DUK_UNREF(heap);
- duk_hobject_find_existing_entry(heap, obj, key, &e_idx, &h_idx);
- if (e_idx >= 0 && !DUK_HOBJECT_E_SLOT_IS_ACCESSOR(heap, obj, e_idx)) {
- *out_attrs = DUK_HOBJECT_E_GET_FLAGS(heap, obj, e_idx);
- return DUK_HOBJECT_E_GET_VALUE_TVAL_PTR(heap, obj, e_idx);
- } else {
- *out_attrs = 0;
- return NULL;
+ if (duk_hobject_find_existing_entry(heap, obj, key, &e_idx, &h_idx)) {
+ DUK_ASSERT(e_idx >= 0);
+ if (!DUK_HOBJECT_E_SLOT_IS_ACCESSOR(heap, obj, e_idx)) {
+ *out_attrs = DUK_HOBJECT_E_GET_FLAGS(heap, obj, e_idx);
+ return DUK_HOBJECT_E_GET_VALUE_TVAL_PTR(heap, obj, e_idx);
+ }
}
+ /* If not found, out_attrs is left unset. */
+ return NULL;
}
/* For internal use: get array part value */
@@ -52884,7 +54424,7 @@ DUK_INTERNAL duk_tval *duk_hobject_find_existing_array_entry_tval_ptr(duk_heap *
* the entry value refcount. A decref for the previous value is not necessary.
*/
-DUK_LOCAL duk_bool_t duk__alloc_entry_checked(duk_hthread *thr, duk_hobject *obj, duk_hstring *key) {
+DUK_LOCAL duk_int_t duk__hobject_alloc_entry_checked(duk_hthread *thr, duk_hobject *obj, duk_hstring *key) {
duk_uint32_t idx;
DUK_ASSERT(thr != NULL);
@@ -52928,7 +54468,7 @@ DUK_LOCAL duk_bool_t duk__alloc_entry_checked(duk_hthread *thr, duk_hobject *obj
for (;;) {
duk_uint32_t t = h_base[i];
if (t == DUK__HASH_UNUSED || t == DUK__HASH_DELETED) {
- DUK_DDD(DUK_DDDPRINT("duk__alloc_entry_checked() inserted key into hash part, %ld -> %ld",
+ DUK_DDD(DUK_DDDPRINT("duk__hobject_alloc_entry_checked() inserted key into hash part, %ld -> %ld",
(long) i, (long) idx));
DUK_ASSERT_DISABLE(i >= 0); /* unsigned */
DUK_ASSERT(i < DUK_HOBJECT_GET_HSIZE(obj));
@@ -52937,7 +54477,7 @@ DUK_LOCAL duk_bool_t duk__alloc_entry_checked(duk_hthread *thr, duk_hobject *obj
h_base[i] = idx;
break;
}
- DUK_DDD(DUK_DDDPRINT("duk__alloc_entry_checked() miss %ld", (long) i));
+ DUK_DDD(DUK_DDDPRINT("duk__hobject_alloc_entry_checked() miss %ld", (long) i));
i = (i + step) & mask;
/* Guaranteed to finish (hash is larger than #props). */
@@ -52952,7 +54492,7 @@ DUK_LOCAL duk_bool_t duk__alloc_entry_checked(duk_hthread *thr, duk_hobject *obj
DUK_ASSERT_DISABLE(idx >= 0);
DUK_ASSERT(idx < DUK_HOBJECT_GET_ESIZE(obj));
DUK_ASSERT(idx < DUK_HOBJECT_GET_ENEXT(obj));
- return idx;
+ return (duk_int_t) idx;
}
/*
@@ -52970,9 +54510,9 @@ DUK_INTERNAL duk_bool_t duk_hobject_get_internal_value(duk_heap *heap, duk_hobje
DUK_ASSERT(obj != NULL);
DUK_ASSERT(tv_out != NULL);
- /* 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) {
+ /* Always in entry part, no need to look up parents etc. */
+ if (duk_hobject_find_existing_entry(heap, obj, DUK_HEAP_STRING_INT_VALUE(heap), &e_idx, &h_idx)) {
+ DUK_ASSERT(e_idx >= 0);
DUK_ASSERT(!DUK_HOBJECT_E_SLOT_IS_ACCESSOR(heap, obj, e_idx));
DUK_TVAL_SET_TVAL(tv_out, DUK_HOBJECT_E_GET_VALUE_TVAL_PTR(heap, obj, e_idx));
return 1;
@@ -53023,7 +54563,6 @@ duk_bool_t duk__lookup_arguments_map(duk_hthread *thr,
duk_propdesc *temp_desc,
duk_hobject **out_map,
duk_hobject **out_varenv) {
- duk_context *ctx = (duk_context *) thr;
duk_hobject *map;
duk_hobject *varenv;
duk_bool_t rc;
@@ -53040,9 +54579,9 @@ duk_bool_t duk__lookup_arguments_map(duk_hthread *thr,
return 0;
}
- map = duk_require_hobject(ctx, -1);
+ map = duk_require_hobject(thr, -1);
DUK_ASSERT(map != NULL);
- duk_pop(ctx); /* map is reachable through obj */
+ duk_pop_unsafe(thr); /* map is reachable through obj */
if (!duk_hobject_get_own_propdesc(thr, map, key, temp_desc, DUK_GETDESC_FLAG_PUSH_VALUE)) {
DUK_DDD(DUK_DDDPRINT("-> 'map' exists, but key not in map"));
@@ -53051,16 +54590,16 @@ duk_bool_t duk__lookup_arguments_map(duk_hthread *thr,
/* [... varname] */
DUK_DDD(DUK_DDDPRINT("-> 'map' exists, and contains key, key is mapped to argument/variable binding %!T",
- (duk_tval *) duk_get_tval(ctx, -1)));
- DUK_ASSERT(duk_is_string(ctx, -1)); /* guaranteed when building arguments */
+ (duk_tval *) duk_get_tval(thr, -1)));
+ DUK_ASSERT(duk_is_string(thr, -1)); /* guaranteed when building arguments */
/* get varenv for varname (callee's declarative lexical environment) */
rc = duk_hobject_get_own_propdesc(thr, obj, DUK_HTHREAD_STRING_INT_VARENV(thr), temp_desc, DUK_GETDESC_FLAG_PUSH_VALUE);
DUK_UNREF(rc);
DUK_ASSERT(rc != 0); /* arguments MUST have an initialized lexical environment reference */
- varenv = duk_require_hobject(ctx, -1);
+ varenv = duk_require_hobject(thr, -1);
DUK_ASSERT(varenv != NULL);
- duk_pop(ctx); /* varenv remains reachable through 'obj' */
+ duk_pop_unsafe(thr); /* varenv remains reachable through 'obj' */
DUK_DDD(DUK_DDDPRINT("arguments varenv is: %!dO", (duk_heaphdr *) varenv));
@@ -53075,7 +54614,6 @@ duk_bool_t duk__lookup_arguments_map(duk_hthread *thr,
* Used in E5 Section 10.6 algorithm for [[GetOwnProperty]] (used by [[Get]]).
*/
DUK_LOCAL duk_bool_t duk__check_arguments_map_for_get(duk_hthread *thr, duk_hobject *obj, duk_hstring *key, duk_propdesc *temp_desc) {
- duk_context *ctx = (duk_context *) thr;
duk_hobject *map;
duk_hobject *varenv;
duk_hstring *varname;
@@ -53089,9 +54627,9 @@ DUK_LOCAL duk_bool_t duk__check_arguments_map_for_get(duk_hthread *thr, duk_hobj
/* [... varname] */
- varname = duk_require_hstring(ctx, -1);
+ varname = duk_require_hstring(thr, -1);
DUK_ASSERT(varname != NULL);
- duk_pop(ctx); /* varname is still reachable */
+ duk_pop_unsafe(thr); /* varname is still reachable */
DUK_DDD(DUK_DDDPRINT("arguments object automatic getvar for a bound variable; "
"key=%!O, varname=%!O",
@@ -53102,7 +54640,7 @@ DUK_LOCAL duk_bool_t duk__check_arguments_map_for_get(duk_hthread *thr, duk_hobj
/* [... value this_binding] */
- duk_pop(ctx);
+ duk_pop_unsafe(thr);
/* leave result on stack top */
return 1;
@@ -53113,7 +54651,6 @@ DUK_LOCAL duk_bool_t duk__check_arguments_map_for_get(duk_hthread *thr, duk_hobj
* Assumes stack top contains 'put' value (which is NOT popped).
*/
DUK_LOCAL void duk__check_arguments_map_for_put(duk_hthread *thr, duk_hobject *obj, duk_hstring *key, duk_propdesc *temp_desc, duk_bool_t throw_flag) {
- duk_context *ctx = (duk_context *) thr;
duk_hobject *map;
duk_hobject *varenv;
duk_hstring *varname;
@@ -53127,15 +54664,15 @@ DUK_LOCAL void duk__check_arguments_map_for_put(duk_hthread *thr, duk_hobject *o
/* [... put_value varname] */
- varname = duk_require_hstring(ctx, -1);
+ varname = duk_require_hstring(thr, -1);
DUK_ASSERT(varname != NULL);
- duk_pop(ctx); /* varname is still reachable */
+ duk_pop_unsafe(thr); /* varname is still reachable */
DUK_DDD(DUK_DDDPRINT("arguments object automatic putvar for a bound variable; "
"key=%!O, varname=%!O, value=%!T",
(duk_heaphdr *) key,
(duk_heaphdr *) varname,
- (duk_tval *) duk_require_tval(ctx, -1)));
+ (duk_tval *) duk_require_tval(thr, -1)));
/* [... put_value] */
@@ -53147,7 +54684,7 @@ DUK_LOCAL void duk__check_arguments_map_for_put(duk_hthread *thr, duk_hobject *o
* the property write call.
*/
- duk_js_putvar_envrec(thr, varenv, varname, duk_require_tval(ctx, -1), throw_flag);
+ duk_js_putvar_envrec(thr, varenv, varname, duk_require_tval(thr, -1), throw_flag);
/* [... put_value] */
}
@@ -53157,7 +54694,6 @@ DUK_LOCAL void duk__check_arguments_map_for_put(duk_hthread *thr, duk_hobject *o
* variable/argument itself (where the map points) is not deleted.
*/
DUK_LOCAL void duk__check_arguments_map_for_delete(duk_hthread *thr, duk_hobject *obj, duk_hstring *key, duk_propdesc *temp_desc) {
- duk_context *ctx = (duk_context *) thr;
duk_hobject *map;
DUK_ASSERT_VALSTACK_SPACE(thr, DUK__VALSTACK_SPACE);
@@ -53167,9 +54703,9 @@ DUK_LOCAL void duk__check_arguments_map_for_delete(duk_hthread *thr, duk_hobject
return;
}
- map = duk_require_hobject(ctx, -1);
+ map = duk_require_hobject(thr, -1);
DUK_ASSERT(map != NULL);
- duk_pop(ctx); /* map is reachable through obj */
+ duk_pop_unsafe(thr); /* map is reachable through obj */
DUK_DDD(DUK_DDDPRINT("-> have 'map', delete key %!O from map (if exists)); ignore result",
(duk_heaphdr *) key));
@@ -53221,7 +54757,6 @@ DUK_LOCAL void duk__check_arguments_map_for_delete(duk_hthread *thr, duk_hobject
*/
DUK_LOCAL duk_bool_t duk__get_own_propdesc_raw(duk_hthread *thr, duk_hobject *obj, duk_hstring *key, duk_uint32_t arr_idx, duk_propdesc *out_desc, duk_small_uint_t flags) {
- duk_context *ctx = (duk_context *) thr;
duk_tval *tv;
DUK_DDD(DUK_DDDPRINT("duk_hobject_get_own_propdesc: thr=%p, obj=%p, key=%p, out_desc=%p, flags=%lx, "
@@ -53230,7 +54765,6 @@ DUK_LOCAL duk_bool_t duk__get_own_propdesc_raw(duk_hthread *thr, duk_hobject *ob
(long) flags, (long) arr_idx,
(duk_heaphdr *) obj, (duk_heaphdr *) key));
- DUK_ASSERT(ctx != NULL);
DUK_ASSERT(thr != NULL);
DUK_ASSERT(thr->heap != NULL);
DUK_ASSERT(obj != NULL);
@@ -53238,51 +54772,39 @@ DUK_LOCAL duk_bool_t duk__get_own_propdesc_raw(duk_hthread *thr, duk_hobject *ob
DUK_ASSERT(out_desc != NULL);
DUK_ASSERT_VALSTACK_SPACE(thr, DUK__VALSTACK_SPACE);
- /* XXX: optimize this filling behavior later */
+ DUK_STATS_INC(thr->heap, stats_getownpropdesc_count);
+
+ /* Each code path returning 1 (= found) must fill in all the output
+ * descriptor fields. We don't do it beforehand because it'd be
+ * unnecessary work if the property isn't found and would happen
+ * multiple times for an inheritance chain.
+ */
+ DUK_ASSERT_SET_GARBAGE(out_desc, sizeof(*out_desc));
+#if 0
out_desc->flags = 0;
out_desc->get = NULL;
out_desc->set = NULL;
out_desc->e_idx = -1;
out_desc->h_idx = -1;
out_desc->a_idx = -1;
+#endif
/*
- * Array part
- */
-
- 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_UNUSED(tv)) {
- DUK_DDD(DUK_DDDPRINT("-> found in array part"));
- if (flags & DUK_GETDESC_FLAG_PUSH_VALUE) {
- duk_push_tval(ctx, tv);
- }
- /* implicit attributes */
- out_desc->flags = DUK_PROPDESC_FLAG_WRITABLE |
- DUK_PROPDESC_FLAG_CONFIGURABLE |
- DUK_PROPDESC_FLAG_ENUMERABLE;
- out_desc->a_idx = arr_idx;
- goto prop_found;
- }
- }
- /* assume array part is comprehensive (contains all array indexed elements
- * or none of them); hence no need to check the entries part here.
- */
- DUK_DDD(DUK_DDDPRINT("-> not found as a concrete property (has array part, "
- "should be there if present)"));
- goto prop_not_found_concrete;
- }
-
- /*
- * Entries part
+ * Try entries part first because it's the common case.
+ *
+ * Array part lookups are usually handled by the array fast path, and
+ * are not usually inherited. Array and entry parts never contain the
+ * same keys so the entry part vs. array part order doesn't matter.
*/
- duk_hobject_find_existing_entry(thr->heap, obj, key, &out_desc->e_idx, &out_desc->h_idx);
- if (out_desc->e_idx >= 0) {
+ if (duk_hobject_find_existing_entry(thr->heap, obj, key, &out_desc->e_idx, &out_desc->h_idx)) {
duk_int_t e_idx = out_desc->e_idx;
+ DUK_ASSERT(out_desc->e_idx >= 0);
+ out_desc->a_idx = -1;
out_desc->flags = DUK_HOBJECT_E_GET_FLAGS(thr->heap, obj, e_idx);
- if (out_desc->flags & DUK_PROPDESC_FLAG_ACCESSOR) {
+ out_desc->get = NULL;
+ out_desc->set = NULL;
+ if (DUK_UNLIKELY(out_desc->flags & DUK_PROPDESC_FLAG_ACCESSOR)) {
DUK_DDD(DUK_DDDPRINT("-> found accessor property in entry part"));
out_desc->get = DUK_HOBJECT_E_GET_VALUE_GETTER(thr->heap, obj, e_idx);
out_desc->set = DUK_HOBJECT_E_GET_VALUE_SETTER(thr->heap, obj, e_idx);
@@ -53290,23 +54812,49 @@ DUK_LOCAL duk_bool_t duk__get_own_propdesc_raw(duk_hthread *thr, duk_hobject *ob
/* a dummy undefined value is pushed to make valstack
* behavior uniform for caller
*/
- duk_push_undefined(ctx);
+ duk_push_undefined(thr);
}
} else {
DUK_DDD(DUK_DDDPRINT("-> found plain property in entry part"));
tv = DUK_HOBJECT_E_GET_VALUE_TVAL_PTR(thr->heap, obj, e_idx);
if (flags & DUK_GETDESC_FLAG_PUSH_VALUE) {
- duk_push_tval(ctx, tv);
+ duk_push_tval(thr, tv);
}
}
goto prop_found;
}
/*
- * Not found as a concrete property, check for virtual properties.
+ * Try array part.
*/
- prop_not_found_concrete:
+ 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_UNUSED(tv)) {
+ DUK_DDD(DUK_DDDPRINT("-> found in array part"));
+ if (flags & DUK_GETDESC_FLAG_PUSH_VALUE) {
+ duk_push_tval(thr, tv);
+ }
+ /* implicit attributes */
+ out_desc->flags = DUK_PROPDESC_FLAG_WRITABLE |
+ DUK_PROPDESC_FLAG_CONFIGURABLE |
+ DUK_PROPDESC_FLAG_ENUMERABLE;
+ out_desc->get = NULL;
+ out_desc->set = NULL;
+ out_desc->e_idx = -1;
+ out_desc->h_idx = -1;
+ out_desc->a_idx = (duk_int_t) arr_idx; /* XXX: limit 2G due to being signed */
+ goto prop_found;
+ }
+ }
+ }
+
+ DUK_DDD(DUK_DDDPRINT("-> not found as a concrete property"));
+
+ /*
+ * Not found as a concrete property, check for virtual properties.
+ */
if (!DUK_HOBJECT_HAS_VIRTUAL_PROPERTIES(obj)) {
/* Quick skip. */
@@ -53326,15 +54874,20 @@ DUK_LOCAL duk_bool_t duk__get_own_propdesc_raw(duk_hthread *thr, duk_hobject *ob
DUK_DDD(DUK_DDDPRINT("-> found, key is 'length', length exotic behavior"));
if (flags & DUK_GETDESC_FLAG_PUSH_VALUE) {
- duk_push_uint(ctx, (duk_uint_t) a->length);
+ duk_push_uint(thr, (duk_uint_t) a->length);
}
out_desc->flags = DUK_PROPDESC_FLAG_VIRTUAL;
if (DUK_HARRAY_LENGTH_WRITABLE(a)) {
out_desc->flags |= DUK_PROPDESC_FLAG_WRITABLE;
}
+ out_desc->get = NULL;
+ out_desc->set = NULL;
+ out_desc->e_idx = -1;
+ out_desc->h_idx = -1;
+ out_desc->a_idx = -1;
DUK_ASSERT(!DUK_HOBJECT_HAS_EXOTIC_ARGUMENTS(obj));
- return 1; /* cannot be arguments exotic */
+ goto prop_found_noexotic; /* cannot be arguments exotic */
}
} else if (DUK_HOBJECT_HAS_EXOTIC_STRINGOBJ(obj)) {
DUK_DDD(DUK_DDDPRINT("string object exotic property get for key: %!O, arr_idx: %ld",
@@ -53352,14 +54905,19 @@ DUK_LOCAL duk_bool_t duk__get_own_propdesc_raw(duk_hthread *thr, duk_hobject *ob
if (arr_idx < DUK_HSTRING_GET_CHARLEN(h_val)) {
DUK_DDD(DUK_DDDPRINT("-> found, array index inside string"));
if (flags & DUK_GETDESC_FLAG_PUSH_VALUE) {
- duk_push_hstring(ctx, h_val);
- duk_substring(ctx, -1, arr_idx, arr_idx + 1); /* [str] -> [substr] */
+ duk_push_hstring(thr, h_val);
+ duk_substring(thr, -1, arr_idx, arr_idx + 1); /* [str] -> [substr] */
}
out_desc->flags = DUK_PROPDESC_FLAG_ENUMERABLE | /* E5 Section 15.5.5.2 */
DUK_PROPDESC_FLAG_VIRTUAL;
+ out_desc->get = NULL;
+ out_desc->set = NULL;
+ out_desc->e_idx = -1;
+ out_desc->h_idx = -1;
+ out_desc->a_idx = -1;
DUK_ASSERT(!DUK_HOBJECT_HAS_EXOTIC_ARGUMENTS(obj));
- return 1; /* cannot be e.g. arguments exotic, since exotic 'traits' are mutually exclusive */
+ goto prop_found_noexotic; /* cannot be arguments exotic */
} else {
/* index is above internal string length -> property is fully normal */
DUK_DDD(DUK_DDDPRINT("array index outside string -> normal property"));
@@ -53372,12 +54930,17 @@ DUK_LOCAL duk_bool_t duk__get_own_propdesc_raw(duk_hthread *thr, duk_hobject *ob
h_val = duk_hobject_get_internal_value_string(thr->heap, obj);
DUK_ASSERT(h_val != NULL);
if (flags & DUK_GETDESC_FLAG_PUSH_VALUE) {
- duk_push_uint(ctx, (duk_uint_t) DUK_HSTRING_GET_CHARLEN(h_val));
+ duk_push_uint(thr, (duk_uint_t) DUK_HSTRING_GET_CHARLEN(h_val));
}
out_desc->flags = DUK_PROPDESC_FLAG_VIRTUAL; /* E5 Section 15.5.5.1 */
+ out_desc->get = NULL;
+ out_desc->set = NULL;
+ out_desc->e_idx = -1;
+ out_desc->h_idx = -1;
+ out_desc->a_idx = -1;
DUK_ASSERT(!DUK_HOBJECT_HAS_EXOTIC_ARGUMENTS(obj));
- return 1; /* cannot be arguments exotic */
+ goto prop_found_noexotic; /* cannot be arguments exotic */
}
}
#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)
@@ -53399,16 +54962,16 @@ DUK_LOCAL duk_bool_t duk__get_own_propdesc_raw(duk_hthread *thr, duk_hobject *ob
*/
if (arr_idx < (h_bufobj->length >> h_bufobj->shift)) {
byte_off = arr_idx << h_bufobj->shift; /* no wrap assuming h_bufobj->length is valid */
- elem_size = 1 << h_bufobj->shift;
+ elem_size = (duk_small_uint_t) (1U << h_bufobj->shift);
if (flags & DUK_GETDESC_FLAG_PUSH_VALUE) {
duk_uint8_t *data;
if (h_bufobj->buf != NULL && DUK_HBUFOBJ_VALID_BYTEOFFSET_EXCL(h_bufobj, byte_off + elem_size)) {
data = (duk_uint8_t *) DUK_HBUFFER_GET_DATA_PTR(thr->heap, h_bufobj->buf) + h_bufobj->offset + byte_off;
- duk_hbufobj_push_validated_read(ctx, h_bufobj, data, elem_size);
+ duk_hbufobj_push_validated_read(thr, h_bufobj, data, elem_size);
} else {
DUK_D(DUK_DPRINT("bufobj access out of underlying buffer, ignoring (read zero)"));
- duk_push_uint(ctx, 0);
+ duk_push_uint(thr, 0);
}
}
out_desc->flags = DUK_PROPDESC_FLAG_WRITABLE |
@@ -53419,9 +54982,14 @@ DUK_LOCAL duk_bool_t duk__get_own_propdesc_raw(duk_hthread *thr, duk_hobject *ob
*/
out_desc->flags |= DUK_PROPDESC_FLAG_ENUMERABLE;
}
+ out_desc->get = NULL;
+ out_desc->set = NULL;
+ out_desc->e_idx = -1;
+ out_desc->h_idx = -1;
+ out_desc->a_idx = -1;
DUK_ASSERT(!DUK_HOBJECT_HAS_EXOTIC_ARGUMENTS(obj));
- return 1; /* cannot be e.g. arguments exotic, since exotic 'traits' are mutually exclusive */
+ goto prop_found_noexotic; /* cannot be e.g. arguments exotic, since exotic 'traits' are mutually exclusive */
} else {
/* index is above internal buffer length -> property is fully normal */
DUK_DDD(DUK_DDDPRINT("array index outside buffer -> normal property"));
@@ -53433,32 +55001,20 @@ DUK_LOCAL duk_bool_t duk__get_own_propdesc_raw(duk_hthread *thr, duk_hobject *ob
/* Length in elements: take into account shift, but
* intentionally don't check the underlying buffer here.
*/
- duk_push_uint(ctx, h_bufobj->length >> h_bufobj->shift);
+ duk_push_uint(thr, h_bufobj->length >> h_bufobj->shift);
}
out_desc->flags = DUK_PROPDESC_FLAG_VIRTUAL;
+ out_desc->get = NULL;
+ out_desc->set = NULL;
+ out_desc->e_idx = -1;
+ out_desc->h_idx = -1;
+ out_desc->a_idx = -1;
DUK_ASSERT(!DUK_HOBJECT_HAS_EXOTIC_ARGUMENTS(obj));
- return 1; /* cannot be arguments exotic */
+ goto prop_found_noexotic; /* cannot be arguments exotic */
}
}
#endif /* DUK_USE_BUFFEROBJECT_SUPPORT */
- else if (DUK_HOBJECT_HAS_EXOTIC_DUKFUNC(obj)) {
- DUK_DDD(DUK_DDDPRINT("duktape/c object exotic property get for key: %!O, arr_idx: %ld",
- (duk_heaphdr *) key, (long) arr_idx));
-
- if (key == DUK_HTHREAD_STRING_LENGTH(thr)) {
- DUK_DDD(DUK_DDDPRINT("-> found, key is 'length', length exotic behavior"));
-
- if (flags & DUK_GETDESC_FLAG_PUSH_VALUE) {
- duk_int16_t func_nargs = ((duk_hnatfunc *) obj)->nargs;
- duk_push_int(ctx, func_nargs == DUK_HNATFUNC_NARGS_VARARGS ? 0 : func_nargs);
- }
- out_desc->flags = DUK_PROPDESC_FLAG_VIRTUAL; /* not enumerable */
-
- DUK_ASSERT(!DUK_HOBJECT_HAS_EXOTIC_ARGUMENTS(obj));
- return 1; /* cannot be arguments exotic */
- }
- }
/* Array properties have exotic behavior but they are concrete,
* so no special handling here.
@@ -53469,15 +55025,16 @@ DUK_LOCAL duk_bool_t duk__get_own_propdesc_raw(duk_hthread *thr, duk_hobject *ob
*/
/*
- * Not found as concrete or virtual
+ * Not found as concrete or virtual.
*/
prop_not_found:
DUK_DDD(DUK_DDDPRINT("-> not found (virtual, entry part, or array part)"));
+ DUK_STATS_INC(thr->heap, stats_getownpropdesc_miss);
return 0;
/*
- * Found
+ * Found.
*
* Arguments object has exotic post-processing, see E5 Section 10.6,
* description of [[GetOwnProperty]] variant for arguments.
@@ -53487,15 +55044,15 @@ DUK_LOCAL duk_bool_t duk__get_own_propdesc_raw(duk_hthread *thr, duk_hobject *ob
DUK_DDD(DUK_DDDPRINT("-> property found, checking for arguments exotic post-behavior"));
/* Notes:
- * - only numbered indices are relevant, so arr_idx fast reject is good
+ * - Only numbered indices are relevant, so arr_idx fast reject is good
* (this is valid unless there are more than 4**32-1 arguments).
- * - since variable lookup has no side effects, this can be skipped if
+ * - Since variable lookup has no side effects, this can be skipped if
* DUK_GETDESC_FLAG_PUSH_VALUE is not set.
*/
- if (DUK_HOBJECT_HAS_EXOTIC_ARGUMENTS(obj) &&
- arr_idx != DUK__NO_ARRAY_INDEX &&
- (flags & DUK_GETDESC_FLAG_PUSH_VALUE)) {
+ if (DUK_UNLIKELY(DUK_HOBJECT_HAS_EXOTIC_ARGUMENTS(obj) &&
+ arr_idx != DUK__NO_ARRAY_INDEX &&
+ (flags & DUK_GETDESC_FLAG_PUSH_VALUE))) {
duk_propdesc temp_desc;
/* Magically bound variable cannot be an accessor. However,
@@ -53513,13 +55070,15 @@ DUK_LOCAL duk_bool_t duk__get_own_propdesc_raw(duk_hthread *thr, duk_hobject *ob
*/
if (duk__check_arguments_map_for_get(thr, obj, key, &temp_desc)) {
DUK_DDD(DUK_DDDPRINT("-> arguments exotic behavior overrides result: %!T -> %!T",
- (duk_tval *) duk_get_tval(ctx, -2),
- (duk_tval *) duk_get_tval(ctx, -1)));
+ (duk_tval *) duk_get_tval(thr, -2),
+ (duk_tval *) duk_get_tval(thr, -1)));
/* [... old_result result] -> [... result] */
- duk_remove_m2(ctx);
+ duk_remove_m2(thr);
}
}
+ prop_found_noexotic:
+ DUK_STATS_INC(thr->heap, stats_getownpropdesc_hit);
return 1;
}
@@ -53564,6 +55123,8 @@ DUK_LOCAL duk_bool_t duk__get_propdesc(duk_hthread *thr, duk_hobject *obj, duk_h
DUK_ASSERT(out_desc != NULL);
DUK_ASSERT_VALSTACK_SPACE(thr, DUK__VALSTACK_SPACE);
+ DUK_STATS_INC(thr->heap, stats_getpropdesc_count);
+
arr_idx = DUK_HSTRING_GET_ARRIDX_FAST(key);
DUK_DDD(DUK_DDDPRINT("duk__get_propdesc: thr=%p, obj=%p, key=%p, out_desc=%p, flags=%lx, "
@@ -53578,6 +55139,7 @@ DUK_LOCAL duk_bool_t duk__get_propdesc(duk_hthread *thr, duk_hobject *obj, duk_h
do {
if (duk__get_own_propdesc_raw(thr, curr, key, arr_idx, out_desc, flags)) {
/* stack contains value (if requested), 'out_desc' is set */
+ DUK_STATS_INC(thr->heap, stats_getpropdesc_hit);
return 1;
}
@@ -53597,6 +55159,7 @@ DUK_LOCAL duk_bool_t duk__get_propdesc(duk_hthread *thr, duk_hobject *obj, duk_h
* value to determine whether out_desc can be looked up
*/
+ DUK_STATS_INC(thr->heap, stats_getpropdesc_miss);
return 0;
}
@@ -53631,7 +55194,7 @@ DUK_LOCAL duk_tval *duk__getprop_shallow_fastpath_array_tval(duk_hthread *thr, d
!DUK_HOBJECT_HAS_EXOTIC_ARGUMENTS(obj) &&
!DUK_HOBJECT_HAS_EXOTIC_STRINGOBJ(obj) &&
!DUK_HOBJECT_IS_BUFOBJ(obj) &&
- !DUK_HOBJECT_HAS_EXOTIC_PROXYOBJ(obj))) {
+ !DUK_HOBJECT_IS_PROXY(obj))) {
/* Must have array part and no conflicting exotic behaviors.
* Doesn't need to have array special behavior, e.g. Arguments
* object has array part.
@@ -53754,15 +55317,12 @@ DUK_LOCAL duk_bool_t duk__putprop_shallow_fastpath_array_tval(duk_hthread *thr,
#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)
DUK_LOCAL duk_bool_t duk__getprop_fastpath_bufobj_tval(duk_hthread *thr, duk_hobject *obj, duk_tval *tv_key) {
- duk_context *ctx;
duk_uint32_t idx;
duk_hbufobj *h_bufobj;
duk_uint_t byte_off;
duk_small_uint_t elem_size;
duk_uint8_t *data;
- ctx = (duk_context *) thr;
-
if (!DUK_HOBJECT_IS_BUFOBJ(obj)) {
return 0;
}
@@ -53794,14 +55354,14 @@ DUK_LOCAL duk_bool_t duk__getprop_fastpath_bufobj_tval(duk_hthread *thr, duk_hob
DUK_ASSERT(idx != DUK__NO_ARRAY_INDEX);
byte_off = idx << h_bufobj->shift; /* no wrap assuming h_bufobj->length is valid */
- elem_size = 1 << h_bufobj->shift;
+ elem_size = (duk_small_uint_t) (1U << h_bufobj->shift);
if (h_bufobj->buf != NULL && DUK_HBUFOBJ_VALID_BYTEOFFSET_EXCL(h_bufobj, byte_off + elem_size)) {
data = (duk_uint8_t *) DUK_HBUFFER_GET_DATA_PTR(thr->heap, h_bufobj->buf) + h_bufobj->offset + byte_off;
- duk_hbufobj_push_validated_read(ctx, h_bufobj, data, elem_size);
+ duk_hbufobj_push_validated_read(thr, h_bufobj, data, elem_size);
} else {
DUK_D(DUK_DPRINT("bufobj access out of underlying buffer, ignoring (read zero)"));
- duk_push_uint(ctx, 0);
+ duk_push_uint(thr, 0);
}
return 1;
@@ -53810,15 +55370,12 @@ DUK_LOCAL duk_bool_t duk__getprop_fastpath_bufobj_tval(duk_hthread *thr, duk_hob
#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)
DUK_LOCAL duk_bool_t duk__putprop_fastpath_bufobj_tval(duk_hthread *thr, duk_hobject *obj, duk_tval *tv_key, duk_tval *tv_val) {
- duk_context *ctx;
duk_uint32_t idx;
duk_hbufobj *h_bufobj;
duk_uint_t byte_off;
duk_small_uint_t elem_size;
duk_uint8_t *data;
- ctx = (duk_context *) thr;
-
if (!(DUK_HOBJECT_IS_BUFOBJ(obj) &&
DUK_TVAL_IS_NUMBER(tv_val))) {
return 0;
@@ -53853,22 +55410,22 @@ DUK_LOCAL duk_bool_t duk__putprop_fastpath_bufobj_tval(duk_hthread *thr, duk_hob
DUK_ASSERT(idx != DUK__NO_ARRAY_INDEX);
byte_off = idx << h_bufobj->shift; /* no wrap assuming h_bufobj->length is valid */
- elem_size = 1 << h_bufobj->shift;
+ elem_size = (duk_small_uint_t) (1U << h_bufobj->shift);
/* Value is required to be a number in the fast path so there
* are no side effects in write coercion.
*/
- duk_push_tval(ctx, tv_val);
- DUK_ASSERT(duk_is_number(ctx, -1));
+ duk_push_tval(thr, tv_val);
+ DUK_ASSERT(duk_is_number(thr, -1));
if (h_bufobj->buf != NULL && DUK_HBUFOBJ_VALID_BYTEOFFSET_EXCL(h_bufobj, byte_off + elem_size)) {
data = (duk_uint8_t *) DUK_HBUFFER_GET_DATA_PTR(thr->heap, h_bufobj->buf) + h_bufobj->offset + byte_off;
- duk_hbufobj_validated_write(ctx, h_bufobj, data, elem_size);
+ duk_hbufobj_validated_write(thr, h_bufobj, data, elem_size);
} else {
DUK_D(DUK_DPRINT("bufobj access out of underlying buffer, ignoring (write skipped)"));
}
- duk_pop(ctx);
+ duk_pop_unsafe(thr);
return 1;
}
#endif /* DUK_USE_BUFFEROBJECT_SUPPORT */
@@ -53878,7 +55435,6 @@ DUK_LOCAL duk_bool_t duk__putprop_fastpath_bufobj_tval(duk_hthread *thr, duk_hob
*/
DUK_INTERNAL duk_bool_t duk_hobject_getprop(duk_hthread *thr, duk_tval *tv_obj, duk_tval *tv_key) {
- duk_context *ctx = (duk_context *) thr;
duk_tval tv_obj_copy;
duk_tval tv_key_copy;
duk_hobject *curr = NULL;
@@ -53891,7 +55447,6 @@ DUK_INTERNAL duk_bool_t duk_hobject_getprop(duk_hthread *thr, duk_tval *tv_obj,
(void *) thr, (void *) tv_obj, (void *) tv_key,
(duk_tval *) tv_obj, (duk_tval *) tv_key));
- DUK_ASSERT(ctx != NULL);
DUK_ASSERT(thr != NULL);
DUK_ASSERT(thr->heap != NULL);
DUK_ASSERT(tv_obj != NULL);
@@ -53899,6 +55454,8 @@ DUK_INTERNAL duk_bool_t duk_hobject_getprop(duk_hthread *thr, duk_tval *tv_obj,
DUK_ASSERT_VALSTACK_SPACE(thr, DUK__VALSTACK_SPACE);
+ DUK_STATS_INC(thr->heap, stats_getprop_all);
+
/*
* Make a copy of tv_obj, tv_key, and tv_val to avoid any issues of
* them being invalidated by a valstack resize.
@@ -53926,7 +55483,7 @@ DUK_INTERNAL duk_bool_t duk_hobject_getprop(duk_hthread *thr, duk_tval *tv_obj,
DUK_ERROR_TYPE(thr, DUK_STR_INVALID_BASE);
#else
DUK_ERROR_FMT2(thr, DUK_ERR_TYPE_ERROR, "cannot read property %s of %s",
- duk_push_string_tval_readable(ctx, tv_key), duk_push_string_tval_readable(ctx, tv_obj));
+ duk_push_string_tval_readable(thr, tv_key), duk_push_string_tval_readable(thr, tv_obj));
#endif
return 0;
}
@@ -53960,23 +55517,24 @@ DUK_INTERNAL duk_bool_t duk_hobject_getprop(duk_hthread *thr, duk_tval *tv_obj,
DUK_DDD(DUK_DDDPRINT("base object string, key is a fast-path number; arr_idx %ld", (long) arr_idx));
pop_count = 0;
} else {
- arr_idx = duk__push_tval_to_property_key(ctx, tv_key, &key);
+ arr_idx = duk__push_tval_to_property_key(thr, tv_key, &key);
DUK_ASSERT(key != NULL);
DUK_DDD(DUK_DDDPRINT("base object string, key is a non-fast-path number; after "
"coercion key is %!T, arr_idx %ld",
- (duk_tval *) duk_get_tval(ctx, -1), (long) arr_idx));
+ (duk_tval *) duk_get_tval(thr, -1), (long) arr_idx));
pop_count = 1;
}
if (arr_idx != DUK__NO_ARRAY_INDEX &&
arr_idx < DUK_HSTRING_GET_CHARLEN(h)) {
- duk_pop_n(ctx, pop_count);
- duk_push_hstring(ctx, h);
- duk_substring(ctx, -1, arr_idx, arr_idx + 1); /* [str] -> [substr] */
+ duk_pop_n_unsafe(thr, pop_count);
+ duk_push_hstring(thr, h);
+ duk_substring(thr, -1, arr_idx, arr_idx + 1); /* [str] -> [substr] */
+ DUK_STATS_INC(thr->heap, stats_getprop_stringidx);
DUK_DDD(DUK_DDDPRINT("-> %!T (base is string, key is an index inside string length "
"after coercion -> return char)",
- (duk_tval *) duk_get_tval(ctx, -1)));
+ (duk_tval *) duk_get_tval(thr, -1)));
return 1;
}
@@ -53984,20 +55542,21 @@ DUK_INTERNAL duk_bool_t duk_hobject_getprop(duk_hthread *thr, duk_tval *tv_obj,
/* This is a pretty awkward control flow, but we need to recheck the
* key coercion here.
*/
- arr_idx = duk__push_tval_to_property_key(ctx, tv_key, &key);
+ arr_idx = duk__push_tval_to_property_key(thr, tv_key, &key);
DUK_ASSERT(key != NULL);
DUK_DDD(DUK_DDDPRINT("base object string, key is a non-fast-path number; after "
"coercion key is %!T, arr_idx %ld",
- (duk_tval *) duk_get_tval(ctx, -1), (long) arr_idx));
+ (duk_tval *) duk_get_tval(thr, -1), (long) arr_idx));
}
if (key == DUK_HTHREAD_STRING_LENGTH(thr)) {
- duk_pop(ctx); /* [key] -> [] */
- duk_push_uint(ctx, (duk_uint_t) DUK_HSTRING_GET_CHARLEN(h)); /* [] -> [res] */
+ duk_pop_unsafe(thr); /* [key] -> [] */
+ duk_push_uint(thr, (duk_uint_t) DUK_HSTRING_GET_CHARLEN(h)); /* [] -> [res] */
+ DUK_STATS_INC(thr->heap, stats_getprop_stringlen);
DUK_DDD(DUK_DDDPRINT("-> %!T (base is string, key is 'length' after coercion -> "
"return string length)",
- (duk_tval *) duk_get_tval(ctx, -1)));
+ (duk_tval *) duk_get_tval(thr, -1)));
return 1;
}
@@ -54019,11 +55578,12 @@ DUK_INTERNAL duk_bool_t duk_hobject_getprop(duk_hthread *thr, duk_tval *tv_obj,
#if defined(DUK_USE_ARRAY_PROP_FASTPATH)
tmp = duk__getprop_shallow_fastpath_array_tval(thr, curr, tv_key);
if (tmp) {
- duk_push_tval(ctx, tmp);
+ duk_push_tval(thr, tmp);
DUK_DDD(DUK_DDDPRINT("-> %!T (base is object, key is a number, array part "
"fast path)",
- (duk_tval *) duk_get_tval(ctx, -1)));
+ (duk_tval *) duk_get_tval(thr, -1)));
+ DUK_STATS_INC(thr->heap, stats_getprop_arrayidx);
return 1;
}
#endif
@@ -54033,32 +55593,34 @@ DUK_INTERNAL duk_bool_t duk_hobject_getprop(duk_hthread *thr, duk_tval *tv_obj,
/* Read value pushed on stack. */
DUK_DDD(DUK_DDDPRINT("-> %!T (base is bufobj, key is a number, bufobj "
"fast path)",
- (duk_tval *) duk_get_tval(ctx, -1)));
+ (duk_tval *) duk_get_tval(thr, -1)));
+ DUK_STATS_INC(thr->heap, stats_getprop_bufobjidx);
return 1;
}
#endif
#if defined(DUK_USE_ES6_PROXY)
- if (DUK_UNLIKELY(DUK_HOBJECT_HAS_EXOTIC_PROXYOBJ(curr))) {
+ if (DUK_UNLIKELY(DUK_HOBJECT_IS_PROXY(curr))) {
duk_hobject *h_target;
if (duk__proxy_check_prop(thr, curr, DUK_STRIDX_GET, tv_key, &h_target)) {
/* -> [ ... trap handler ] */
DUK_DDD(DUK_DDDPRINT("-> proxy object 'get' for key %!T", (duk_tval *) tv_key));
- duk_push_hobject(ctx, h_target); /* target */
- duk_push_tval(ctx, tv_key); /* P */
- duk_push_tval(ctx, tv_obj); /* Receiver: Proxy object */
- duk_call_method(ctx, 3 /*nargs*/);
+ DUK_STATS_INC(thr->heap, stats_getprop_proxy);
+ duk_push_hobject(thr, h_target); /* target */
+ duk_push_tval(thr, tv_key); /* P */
+ duk_push_tval(thr, tv_obj); /* Receiver: Proxy object */
+ duk_call_method(thr, 3 /*nargs*/);
/* Target object must be checked for a conflicting
* non-configurable property.
*/
- arr_idx = duk__push_tval_to_property_key(ctx, tv_key, &key);
+ arr_idx = duk__push_tval_to_property_key(thr, tv_key, &key);
DUK_ASSERT(key != NULL);
if (duk__get_own_propdesc_raw(thr, h_target, key, arr_idx, &desc, DUK_GETDESC_FLAG_PUSH_VALUE)) {
- duk_tval *tv_hook = duk_require_tval(ctx, -3); /* value from hook */
- duk_tval *tv_targ = duk_require_tval(ctx, -1); /* value from target */
+ duk_tval *tv_hook = duk_require_tval(thr, -3); /* value from hook */
+ duk_tval *tv_targ = duk_require_tval(thr, -1); /* value from target */
duk_bool_t datadesc_reject;
duk_bool_t accdesc_reject;
@@ -54081,9 +55643,9 @@ DUK_INTERNAL duk_bool_t duk_hobject_getprop(duk_hthread *thr, duk_tval *tv_obj,
DUK_ERROR_TYPE(thr, DUK_STR_PROXY_REJECTED);
}
- duk_pop_2(ctx);
+ duk_pop_2_unsafe(thr);
} else {
- duk_pop(ctx);
+ duk_pop_unsafe(thr);
}
return 1; /* return value */
}
@@ -54094,18 +55656,19 @@ DUK_INTERNAL duk_bool_t duk_hobject_getprop(duk_hthread *thr, duk_tval *tv_obj,
#endif /* DUK_USE_ES6_PROXY */
if (DUK_HOBJECT_HAS_EXOTIC_ARGUMENTS(curr)) {
- arr_idx = duk__push_tval_to_property_key(ctx, tv_key, &key);
+ arr_idx = duk__push_tval_to_property_key(thr, tv_key, &key);
DUK_ASSERT(key != NULL);
+ DUK_STATS_INC(thr->heap, stats_getprop_arguments);
if (duk__check_arguments_map_for_get(thr, curr, key, &desc)) {
DUK_DDD(DUK_DDDPRINT("-> %!T (base is object with arguments exotic behavior, "
"key matches magically bound property -> skip standard "
"Get with replacement value)",
- (duk_tval *) duk_get_tval(ctx, -1)));
+ (duk_tval *) duk_get_tval(thr, -1)));
/* no need for 'caller' post-check, because 'key' must be an array index */
- duk_remove_m2(ctx); /* [key result] -> [result] */
+ duk_remove_m2(thr); /* [key result] -> [result] */
return 1;
}
@@ -54139,22 +55702,22 @@ DUK_INTERNAL duk_bool_t duk_hobject_getprop(duk_hthread *thr, duk_tval *tv_obj,
DUK_DDD(DUK_DDDPRINT("base object buffer, key is a fast-path number; arr_idx %ld", (long) arr_idx));
pop_count = 0;
} else {
- arr_idx = duk__push_tval_to_property_key(ctx, tv_key, &key);
+ arr_idx = duk__push_tval_to_property_key(thr, tv_key, &key);
DUK_ASSERT(key != NULL);
DUK_DDD(DUK_DDDPRINT("base object buffer, key is a non-fast-path number; after "
"coercion key is %!T, arr_idx %ld",
- (duk_tval *) duk_get_tval(ctx, -1), (long) arr_idx));
+ (duk_tval *) duk_get_tval(thr, -1), (long) arr_idx));
pop_count = 1;
}
if (arr_idx != DUK__NO_ARRAY_INDEX &&
arr_idx < DUK_HBUFFER_GET_SIZE(h)) {
- duk_pop_n(ctx, pop_count);
- duk_push_uint(ctx, ((duk_uint8_t *) DUK_HBUFFER_GET_DATA_PTR(thr->heap, h))[arr_idx]);
-
+ duk_pop_n_unsafe(thr, pop_count);
+ duk_push_uint(thr, ((duk_uint8_t *) DUK_HBUFFER_GET_DATA_PTR(thr->heap, h))[arr_idx]);
+ DUK_STATS_INC(thr->heap, stats_getprop_bufferidx);
DUK_DDD(DUK_DDDPRINT("-> %!T (base is buffer, key is an index inside buffer length "
"after coercion -> return byte as number)",
- (duk_tval *) duk_get_tval(ctx, -1)));
+ (duk_tval *) duk_get_tval(thr, -1)));
return 1;
}
@@ -54162,20 +55725,21 @@ DUK_INTERNAL duk_bool_t duk_hobject_getprop(duk_hthread *thr, duk_tval *tv_obj,
/* This is a pretty awkward control flow, but we need to recheck the
* key coercion here.
*/
- arr_idx = duk__push_tval_to_property_key(ctx, tv_key, &key);
+ arr_idx = duk__push_tval_to_property_key(thr, tv_key, &key);
DUK_ASSERT(key != NULL);
DUK_DDD(DUK_DDDPRINT("base object buffer, key is a non-fast-path number; after "
"coercion key is %!T, arr_idx %ld",
- (duk_tval *) duk_get_tval(ctx, -1), (long) arr_idx));
+ (duk_tval *) duk_get_tval(thr, -1), (long) arr_idx));
}
if (key == DUK_HTHREAD_STRING_LENGTH(thr)) {
- duk_pop(ctx); /* [key] -> [] */
- duk_push_uint(ctx, (duk_uint_t) DUK_HBUFFER_GET_SIZE(h)); /* [] -> [res] */
+ duk_pop_unsafe(thr); /* [key] -> [] */
+ duk_push_uint(thr, (duk_uint_t) DUK_HBUFFER_GET_SIZE(h)); /* [] -> [res] */
+ DUK_STATS_INC(thr->heap, stats_getprop_bufferlen);
DUK_DDD(DUK_DDDPRINT("-> %!T (base is buffer, key is 'length' "
"after coercion -> return buffer length)",
- (duk_tval *) duk_get_tval(ctx, -1)));
+ (duk_tval *) duk_get_tval(thr, -1)));
return 1;
}
@@ -54191,25 +55755,10 @@ DUK_INTERNAL duk_bool_t duk_hobject_getprop(duk_hthread *thr, duk_tval *tv_obj,
}
case DUK_TAG_LIGHTFUNC: {
- duk_int_t lf_flags = DUK_TVAL_GET_LIGHTFUNC_FLAGS(tv_obj);
-
- /* Must coerce key: if key is an object, it may coerce to e.g. 'length'. */
- arr_idx = duk__push_tval_to_property_key(ctx, tv_key, &key);
-
- if (key == DUK_HTHREAD_STRING_LENGTH(thr)) {
- duk_int_t lf_len = DUK_LFUNC_FLAGS_GET_LENGTH(lf_flags);
- duk_pop(ctx);
- duk_push_int(ctx, lf_len);
- return 1;
- } else if (key == DUK_HTHREAD_STRING_NAME(thr)) {
- duk_pop(ctx);
- duk_push_lightfunc_name(ctx, tv_obj);
- return 1;
- }
-
+ /* Lightfuncs inherit getter .name and .length from %NativeFunctionPrototype%. */
DUK_DDD(DUK_DDDPRINT("base object is a lightfunc, start lookup from function prototype"));
- curr = thr->builtins[DUK_BIDX_FUNCTION_PROTOTYPE];
- goto lookup; /* avoid double coercion */
+ curr = thr->builtins[DUK_BIDX_NATIVE_FUNCTION_PROTOTYPE];
+ break;
}
#if defined(DUK_USE_FASTINT)
@@ -54227,9 +55776,8 @@ DUK_INTERNAL duk_bool_t duk_hobject_getprop(duk_hthread *thr, duk_tval *tv_obj,
/* key coercion (unless already coerced above) */
DUK_ASSERT(key == NULL);
- arr_idx = duk__push_tval_to_property_key(ctx, tv_key, &key);
+ arr_idx = duk__push_tval_to_property_key(thr, tv_key, &key);
DUK_ASSERT(key != NULL);
-
/*
* Property lookup
*/
@@ -54249,14 +55797,14 @@ DUK_INTERNAL duk_bool_t duk_hobject_getprop(duk_hthread *thr, duk_tval *tv_obj,
/* accessor with defined getter */
DUK_ASSERT((desc.flags & DUK_PROPDESC_FLAG_ACCESSOR) != 0);
- duk_pop(ctx); /* [key undefined] -> [key] */
- duk_push_hobject(ctx, desc.get);
- duk_push_tval(ctx, tv_obj); /* note: original, uncoerced base */
+ duk_pop_unsafe(thr); /* [key undefined] -> [key] */
+ duk_push_hobject(thr, desc.get);
+ duk_push_tval(thr, tv_obj); /* note: original, uncoerced base */
#if defined(DUK_USE_NONSTD_GETTER_KEY_ARGUMENT)
- duk_dup_m3(ctx);
- duk_call_method(ctx, 1); /* [key getter this key] -> [key retval] */
+ duk_dup_m3(thr);
+ duk_call_method(thr, 1); /* [key getter this key] -> [key retval] */
#else
- duk_call_method(ctx, 0); /* [key getter this] -> [key retval] */
+ duk_call_method(thr, 0); /* [key getter this] -> [key retval] */
#endif
} else {
/* [key value] or [key undefined] */
@@ -54267,7 +55815,7 @@ DUK_INTERNAL duk_bool_t duk_hobject_getprop(duk_hthread *thr, duk_tval *tv_obj,
/* if accessor without getter, return value is undefined */
DUK_ASSERT(((desc.flags & DUK_PROPDESC_FLAG_ACCESSOR) == 0) ||
- duk_is_undefined(ctx, -1));
+ duk_is_undefined(thr, -1));
/* Note: for an accessor without getter, falling through to
* check for "caller" exotic behavior is unnecessary as
@@ -54292,9 +55840,9 @@ DUK_INTERNAL duk_bool_t duk_hobject_getprop(duk_hthread *thr, duk_tval *tv_obj,
* Not found
*/
- duk_to_undefined(ctx, -1); /* [key] -> [undefined] (default value) */
+ duk_to_undefined(thr, -1); /* [key] -> [undefined] (default value) */
- DUK_DDD(DUK_DDDPRINT("-> %!T (not found)", (duk_tval *) duk_get_tval(ctx, -1)));
+ DUK_DDD(DUK_DDDPRINT("-> %!T (not found)", (duk_tval *) duk_get_tval(thr, -1)));
return 0;
/*
@@ -54348,7 +55896,7 @@ DUK_INTERNAL duk_bool_t duk_hobject_getprop(duk_hthread *thr, duk_tval *tv_obj,
*/
DUK_ASSERT(!DUK_HOBJECT_HAS_BOUNDFUNC(orig));
- h = duk_get_hobject(ctx, -1); /* NULL if not an object */
+ h = duk_get_hobject(thr, -1); /* NULL if not an object */
if (h &&
DUK_HOBJECT_IS_FUNCTION(h) &&
DUK_HOBJECT_HAS_STRICT(h)) {
@@ -54359,9 +55907,9 @@ DUK_INTERNAL duk_bool_t duk_hobject_getprop(duk_hthread *thr, duk_tval *tv_obj,
}
#endif /* !DUK_USE_NONSTD_FUNC_CALLER_PROPERTY */
- duk_remove_m2(ctx); /* [key result] -> [result] */
+ duk_remove_m2(thr); /* [key result] -> [result] */
- DUK_DDD(DUK_DDDPRINT("-> %!T (found)", (duk_tval *) duk_get_tval(ctx, -1)));
+ DUK_DDD(DUK_DDDPRINT("-> %!T (found)", (duk_tval *) duk_get_tval(thr, -1)));
return 1;
}
@@ -54373,7 +55921,6 @@ DUK_INTERNAL duk_bool_t duk_hobject_getprop(duk_hthread *thr, duk_tval *tv_obj,
*/
DUK_INTERNAL duk_bool_t duk_hobject_hasprop(duk_hthread *thr, duk_tval *tv_obj, duk_tval *tv_key) {
- duk_context *ctx = (duk_context *) thr;
duk_tval tv_key_copy;
duk_hobject *obj;
duk_hstring *key;
@@ -54412,27 +55959,23 @@ DUK_INTERNAL duk_bool_t duk_hobject_hasprop(duk_hthread *thr, duk_tval *tv_obj,
obj = DUK_TVAL_GET_OBJECT(tv_obj);
DUK_ASSERT(obj != NULL);
- arr_idx = duk__push_tval_to_property_key(ctx, tv_key, &key);
+ arr_idx = duk__push_tval_to_property_key(thr, tv_key, &key);
} else if (DUK_TVAL_IS_BUFFER(tv_obj)) {
- arr_idx = duk__push_tval_to_property_key(ctx, tv_key, &key);
+ arr_idx = duk__push_tval_to_property_key(thr, tv_key, &key);
if (duk__key_is_plain_buf_ownprop(thr, DUK_TVAL_GET_BUFFER(tv_obj), key, arr_idx)) {
rc = 1;
goto pop_and_return;
}
obj = thr->builtins[DUK_BIDX_UINT8ARRAY_PROTOTYPE];
} else if (DUK_TVAL_IS_LIGHTFUNC(tv_obj)) {
- arr_idx = duk__push_tval_to_property_key(ctx, tv_key, &key);
- if (duk__key_is_lightfunc_ownprop(thr, key)) {
- rc = 1;
- goto pop_and_return;
- }
+ arr_idx = duk__push_tval_to_property_key(thr, tv_key, &key);
- /* If not found, resume existence check from Function.prototype.
+ /* If not found, resume existence check from %NativeFunctionPrototype%.
* We can just substitute the value in this case; nothing will
* need the original base value (as would be the case with e.g.
* setters/getters.
*/
- obj = thr->builtins[DUK_BIDX_FUNCTION_PROTOTYPE];
+ obj = thr->builtins[DUK_BIDX_NATIVE_FUNCTION_PROTOTYPE];
} else {
/* Note: unconditional throw */
DUK_DDD(DUK_DDDPRINT("base object is not an object -> reject"));
@@ -54446,7 +55989,7 @@ DUK_INTERNAL duk_bool_t duk_hobject_hasprop(duk_hthread *thr, duk_tval *tv_obj,
DUK_UNREF(arr_idx);
#if defined(DUK_USE_ES6_PROXY)
- if (DUK_UNLIKELY(DUK_HOBJECT_HAS_EXOTIC_PROXYOBJ(obj))) {
+ if (DUK_UNLIKELY(DUK_HOBJECT_IS_PROXY(obj))) {
duk_hobject *h_target;
duk_bool_t tmp_bool;
@@ -54458,10 +56001,10 @@ DUK_INTERNAL duk_bool_t duk_hobject_hasprop(duk_hthread *thr, duk_tval *tv_obj,
if (duk__proxy_check_prop(thr, obj, DUK_STRIDX_HAS, tv_key, &h_target)) {
/* [ ... key trap handler ] */
DUK_DDD(DUK_DDDPRINT("-> proxy object 'has' for key %!T", (duk_tval *) tv_key));
- duk_push_hobject(ctx, h_target); /* target */
- duk_push_tval(ctx, tv_key); /* P */
- duk_call_method(ctx, 2 /*nargs*/);
- tmp_bool = duk_to_boolean(ctx, -1);
+ duk_push_hobject(thr, h_target); /* target */
+ duk_push_tval(thr, tv_key); /* P */
+ duk_call_method(thr, 2 /*nargs*/);
+ tmp_bool = duk_to_boolean(thr, -1);
if (!tmp_bool) {
/* Target object must be checked for a conflicting
* non-configurable property.
@@ -54484,7 +56027,7 @@ DUK_INTERNAL duk_bool_t duk_hobject_hasprop(duk_hthread *thr, duk_tval *tv_obj,
}
}
- duk_pop_2(ctx); /* [ key trap_result ] -> [] */
+ duk_pop_2_unsafe(thr); /* [ key trap_result ] -> [] */
return tmp_bool;
}
@@ -54498,7 +56041,7 @@ DUK_INTERNAL duk_bool_t duk_hobject_hasprop(duk_hthread *thr, duk_tval *tv_obj,
/* fall through */
pop_and_return:
- duk_pop(ctx); /* [ key ] -> [] */
+ duk_pop_unsafe(thr); /* [ key ] -> [] */
return rc;
}
@@ -54551,7 +56094,7 @@ DUK_LOCAL duk_uint32_t duk__to_new_array_length_checked(duk_hthread *thr, duk_tv
/* Very common case. */
duk_int64_t fi;
fi = DUK_TVAL_GET_FASTINT(tv);
- if (fi < 0 || fi > 0xffffffffLL) {
+ if (fi < 0 || fi > DUK_I64_CONSTANT(0xffffffff)) {
goto fail_range;
}
return (duk_uint32_t) fi;
@@ -54664,7 +56207,7 @@ duk_bool_t duk__handle_put_array_length_smaller(duk_hthread *thr,
return 1;
} else {
/*
- * Entries part is a bit more complex
+ * Entries part is a bit more complex.
*/
/* Stage 1: find highest preventing non-configurable entry (if any).
@@ -54783,7 +56326,6 @@ duk_bool_t duk__handle_put_array_length_smaller(duk_hthread *thr,
/* XXX: is valstack top best place for argument? */
DUK_LOCAL duk_bool_t duk__handle_put_array_length(duk_hthread *thr, duk_hobject *obj) {
- duk_context *ctx = (duk_context *) thr;
duk_harray *a;
duk_uint32_t old_len;
duk_uint32_t new_len;
@@ -54792,10 +56334,9 @@ DUK_LOCAL duk_bool_t duk__handle_put_array_length(duk_hthread *thr, duk_hobject
DUK_DDD(DUK_DDDPRINT("handling a put operation to array 'length' exotic property, "
"new val: %!T",
- (duk_tval *) duk_get_tval(ctx, -1)));
+ (duk_tval *) duk_get_tval(thr, -1)));
DUK_ASSERT(thr != NULL);
- DUK_ASSERT(ctx != NULL);
DUK_ASSERT(obj != NULL);
DUK_ASSERT_VALSTACK_SPACE(thr, DUK__VALSTACK_SPACE);
@@ -54805,14 +56346,14 @@ DUK_LOCAL duk_bool_t duk__handle_put_array_length(duk_hthread *thr, duk_hobject
a = (duk_harray *) obj;
DUK_ASSERT_HARRAY_VALID(a);
- DUK_ASSERT(duk_is_valid_index(ctx, -1));
+ DUK_ASSERT(duk_is_valid_index(thr, -1));
/*
* Get old and new length
*/
old_len = a->length;
- new_len = duk__to_new_array_length_checked(thr, DUK_GET_TVAL_NEGIDX(ctx, -1));
+ new_len = duk__to_new_array_length_checked(thr, DUK_GET_TVAL_NEGIDX(thr, -1));
DUK_DDD(DUK_DDDPRINT("old_len=%ld, new_len=%ld", (long) old_len, (long) new_len));
/*
@@ -54885,7 +56426,6 @@ DUK_LOCAL duk_bool_t duk__handle_put_array_length(duk_hthread *thr, duk_hobject
*/
DUK_INTERNAL duk_bool_t duk_hobject_putprop(duk_hthread *thr, duk_tval *tv_obj, duk_tval *tv_key, duk_tval *tv_val, duk_bool_t throw_flag) {
- duk_context *ctx = (duk_context *) thr;
duk_tval tv_obj_copy;
duk_tval tv_key_copy;
duk_tval tv_val_copy;
@@ -54907,13 +56447,14 @@ DUK_INTERNAL duk_bool_t duk_hobject_putprop(duk_hthread *thr, duk_tval *tv_obj,
DUK_ASSERT(thr != NULL);
DUK_ASSERT(thr->heap != NULL);
- DUK_ASSERT(ctx != NULL);
DUK_ASSERT(tv_obj != NULL);
DUK_ASSERT(tv_key != NULL);
DUK_ASSERT(tv_val != NULL);
DUK_ASSERT_VALSTACK_SPACE(thr, DUK__VALSTACK_SPACE);
+ DUK_STATS_INC(thr->heap, stats_putprop_all);
+
/*
* Make a copy of tv_obj, tv_key, and tv_val to avoid any issues of
* them being invalidated by a valstack resize.
@@ -54943,7 +56484,7 @@ DUK_INTERNAL duk_bool_t duk_hobject_putprop(duk_hthread *thr, duk_tval *tv_obj,
DUK_ERROR_TYPE(thr, DUK_STR_INVALID_BASE);
#else
DUK_ERROR_FMT2(thr, DUK_ERR_TYPE_ERROR, "cannot write property %s of %s",
- duk_push_string_tval_readable(ctx, tv_key), duk_push_string_tval_readable(ctx, tv_obj));
+ duk_push_string_tval_readable(thr, tv_key), duk_push_string_tval_readable(thr, tv_obj));
#endif
return 0;
}
@@ -54963,7 +56504,7 @@ DUK_INTERNAL duk_bool_t duk_hobject_putprop(duk_hthread *thr, duk_tval *tv_obj,
*/
DUK_ASSERT(key == NULL);
- arr_idx = duk__push_tval_to_property_key(ctx, tv_key, &key);
+ arr_idx = duk__push_tval_to_property_key(thr, tv_key, &key);
DUK_ASSERT(key != NULL);
if (DUK_UNLIKELY(DUK_HSTRING_HAS_SYMBOL(h))) {
@@ -55022,6 +56563,7 @@ DUK_INTERNAL duk_bool_t duk_hobject_putprop(duk_hthread *thr, duk_tval *tv_obj,
#if defined(DUK_USE_ARRAY_PROP_FASTPATH)
if (duk__putprop_shallow_fastpath_array_tval(thr, orig, tv_key, tv_val) != 0) {
DUK_DDD(DUK_DDDPRINT("array fast path success"));
+ DUK_STATS_INC(thr->heap, stats_putprop_arrayidx);
return 1;
}
#endif
@@ -55029,25 +56571,27 @@ DUK_INTERNAL duk_bool_t duk_hobject_putprop(duk_hthread *thr, duk_tval *tv_obj,
#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)
if (duk__putprop_fastpath_bufobj_tval(thr, orig, tv_key, tv_val) != 0) {
DUK_DDD(DUK_DDDPRINT("base is bufobj, key is a number, bufobj fast path"));
+ DUK_STATS_INC(thr->heap, stats_putprop_bufobjidx);
return 1;
}
#endif
#if defined(DUK_USE_ES6_PROXY)
- if (DUK_UNLIKELY(DUK_HOBJECT_HAS_EXOTIC_PROXYOBJ(orig))) {
+ if (DUK_UNLIKELY(DUK_HOBJECT_IS_PROXY(orig))) {
duk_hobject *h_target;
duk_bool_t tmp_bool;
if (duk__proxy_check_prop(thr, orig, DUK_STRIDX_SET, tv_key, &h_target)) {
/* -> [ ... trap handler ] */
DUK_DDD(DUK_DDDPRINT("-> proxy object 'set' for key %!T", (duk_tval *) tv_key));
- duk_push_hobject(ctx, h_target); /* target */
- duk_push_tval(ctx, tv_key); /* P */
- duk_push_tval(ctx, tv_val); /* V */
- duk_push_tval(ctx, tv_obj); /* Receiver: Proxy object */
- duk_call_method(ctx, 4 /*nargs*/);
- tmp_bool = duk_to_boolean(ctx, -1);
- duk_pop(ctx);
+ DUK_STATS_INC(thr->heap, stats_putprop_proxy);
+ duk_push_hobject(thr, h_target); /* target */
+ duk_push_tval(thr, tv_key); /* P */
+ duk_push_tval(thr, tv_val); /* V */
+ duk_push_tval(thr, tv_obj); /* Receiver: Proxy object */
+ duk_call_method(thr, 4 /*nargs*/);
+ tmp_bool = duk_to_boolean(thr, -1);
+ duk_pop_nodecref_unsafe(thr);
if (!tmp_bool) {
goto fail_proxy_rejected;
}
@@ -55055,11 +56599,11 @@ DUK_INTERNAL duk_bool_t duk_hobject_putprop(duk_hthread *thr, duk_tval *tv_obj,
/* Target object must be checked for a conflicting
* non-configurable property.
*/
- arr_idx = duk__push_tval_to_property_key(ctx, tv_key, &key);
+ arr_idx = duk__push_tval_to_property_key(thr, tv_key, &key);
DUK_ASSERT(key != NULL);
if (duk__get_own_propdesc_raw(thr, h_target, key, arr_idx, &desc, DUK_GETDESC_FLAG_PUSH_VALUE)) {
- duk_tval *tv_targ = duk_require_tval(ctx, -1);
+ duk_tval *tv_targ = duk_require_tval(thr, -1);
duk_bool_t datadesc_reject;
duk_bool_t accdesc_reject;
@@ -55081,9 +56625,9 @@ DUK_INTERNAL duk_bool_t duk_hobject_putprop(duk_hthread *thr, duk_tval *tv_obj,
DUK_ERROR_TYPE(thr, DUK_STR_PROXY_REJECTED);
}
- duk_pop_2(ctx);
+ duk_pop_2_unsafe(thr);
} else {
- duk_pop(ctx);
+ duk_pop_unsafe(thr);
}
return 1; /* success */
}
@@ -55118,11 +56662,11 @@ DUK_INTERNAL duk_bool_t duk_hobject_putprop(duk_hthread *thr, duk_tval *tv_obj,
DUK_DDD(DUK_DDDPRINT("base object buffer, key is a fast-path number; arr_idx %ld", (long) arr_idx));
pop_count = 0;
} else {
- arr_idx = duk__push_tval_to_property_key(ctx, tv_key, &key);
+ arr_idx = duk__push_tval_to_property_key(thr, tv_key, &key);
DUK_ASSERT(key != NULL);
DUK_DDD(DUK_DDDPRINT("base object buffer, key is a non-fast-path number; after "
"coercion key is %!T, arr_idx %ld",
- (duk_tval *) duk_get_tval(ctx, -1), (long) arr_idx));
+ (duk_tval *) duk_get_tval(thr, -1), (long) arr_idx));
pop_count = 1;
}
@@ -55143,13 +56687,14 @@ DUK_INTERNAL duk_bool_t duk_hobject_putprop(duk_hthread *thr, duk_tval *tv_obj,
else
#endif
{
- duk_push_tval(ctx, tv_val);
- data[arr_idx] = (duk_uint8_t) duk_to_uint32(ctx, -1);
+ duk_push_tval(thr, tv_val);
+ data[arr_idx] = (duk_uint8_t) duk_to_uint32(thr, -1);
pop_count++;
}
- duk_pop_n(ctx, pop_count);
+ duk_pop_n_unsafe(thr, pop_count);
DUK_DDD(DUK_DDDPRINT("result: success (buffer data write)"));
+ DUK_STATS_INC(thr->heap, stats_putprop_bufferidx);
return 1;
}
@@ -55157,11 +56702,11 @@ DUK_INTERNAL duk_bool_t duk_hobject_putprop(duk_hthread *thr, duk_tval *tv_obj,
/* This is a pretty awkward control flow, but we need to recheck the
* key coercion here.
*/
- arr_idx = duk__push_tval_to_property_key(ctx, tv_key, &key);
+ arr_idx = duk__push_tval_to_property_key(thr, tv_key, &key);
DUK_ASSERT(key != NULL);
DUK_DDD(DUK_DDDPRINT("base object buffer, key is a non-fast-path number; after "
"coercion key is %!T, arr_idx %ld",
- (duk_tval *) duk_get_tval(ctx, -1), (long) arr_idx));
+ (duk_tval *) duk_get_tval(thr, -1), (long) arr_idx));
}
if (key == DUK_HTHREAD_STRING_LENGTH(thr)) {
@@ -55180,20 +56725,13 @@ DUK_INTERNAL duk_bool_t duk_hobject_putprop(duk_hthread *thr, duk_tval *tv_obj,
}
case DUK_TAG_LIGHTFUNC: {
- /* All lightfunc own properties are non-writable and the lightfunc
- * is considered non-extensible. However, the write may be captured
- * by an inherited setter which means we can't stop the lookup here.
+ /* Lightfuncs have no own properties and are considered non-extensible.
+ * However, the write may be captured by an inherited setter which
+ * means we can't stop the lookup here.
*/
-
- arr_idx = duk__push_tval_to_property_key(ctx, tv_key, &key);
-
- if (duk__key_is_lightfunc_ownprop(thr, key)) {
- goto fail_not_writable;
- }
-
DUK_DDD(DUK_DDDPRINT("base object is a lightfunc, start lookup from function prototype"));
- curr = thr->builtins[DUK_BIDX_FUNCTION_PROTOTYPE];
- goto lookup; /* avoid double coercion */
+ curr = thr->builtins[DUK_BIDX_NATIVE_FUNCTION_PROTOTYPE];
+ break;
}
#if defined(DUK_USE_FASTINT)
@@ -55209,7 +56747,7 @@ DUK_INTERNAL duk_bool_t duk_hobject_putprop(duk_hthread *thr, duk_tval *tv_obj,
}
DUK_ASSERT(key == NULL);
- arr_idx = duk__push_tval_to_property_key(ctx, tv_key, &key);
+ arr_idx = duk__push_tval_to_property_key(thr, tv_key, &key);
DUK_ASSERT(key != NULL);
lookup:
@@ -55247,16 +56785,16 @@ DUK_INTERNAL duk_bool_t duk_hobject_putprop(duk_hthread *thr, duk_tval *tv_obj,
if (!setter) {
goto fail_no_setter;
}
- duk_push_hobject(ctx, setter);
- duk_push_tval(ctx, tv_obj); /* note: original, uncoerced base */
- duk_push_tval(ctx, tv_val); /* [key setter this val] */
+ duk_push_hobject(thr, setter);
+ duk_push_tval(thr, tv_obj); /* note: original, uncoerced base */
+ duk_push_tval(thr, tv_val); /* [key setter this val] */
#if defined(DUK_USE_NONSTD_SETTER_KEY_ARGUMENT)
- duk_dup_m4(ctx);
- duk_call_method(ctx, 2); /* [key setter this val key] -> [key retval] */
+ duk_dup_m4(thr);
+ duk_call_method(thr, 2); /* [key setter this val key] -> [key retval] */
#else
- duk_call_method(ctx, 1); /* [key setter this val] -> [key retval] */
+ duk_call_method(thr, 1); /* [key setter this val] -> [key retval] */
#endif
- duk_pop(ctx); /* ignore retval -> [key] */
+ duk_pop_unsafe(thr); /* ignore retval -> [key] */
goto success_no_arguments_exotic;
}
@@ -55318,9 +56856,9 @@ DUK_INTERNAL duk_bool_t duk_hobject_putprop(duk_hthread *thr, duk_tval *tv_obj,
* compatible with what we need.
*/
- duk_push_tval(ctx, tv_val); /* [key val] */
+ duk_push_tval(thr, tv_val); /* [key val] */
rc = duk__handle_put_array_length(thr, orig);
- duk_pop(ctx); /* [key val] -> [key] */
+ duk_pop_unsafe(thr); /* [key val] -> [key] */
if (!rc) {
goto fail_array_length_partial;
}
@@ -55348,23 +56886,23 @@ DUK_INTERNAL duk_bool_t duk_hobject_putprop(duk_hthread *thr, duk_tval *tv_obj,
DUK_ASSERT(arr_idx != DUK__NO_ARRAY_INDEX); /* index/length check guarantees */
byte_off = arr_idx << h_bufobj->shift; /* no wrap assuming h_bufobj->length is valid */
- elem_size = 1 << h_bufobj->shift;
+ elem_size = (duk_small_uint_t) (1U << h_bufobj->shift);
/* Coerce to number before validating pointers etc so that the
* number coercions in duk_hbufobj_validated_write() are
* guaranteed to be side effect free and not invalidate the
* pointer checks we do here.
*/
- duk_push_tval(ctx, tv_val);
- (void) duk_to_number_m1(ctx);
+ duk_push_tval(thr, tv_val);
+ (void) duk_to_number_m1(thr);
if (h_bufobj->buf != NULL && DUK_HBUFOBJ_VALID_BYTEOFFSET_EXCL(h_bufobj, byte_off + elem_size)) {
data = (duk_uint8_t *) DUK_HBUFFER_GET_DATA_PTR(thr->heap, h_bufobj->buf) + h_bufobj->offset + byte_off;
- duk_hbufobj_validated_write(ctx, h_bufobj, data, elem_size);
+ duk_hbufobj_validated_write(thr, h_bufobj, data, elem_size);
} else {
DUK_D(DUK_DPRINT("bufobj access out of underlying buffer, ignoring (write skipped)"));
}
- duk_pop(ctx);
+ duk_pop_unsafe(thr);
goto success_no_arguments_exotic;
}
}
@@ -55648,7 +57186,7 @@ DUK_INTERNAL duk_bool_t duk_hobject_putprop(duk_hthread *thr, duk_tval *tv_obj,
* refcount; may need a props allocation resize but doesn't
* 'recheck' the valstack.
*/
- e_idx = duk__alloc_entry_checked(thr, orig, key);
+ e_idx = duk__hobject_alloc_entry_checked(thr, orig, key);
DUK_ASSERT(e_idx >= 0);
tv = DUK_HOBJECT_E_GET_VALUE_TVAL_PTR(thr->heap, orig, e_idx);
@@ -55716,16 +57254,16 @@ DUK_INTERNAL duk_bool_t duk_hobject_putprop(duk_hthread *thr, duk_tval *tv_obj,
* rework to use tv_val directly?
*/
- duk_push_tval(ctx, tv_val);
+ duk_push_tval(thr, tv_val);
(void) duk__check_arguments_map_for_put(thr, orig, key, &desc, throw_flag);
- duk_pop(ctx);
+ duk_pop_unsafe(thr);
}
/* fall thru */
success_no_arguments_exotic:
/* shared exit path now */
DUK_DDD(DUK_DDDPRINT("result: success"));
- duk_pop(ctx); /* remove key */
+ duk_pop_unsafe(thr); /* remove key */
return 1;
#if defined(DUK_USE_ES6_PROXY)
@@ -55745,10 +57283,10 @@ DUK_INTERNAL duk_bool_t duk_hobject_putprop(duk_hthread *thr, duk_tval *tv_obj,
DUK_ERROR_TYPE(thr, DUK_STR_INVALID_BASE);
#else
DUK_ERROR_FMT2(thr, DUK_ERR_TYPE_ERROR, "cannot write property %s of %s",
- duk_push_string_tval_readable(ctx, tv_key), duk_push_string_tval_readable(ctx, tv_obj));
+ duk_push_string_tval_readable(thr, tv_key), duk_push_string_tval_readable(thr, tv_obj));
#endif
}
- duk_pop(ctx); /* remove key */
+ duk_pop_unsafe(thr); /* remove key */
return 0;
fail_not_extensible:
@@ -55756,7 +57294,7 @@ DUK_INTERNAL duk_bool_t duk_hobject_putprop(duk_hthread *thr, duk_tval *tv_obj,
if (throw_flag) {
DUK_ERROR_TYPE(thr, DUK_STR_NOT_EXTENSIBLE);
}
- duk_pop(ctx); /* remove key */
+ duk_pop_unsafe(thr); /* remove key */
return 0;
fail_not_writable:
@@ -55764,7 +57302,7 @@ DUK_INTERNAL duk_bool_t duk_hobject_putprop(duk_hthread *thr, duk_tval *tv_obj,
if (throw_flag) {
DUK_ERROR_TYPE(thr, DUK_STR_NOT_WRITABLE);
}
- duk_pop(ctx); /* remove key */
+ duk_pop_unsafe(thr); /* remove key */
return 0;
#if defined(DUK_USE_ROM_OBJECTS)
@@ -55781,7 +57319,7 @@ DUK_INTERNAL duk_bool_t duk_hobject_putprop(duk_hthread *thr, duk_tval *tv_obj,
if (throw_flag) {
DUK_ERROR_TYPE(thr, DUK_STR_NOT_CONFIGURABLE);
}
- duk_pop(ctx); /* remove key */
+ duk_pop_unsafe(thr); /* remove key */
return 0;
fail_no_setter:
@@ -55789,7 +57327,7 @@ DUK_INTERNAL duk_bool_t duk_hobject_putprop(duk_hthread *thr, duk_tval *tv_obj,
if (throw_flag) {
DUK_ERROR_TYPE(thr, DUK_STR_SETTER_UNDEFINED);
}
- duk_pop(ctx); /* remove key */
+ duk_pop_unsafe(thr); /* remove key */
return 0;
fail_internal:
@@ -55797,7 +57335,7 @@ DUK_INTERNAL duk_bool_t duk_hobject_putprop(duk_hthread *thr, duk_tval *tv_obj,
if (throw_flag) {
DUK_ERROR_INTERNAL(thr);
}
- duk_pop(ctx); /* remove key */
+ duk_pop_unsafe(thr); /* remove key */
return 0;
}
@@ -55965,7 +57503,6 @@ DUK_INTERNAL duk_bool_t duk_hobject_delprop_raw(duk_hthread *thr, duk_hobject *o
*/
DUK_INTERNAL duk_bool_t duk_hobject_delprop(duk_hthread *thr, duk_tval *tv_obj, duk_tval *tv_key, duk_bool_t throw_flag) {
- duk_context *ctx = (duk_context *) thr;
duk_hstring *key = NULL;
#if defined(DUK_USE_ES6_PROXY)
duk_propdesc desc;
@@ -55978,7 +57515,6 @@ DUK_INTERNAL duk_bool_t duk_hobject_delprop(duk_hthread *thr, duk_tval *tv_obj,
(void *) thr, (void *) tv_obj, (void *) tv_key,
(duk_tval *) tv_obj, (duk_tval *) tv_key));
- DUK_ASSERT(ctx != NULL);
DUK_ASSERT(thr != NULL);
DUK_ASSERT(thr->heap != NULL);
DUK_ASSERT(tv_obj != NULL);
@@ -55989,7 +57525,7 @@ DUK_INTERNAL duk_bool_t duk_hobject_delprop(duk_hthread *thr, duk_tval *tv_obj,
/* Storing the entry top is cheaper here to ensure stack is correct at exit,
* as there are several paths out.
*/
- entry_top = duk_get_top(ctx);
+ entry_top = duk_get_top(thr);
if (DUK_TVAL_IS_UNDEFINED(tv_obj) ||
DUK_TVAL_IS_NULL(tv_obj)) {
@@ -55997,16 +57533,16 @@ DUK_INTERNAL duk_bool_t duk_hobject_delprop(duk_hthread *thr, duk_tval *tv_obj,
goto fail_invalid_base_uncond;
}
- duk_push_tval(ctx, tv_obj);
- duk_push_tval(ctx, tv_key);
+ duk_push_tval(thr, tv_obj);
+ duk_push_tval(thr, tv_key);
- tv_obj = DUK_GET_TVAL_NEGIDX(ctx, -2);
+ tv_obj = DUK_GET_TVAL_NEGIDX(thr, -2);
if (DUK_TVAL_IS_OBJECT(tv_obj)) {
duk_hobject *obj = DUK_TVAL_GET_OBJECT(tv_obj);
DUK_ASSERT(obj != NULL);
#if defined(DUK_USE_ES6_PROXY)
- if (DUK_UNLIKELY(DUK_HOBJECT_HAS_EXOTIC_PROXYOBJ(obj))) {
+ if (DUK_UNLIKELY(DUK_HOBJECT_IS_PROXY(obj))) {
duk_hobject *h_target;
duk_bool_t tmp_bool;
@@ -56015,11 +57551,11 @@ DUK_INTERNAL duk_bool_t duk_hobject_delprop(duk_hthread *thr, duk_tval *tv_obj,
if (duk__proxy_check_prop(thr, obj, DUK_STRIDX_DELETE_PROPERTY, tv_key, &h_target)) {
/* -> [ ... obj key trap handler ] */
DUK_DDD(DUK_DDDPRINT("-> proxy object 'deleteProperty' for key %!T", (duk_tval *) tv_key));
- duk_push_hobject(ctx, h_target); /* target */
- duk_dup_m4(ctx); /* P */
- duk_call_method(ctx, 2 /*nargs*/);
- tmp_bool = duk_to_boolean(ctx, -1);
- duk_pop(ctx);
+ duk_push_hobject(thr, h_target); /* target */
+ duk_dup_m4(thr); /* P */
+ duk_call_method(thr, 2 /*nargs*/);
+ tmp_bool = duk_to_boolean(thr, -1);
+ duk_pop_nodecref_unsafe(thr);
if (!tmp_bool) {
goto fail_proxy_rejected; /* retval indicates delete failed */
}
@@ -56027,8 +57563,8 @@ DUK_INTERNAL duk_bool_t duk_hobject_delprop(duk_hthread *thr, duk_tval *tv_obj,
/* Target object must be checked for a conflicting
* non-configurable property.
*/
- tv_key = DUK_GET_TVAL_NEGIDX(ctx, -1);
- arr_idx = duk__push_tval_to_property_key(ctx, tv_key, &key);
+ tv_key = DUK_GET_TVAL_NEGIDX(thr, -1);
+ arr_idx = duk__push_tval_to_property_key(thr, tv_key, &key);
DUK_ASSERT(key != NULL);
if (duk__get_own_propdesc_raw(thr, h_target, key, arr_idx, &desc, 0 /*flags*/)) { /* don't push value */
@@ -56054,7 +57590,7 @@ DUK_INTERNAL duk_bool_t duk_hobject_delprop(duk_hthread *thr, duk_tval *tv_obj,
}
#endif /* DUK_USE_ES6_PROXY */
- arr_idx = duk__to_property_key(ctx, -1, &key);
+ arr_idx = duk__to_property_key(thr, -1, &key);
DUK_ASSERT(key != NULL);
rc = duk_hobject_delprop_raw(thr, obj, key, throw_flag ? DUK_DELPROP_FLAG_THROW : 0);
@@ -56070,7 +57606,7 @@ DUK_INTERNAL duk_bool_t duk_hobject_delprop(duk_hthread *thr, duk_tval *tv_obj,
duk_hstring *h = DUK_TVAL_GET_STRING(tv_obj);
DUK_ASSERT(h != NULL);
- arr_idx = duk__to_property_key(ctx, -1, &key);
+ arr_idx = duk__to_property_key(thr, -1, &key);
DUK_ASSERT(key != NULL);
if (key == DUK_HTHREAD_STRING_LENGTH(thr)) {
@@ -56089,7 +57625,7 @@ DUK_INTERNAL duk_bool_t duk_hobject_delprop(duk_hthread *thr, duk_tval *tv_obj,
duk_hbuffer *h = DUK_TVAL_GET_BUFFER(tv_obj);
DUK_ASSERT(h != NULL);
- arr_idx = duk__to_property_key(ctx, -1, &key);
+ arr_idx = duk__to_property_key(thr, -1, &key);
DUK_ASSERT(key != NULL);
if (key == DUK_HTHREAD_STRING_LENGTH(thr)) {
@@ -56101,16 +57637,13 @@ DUK_INTERNAL duk_bool_t duk_hobject_delprop(duk_hthread *thr, duk_tval *tv_obj,
goto fail_not_configurable;
}
} else if (DUK_TVAL_IS_LIGHTFUNC(tv_obj)) {
- /* Lightfunc virtual properties are non-configurable, so
- * reject if match any of them.
+ /* Lightfunc has no virtual properties since Duktape 2.2
+ * so success. Still must coerce key for side effects.
*/
- arr_idx = duk__to_property_key(ctx, -1, &key);
+ arr_idx = duk__to_property_key(thr, -1, &key);
DUK_ASSERT(key != NULL);
-
- if (duk__key_is_lightfunc_ownprop(thr, key)) {
- goto fail_not_configurable;
- }
+ DUK_UNREF(key);
}
/* non-object base, no offending virtual property */
@@ -56118,17 +57651,17 @@ DUK_INTERNAL duk_bool_t duk_hobject_delprop(duk_hthread *thr, duk_tval *tv_obj,
goto done_rc;
done_rc:
- duk_set_top(ctx, entry_top);
+ duk_set_top_unsafe(thr, entry_top);
return rc;
fail_invalid_base_uncond:
/* Note: unconditional throw */
- DUK_ASSERT(duk_get_top(ctx) == entry_top);
+ DUK_ASSERT(duk_get_top(thr) == entry_top);
#if defined(DUK_USE_PARANOID_ERRORS)
DUK_ERROR_TYPE(thr, DUK_STR_INVALID_BASE);
#else
DUK_ERROR_FMT2(thr, DUK_ERR_TYPE_ERROR, "cannot delete property %s of %s",
- duk_push_string_tval_readable(ctx, tv_key), duk_push_string_tval_readable(ctx, tv_obj));
+ duk_push_string_tval_readable(thr, tv_key), duk_push_string_tval_readable(thr, tv_obj));
#endif
return 0;
@@ -56137,7 +57670,7 @@ DUK_INTERNAL duk_bool_t duk_hobject_delprop(duk_hthread *thr, duk_tval *tv_obj,
if (throw_flag) {
DUK_ERROR_TYPE(thr, DUK_STR_PROXY_REJECTED);
}
- duk_set_top(ctx, entry_top);
+ duk_set_top_unsafe(thr, entry_top);
return 0;
#endif
@@ -56145,7 +57678,7 @@ DUK_INTERNAL duk_bool_t duk_hobject_delprop(duk_hthread *thr, duk_tval *tv_obj,
if (throw_flag) {
DUK_ERROR_TYPE(thr, DUK_STR_NOT_CONFIGURABLE);
}
- duk_set_top(ctx, entry_top);
+ duk_set_top_unsafe(thr, entry_top);
return 0;
}
@@ -56169,7 +57702,6 @@ DUK_INTERNAL duk_bool_t duk_hobject_delprop(duk_hthread *thr, duk_tval *tv_obj,
*/
DUK_INTERNAL void duk_hobject_define_property_internal(duk_hthread *thr, duk_hobject *obj, duk_hstring *key, duk_small_uint_t flags) {
- duk_context *ctx = (duk_context *) thr;
duk_propdesc desc;
duk_uint32_t arr_idx;
duk_int_t e_idx;
@@ -56179,7 +57711,7 @@ DUK_INTERNAL void duk_hobject_define_property_internal(duk_hthread *thr, duk_hob
DUK_DDD(DUK_DDDPRINT("define new property (internal): thr=%p, obj=%!O, key=%!O, flags=0x%02lx, val=%!T",
(void *) thr, (duk_heaphdr *) obj, (duk_heaphdr *) key,
- (unsigned long) flags, (duk_tval *) duk_get_tval(ctx, -1)));
+ (unsigned long) flags, (duk_tval *) duk_get_tval(thr, -1)));
DUK_ASSERT(thr != NULL);
DUK_ASSERT(thr->heap != NULL);
@@ -56187,7 +57719,7 @@ DUK_INTERNAL void duk_hobject_define_property_internal(duk_hthread *thr, duk_hob
DUK_ASSERT(key != NULL);
DUK_ASSERT(!DUK_HEAPHDR_HAS_READONLY((duk_heaphdr *) obj));
DUK_ASSERT_VALSTACK_SPACE(thr, DUK__VALSTACK_SPACE);
- DUK_ASSERT(duk_is_valid_index(ctx, -1)); /* contains value */
+ DUK_ASSERT(duk_is_valid_index(thr, -1)); /* contains value */
arr_idx = DUK_HSTRING_GET_ARRIDX_SLOW(key);
@@ -56229,7 +57761,7 @@ DUK_INTERNAL void duk_hobject_define_property_internal(duk_hthread *thr, duk_hob
duk_uint32_t prev_len;
prev_len = ((duk_harray *) obj)->length;
#endif
- new_len = duk__to_new_array_length_checked(thr, DUK_GET_TVAL_NEGIDX(ctx, -1));
+ new_len = duk__to_new_array_length_checked(thr, DUK_GET_TVAL_NEGIDX(thr, -1));
((duk_harray *) obj)->length = new_len;
DUK_D(DUK_DPRINT("internal define property for array .length: %ld -> %ld",
(long) prev_len, (long) ((duk_harray *) obj)->length));
@@ -56259,7 +57791,7 @@ DUK_INTERNAL void duk_hobject_define_property_internal(duk_hthread *thr, duk_hob
}
DUK_DDD(DUK_DDDPRINT("property does not exist, object belongs in entry part -> allocate new entry and write value and attributes"));
- e_idx = duk__alloc_entry_checked(thr, obj, key); /* increases key refcount */
+ e_idx = duk__hobject_alloc_entry_checked(thr, obj, key); /* increases key refcount */
DUK_ASSERT(e_idx >= 0);
DUK_HOBJECT_E_SET_FLAGS(thr->heap, obj, e_idx, propflags);
tv1 = DUK_HOBJECT_E_GET_VALUE_TVAL_PTR(thr->heap, obj, e_idx);
@@ -56270,7 +57802,7 @@ DUK_INTERNAL void duk_hobject_define_property_internal(duk_hthread *thr, duk_hob
write_value:
/* tv1 points to value storage */
- tv2 = duk_require_tval(ctx, -1); /* late lookup, avoid side effects */
+ tv2 = duk_require_tval(thr, -1); /* late lookup, avoid side effects */
DUK_DDD(DUK_DDDPRINT("writing/updating value: %!T -> %!T",
(duk_tval *) tv1, (duk_tval *) tv2));
@@ -56278,7 +57810,7 @@ DUK_INTERNAL void duk_hobject_define_property_internal(duk_hthread *thr, duk_hob
goto pop_exit;
pop_exit:
- duk_pop(ctx); /* remove in_val */
+ duk_pop_unsafe(thr); /* remove in_val */
return;
error_virtual: /* share error message */
@@ -56294,14 +57826,13 @@ DUK_INTERNAL void duk_hobject_define_property_internal(duk_hthread *thr, duk_hob
*/
DUK_INTERNAL void duk_hobject_define_property_internal_arridx(duk_hthread *thr, duk_hobject *obj, duk_uarridx_t arr_idx, duk_small_uint_t flags) {
- duk_context *ctx = (duk_context *) thr;
duk_hstring *key;
duk_tval *tv1, *tv2;
DUK_DDD(DUK_DDDPRINT("define new property (internal) arr_idx fast path: thr=%p, obj=%!O, "
"arr_idx=%ld, flags=0x%02lx, val=%!T",
(void *) thr, obj, (long) arr_idx, (unsigned long) flags,
- (duk_tval *) duk_get_tval(ctx, -1)));
+ (duk_tval *) duk_get_tval(thr, -1)));
DUK_ASSERT(thr != NULL);
DUK_ASSERT(thr->heap != NULL);
@@ -56322,23 +57853,23 @@ DUK_INTERNAL void duk_hobject_define_property_internal_arridx(duk_hthread *thr,
DUK_ASSERT(arr_idx < DUK_HOBJECT_GET_ASIZE(obj));
tv1 = DUK_HOBJECT_A_GET_VALUE_PTR(thr->heap, obj, arr_idx);
- tv2 = duk_require_tval(ctx, -1);
+ tv2 = duk_require_tval(thr, -1);
DUK_TVAL_SET_TVAL_UPDREF(thr, tv1, tv2); /* side effects */
- duk_pop(ctx); /* [ ...val ] -> [ ... ] */
+ duk_pop_unsafe(thr); /* [ ...val ] -> [ ... ] */
return;
}
DUK_DDD(DUK_DDDPRINT("define property fast path didn't work, use slow path"));
- key = duk_push_uint_to_hstring(ctx, (duk_uint_t) arr_idx);
+ key = duk_push_uint_to_hstring(thr, (duk_uint_t) arr_idx);
DUK_ASSERT(key != NULL);
- duk_insert(ctx, -2); /* [ ... val key ] -> [ ... key val ] */
+ duk_insert(thr, -2); /* [ ... val key ] -> [ ... key val ] */
duk_hobject_define_property_internal(thr, obj, key, flags);
- duk_pop(ctx); /* [ ... key ] -> [ ... ] */
+ duk_pop_unsafe(thr); /* [ ... key ] -> [ ... ] */
}
/*
@@ -56346,10 +57877,9 @@ DUK_INTERNAL void duk_hobject_define_property_internal_arridx(duk_hthread *thr,
*/
DUK_INTERNAL duk_size_t duk_hobject_get_length(duk_hthread *thr, duk_hobject *obj) {
- duk_context *ctx = (duk_context *) thr;
duk_double_t val;
- DUK_ASSERT_CTX_VALID(ctx);
+ DUK_ASSERT_CTX_VALID(thr);
DUK_ASSERT(obj != NULL);
/* Fast path for Arrays. */
@@ -56358,13 +57888,13 @@ DUK_INTERNAL duk_size_t duk_hobject_get_length(duk_hthread *thr, duk_hobject *ob
}
/* Slow path, .length can be e.g. accessor, obj can be a Proxy, etc. */
- duk_push_hobject(ctx, obj);
- duk_push_hstring_stridx(ctx, DUK_STRIDX_LENGTH);
+ duk_push_hobject(thr, obj);
+ duk_push_hstring_stridx(thr, DUK_STRIDX_LENGTH);
(void) duk_hobject_getprop(thr,
- DUK_GET_TVAL_NEGIDX(ctx, -2),
- DUK_GET_TVAL_NEGIDX(ctx, -1));
- val = duk_to_number_m1(ctx);
- duk_pop_3(ctx);
+ DUK_GET_TVAL_NEGIDX(thr, -2),
+ DUK_GET_TVAL_NEGIDX(thr, -1));
+ val = duk_to_number_m1(thr);
+ duk_pop_3_unsafe(thr);
/* This isn't part of Ecmascript semantics; return a value within
* duk_size_t range, or 0 otherwise.
@@ -56416,31 +57946,27 @@ DUK_INTERNAL duk_bool_t duk_hobject_has_finalizer_fast_raw(duk_hobject *obj) {
* [ ... key ] -> [ ... desc/undefined ]
*/
-DUK_INTERNAL void duk_hobject_object_get_own_property_descriptor(duk_context *ctx, duk_idx_t obj_idx) {
- duk_hthread *thr = (duk_hthread *) ctx;
+DUK_INTERNAL void duk_hobject_object_get_own_property_descriptor(duk_hthread *thr, duk_idx_t obj_idx) {
duk_hobject *obj;
duk_hstring *key;
duk_propdesc pd;
- duk_bool_t rc;
- DUK_ASSERT(ctx != NULL);
DUK_ASSERT(thr != NULL);
DUK_ASSERT(thr->heap != NULL);
- obj = duk_require_hobject_promote_mask(ctx, obj_idx, DUK_TYPE_MASK_LIGHTFUNC | DUK_TYPE_MASK_BUFFER);
- key = duk_to_property_key_hstring(ctx, -1);
+ obj = duk_require_hobject_promote_mask(thr, obj_idx, DUK_TYPE_MASK_LIGHTFUNC | DUK_TYPE_MASK_BUFFER);
+ key = duk_to_property_key_hstring(thr, -1);
DUK_ASSERT(key != NULL);
DUK_ASSERT_VALSTACK_SPACE(thr, DUK__VALSTACK_SPACE);
- rc = duk_hobject_get_own_propdesc(thr, obj, key, &pd, DUK_GETDESC_FLAG_PUSH_VALUE);
- if (!rc) {
- duk_push_undefined(ctx);
- duk_remove_m2(ctx);
+ if (!duk_hobject_get_own_propdesc(thr, obj, key, &pd, DUK_GETDESC_FLAG_PUSH_VALUE)) {
+ duk_push_undefined(thr);
+ duk_remove_m2(thr);
return;
}
- duk_push_object(ctx);
+ duk_push_object(thr);
/* [ ... key value desc ] */
@@ -56449,32 +57975,32 @@ DUK_INTERNAL void duk_hobject_object_get_own_property_descriptor(duk_context *ct
* still have the property present with the value 'undefined'.
*/
if (pd.get) {
- duk_push_hobject(ctx, pd.get);
+ duk_push_hobject(thr, pd.get);
} else {
- duk_push_undefined(ctx);
+ duk_push_undefined(thr);
}
- duk_put_prop_stridx_short(ctx, -2, DUK_STRIDX_GET);
+ duk_put_prop_stridx_short(thr, -2, DUK_STRIDX_GET);
if (pd.set) {
- duk_push_hobject(ctx, pd.set);
+ duk_push_hobject(thr, pd.set);
} else {
- duk_push_undefined(ctx);
+ duk_push_undefined(thr);
}
- duk_put_prop_stridx_short(ctx, -2, DUK_STRIDX_SET);
+ duk_put_prop_stridx_short(thr, -2, DUK_STRIDX_SET);
} else {
- duk_dup_m2(ctx);
- duk_put_prop_stridx_short(ctx, -2, DUK_STRIDX_VALUE);
- duk_push_boolean(ctx, DUK_PROPDESC_IS_WRITABLE(&pd));
- duk_put_prop_stridx_short(ctx, -2, DUK_STRIDX_WRITABLE);
+ duk_dup_m2(thr);
+ duk_put_prop_stridx_short(thr, -2, DUK_STRIDX_VALUE);
+ duk_push_boolean(thr, DUK_PROPDESC_IS_WRITABLE(&pd));
+ duk_put_prop_stridx_short(thr, -2, DUK_STRIDX_WRITABLE);
}
- duk_push_boolean(ctx, DUK_PROPDESC_IS_ENUMERABLE(&pd));
- duk_put_prop_stridx_short(ctx, -2, DUK_STRIDX_ENUMERABLE);
- duk_push_boolean(ctx, DUK_PROPDESC_IS_CONFIGURABLE(&pd));
- duk_put_prop_stridx_short(ctx, -2, DUK_STRIDX_CONFIGURABLE);
+ duk_push_boolean(thr, DUK_PROPDESC_IS_ENUMERABLE(&pd));
+ duk_put_prop_stridx_short(thr, -2, DUK_STRIDX_ENUMERABLE);
+ duk_push_boolean(thr, DUK_PROPDESC_IS_CONFIGURABLE(&pd));
+ duk_put_prop_stridx_short(thr, -2, DUK_STRIDX_CONFIGURABLE);
/* [ ... key value desc ] */
- duk_replace(ctx, -3);
- duk_pop(ctx); /* -> [ ... desc ] */
+ duk_replace(thr, -3);
+ duk_pop_unsafe(thr); /* -> [ ... desc ] */
}
/*
@@ -56494,13 +58020,12 @@ DUK_INTERNAL void duk_hobject_object_get_own_property_descriptor(duk_context *ct
/* XXX: very basic optimization -> duk_get_prop_stridx_top */
DUK_INTERNAL
-void duk_hobject_prepare_property_descriptor(duk_context *ctx,
+void duk_hobject_prepare_property_descriptor(duk_hthread *thr,
duk_idx_t idx_in,
duk_uint_t *out_defprop_flags,
duk_idx_t *out_idx_value,
duk_hobject **out_getter,
duk_hobject **out_setter) {
- duk_hthread *thr = (duk_hthread *) ctx;
duk_idx_t idx_value = -1;
duk_hobject *getter = NULL;
duk_hobject *setter = NULL;
@@ -56508,7 +58033,6 @@ void duk_hobject_prepare_property_descriptor(duk_context *ctx,
duk_bool_t is_acc_desc = 0;
duk_uint_t defprop_flags = 0;
- DUK_ASSERT(ctx != NULL);
DUK_ASSERT(out_defprop_flags != NULL);
DUK_ASSERT(out_idx_value != NULL);
DUK_ASSERT(out_getter != NULL);
@@ -56516,8 +58040,8 @@ void duk_hobject_prepare_property_descriptor(duk_context *ctx,
DUK_ASSERT(idx_in <= 0x7fffL); /* short variants would be OK, but not used to avoid shifts */
/* Must be an object, otherwise TypeError (E5.1 Section 8.10.5, step 1). */
- idx_in = duk_require_normalize_index(ctx, idx_in);
- (void) duk_require_hobject(ctx, idx_in);
+ idx_in = duk_require_normalize_index(thr, idx_in);
+ (void) duk_require_hobject(thr, idx_in);
/* The coercion order must match the ToPropertyDescriptor() algorithm
* so that side effects in coercion happen in the correct order.
@@ -56525,23 +58049,23 @@ void duk_hobject_prepare_property_descriptor(duk_context *ctx,
* although it doesn't matter in practice.)
*/
- if (duk_get_prop_stridx(ctx, idx_in, DUK_STRIDX_VALUE)) {
+ if (duk_get_prop_stridx(thr, idx_in, DUK_STRIDX_VALUE)) {
is_data_desc = 1;
defprop_flags |= DUK_DEFPROP_HAVE_VALUE;
- idx_value = duk_get_top_index(ctx);
+ idx_value = duk_get_top_index(thr);
}
- if (duk_get_prop_stridx(ctx, idx_in, DUK_STRIDX_WRITABLE)) {
+ if (duk_get_prop_stridx(thr, idx_in, DUK_STRIDX_WRITABLE)) {
is_data_desc = 1;
- if (duk_to_boolean(ctx, -1)) {
+ if (duk_to_boolean(thr, -1)) {
defprop_flags |= DUK_DEFPROP_HAVE_WRITABLE | DUK_DEFPROP_WRITABLE;
} else {
defprop_flags |= DUK_DEFPROP_HAVE_WRITABLE;
}
}
- if (duk_get_prop_stridx(ctx, idx_in, DUK_STRIDX_GET)) {
- duk_tval *tv = duk_require_tval(ctx, -1);
+ if (duk_get_prop_stridx(thr, idx_in, DUK_STRIDX_GET)) {
+ duk_tval *tv = duk_require_tval(thr, -1);
duk_hobject *h_get;
if (DUK_TVAL_IS_UNDEFINED(tv)) {
@@ -56552,7 +58076,7 @@ void duk_hobject_prepare_property_descriptor(duk_context *ctx,
* lightfuncs don't fit into a property value slot. This
* has some side effects, see test-dev-lightfunc-accessor.js.
*/
- h_get = duk_get_hobject_promote_lfunc(ctx, -1);
+ h_get = duk_get_hobject_promote_lfunc(thr, -1);
if (h_get == NULL || !DUK_HOBJECT_IS_CALLABLE(h_get)) {
goto type_error;
}
@@ -56562,8 +58086,8 @@ void duk_hobject_prepare_property_descriptor(duk_context *ctx,
defprop_flags |= DUK_DEFPROP_HAVE_GETTER;
}
- if (duk_get_prop_stridx(ctx, idx_in, DUK_STRIDX_SET)) {
- duk_tval *tv = duk_require_tval(ctx, -1);
+ if (duk_get_prop_stridx(thr, idx_in, DUK_STRIDX_SET)) {
+ duk_tval *tv = duk_require_tval(thr, -1);
duk_hobject *h_set;
if (DUK_TVAL_IS_UNDEFINED(tv)) {
@@ -56574,7 +58098,7 @@ void duk_hobject_prepare_property_descriptor(duk_context *ctx,
* lightfuncs don't fit into a property value slot. This
* has some side effects, see test-dev-lightfunc-accessor.js.
*/
- h_set = duk_get_hobject_promote_lfunc(ctx, -1);
+ h_set = duk_get_hobject_promote_lfunc(thr, -1);
if (h_set == NULL || !DUK_HOBJECT_IS_CALLABLE(h_set)) {
goto type_error;
}
@@ -56584,16 +58108,16 @@ void duk_hobject_prepare_property_descriptor(duk_context *ctx,
defprop_flags |= DUK_DEFPROP_HAVE_SETTER;
}
- if (duk_get_prop_stridx(ctx, idx_in, DUK_STRIDX_ENUMERABLE)) {
- if (duk_to_boolean(ctx, -1)) {
+ if (duk_get_prop_stridx(thr, idx_in, DUK_STRIDX_ENUMERABLE)) {
+ if (duk_to_boolean(thr, -1)) {
defprop_flags |= DUK_DEFPROP_HAVE_ENUMERABLE | DUK_DEFPROP_ENUMERABLE;
} else {
defprop_flags |= DUK_DEFPROP_HAVE_ENUMERABLE;
}
}
- if (duk_get_prop_stridx(ctx, idx_in, DUK_STRIDX_CONFIGURABLE)) {
- if (duk_to_boolean(ctx, -1)) {
+ if (duk_get_prop_stridx(thr, idx_in, DUK_STRIDX_CONFIGURABLE)) {
+ if (duk_to_boolean(thr, -1)) {
defprop_flags |= DUK_DEFPROP_HAVE_CONFIGURABLE | DUK_DEFPROP_CONFIGURABLE;
} else {
defprop_flags |= DUK_DEFPROP_HAVE_CONFIGURABLE;
@@ -56637,7 +58161,7 @@ void duk_hobject_prepare_property_descriptor(duk_context *ctx,
/* XXX: this is a major target for size optimization */
DUK_INTERNAL
-duk_bool_t duk_hobject_define_property_helper(duk_context *ctx,
+duk_bool_t duk_hobject_define_property_helper(duk_hthread *thr,
duk_uint_t defprop_flags,
duk_hobject *obj,
duk_hstring *key,
@@ -56645,7 +58169,6 @@ duk_bool_t duk_hobject_define_property_helper(duk_context *ctx,
duk_hobject *get,
duk_hobject *set,
duk_bool_t throw_flag) {
- duk_hthread *thr = (duk_hthread *) ctx;
duk_uint32_t arr_idx;
duk_tval tv;
duk_bool_t has_enumerable;
@@ -56667,7 +58190,6 @@ duk_bool_t duk_hobject_define_property_helper(duk_context *ctx,
DUK_ASSERT(thr != NULL);
DUK_ASSERT(thr->heap != NULL);
- DUK_ASSERT(ctx != NULL);
DUK_ASSERT(obj != NULL);
DUK_ASSERT(key != NULL);
/* idx_value may be < 0 (no value), set and get may be NULL */
@@ -56704,7 +58226,7 @@ duk_bool_t duk_hobject_define_property_helper(duk_context *ctx,
(long) has_enumerable, (long) is_enumerable,
(long) has_configurable, (long) is_configurable,
(long) has_writable, (long) is_writable,
- (long) has_value, (duk_tval *) (idx_value >= 0 ? duk_get_tval(ctx, idx_value) : NULL),
+ (long) has_value, (duk_tval *) (idx_value >= 0 ? duk_get_tval(thr, idx_value) : NULL),
(long) has_get, (void *) get, (duk_heaphdr *) get,
(long) has_set, (void *) set, (duk_heaphdr *) set,
(long) arr_idx, (long) throw_flag));
@@ -56739,9 +58261,9 @@ duk_bool_t duk_hobject_define_property_helper(duk_context *ctx,
arrlen_old_len = a->length;
DUK_ASSERT(idx_value >= 0);
- arrlen_new_len = duk__to_new_array_length_checked(thr, DUK_GET_TVAL_POSIDX(ctx, idx_value));
- duk_push_u32(ctx, arrlen_new_len);
- duk_replace(ctx, idx_value); /* step 3.e: replace 'Desc.[[Value]]' */
+ arrlen_new_len = duk__to_new_array_length_checked(thr, DUK_GET_TVAL_POSIDX(thr, idx_value));
+ duk_push_u32(thr, arrlen_new_len);
+ duk_replace(thr, idx_value); /* step 3.e: replace 'Desc.[[Value]]' */
DUK_DDD(DUK_DDDPRINT("old_len=%ld, new_len=%ld", (long) arrlen_old_len, (long) arrlen_new_len));
@@ -56870,7 +58392,7 @@ duk_bool_t duk_hobject_define_property_helper(duk_context *ctx,
}
/* write to entry part */
- e_idx = duk__alloc_entry_checked(thr, obj, key);
+ e_idx = duk__hobject_alloc_entry_checked(thr, obj, key);
DUK_ASSERT(e_idx >= 0);
DUK_HOBJECT_E_SET_VALUE_GETTER(thr->heap, obj, e_idx, get);
@@ -56900,7 +58422,7 @@ duk_bool_t duk_hobject_define_property_helper(duk_context *ctx,
new_flags |= DUK_PROPDESC_FLAG_CONFIGURABLE;
}
if (has_value) {
- duk_tval *tv_tmp = duk_require_tval(ctx, idx_value);
+ duk_tval *tv_tmp = duk_require_tval(thr, idx_value);
DUK_TVAL_SET_TVAL(&tv, tv_tmp);
} else {
DUK_TVAL_SET_UNDEFINED(&tv); /* default value */
@@ -56923,7 +58445,7 @@ duk_bool_t duk_hobject_define_property_helper(duk_context *ctx,
}
/* write to entry part */
- e_idx = duk__alloc_entry_checked(thr, obj, key);
+ e_idx = duk__hobject_alloc_entry_checked(thr, obj, key);
DUK_ASSERT(e_idx >= 0);
tv2 = DUK_HOBJECT_E_GET_VALUE_TVAL_PTR(thr->heap, obj, e_idx);
DUK_TVAL_SET_TVAL(tv2, &tv);
@@ -56976,8 +58498,8 @@ duk_bool_t duk_hobject_define_property_helper(duk_context *ctx,
goto need_check;
}
- tmp1 = duk_require_tval(ctx, -1); /* curr value */
- tmp2 = duk_require_tval(ctx, idx_value); /* new value */
+ tmp1 = duk_require_tval(thr, -1); /* curr value */
+ tmp2 = duk_require_tval(thr, idx_value); /* new value */
if (!duk_js_samevalue(tmp1, tmp2)) {
goto need_check;
}
@@ -57096,7 +58618,7 @@ duk_bool_t duk_hobject_define_property_helper(duk_context *ctx,
if (curr.a_idx >= 0) {
DUK_DDD(DUK_DDDPRINT("property to convert is stored in an array entry, abandon array and re-lookup"));
duk__abandon_array_checked(thr, obj);
- duk_pop(ctx); /* remove old value */
+ duk_pop_unsafe(thr); /* remove old value */
rc = duk__get_own_propdesc_raw(thr, obj, key, arr_idx, &curr, DUK_GETDESC_FLAG_PUSH_VALUE);
DUK_UNREF(rc);
DUK_ASSERT(rc != 0);
@@ -57172,8 +58694,8 @@ duk_bool_t duk_hobject_define_property_helper(duk_context *ctx,
}
/* Note: changing from writable to non-writable is OK */
if (!(curr.flags & DUK_PROPDESC_FLAG_WRITABLE) && has_value) {
- duk_tval *tmp1 = duk_require_tval(ctx, -1); /* curr value */
- duk_tval *tmp2 = duk_require_tval(ctx, idx_value); /* new value */
+ duk_tval *tmp1 = duk_require_tval(thr, -1); /* curr value */
+ duk_tval *tmp2 = duk_require_tval(thr, idx_value); /* new value */
if (!duk_js_samevalue(tmp1, tmp2)) {
goto fail_not_configurable;
}
@@ -57244,7 +58766,7 @@ duk_bool_t duk_hobject_define_property_helper(duk_context *ctx,
DUK_ASSERT(!has_get);
DUK_ASSERT(idx_value >= 0); /* must be: if attributes match and we get here the value must differ (otherwise no change) */
- tv2 = duk_require_tval(ctx, idx_value);
+ tv2 = duk_require_tval(thr, idx_value);
tv1 = DUK_HOBJECT_A_GET_VALUE_PTR(thr->heap, obj, curr.a_idx);
DUK_TVAL_SET_TVAL_UPDREF(thr, tv1, tv2); /* side effects; may invalidate a_idx */
goto success_exotics;
@@ -57252,7 +58774,7 @@ duk_bool_t duk_hobject_define_property_helper(duk_context *ctx,
DUK_DDD(DUK_DDDPRINT("array index, new property attributes do not match array defaults, abandon array and re-lookup"));
duk__abandon_array_checked(thr, obj);
- duk_pop(ctx); /* remove old value */
+ duk_pop_unsafe(thr); /* remove old value */
rc = duk__get_own_propdesc_raw(thr, obj, key, arr_idx, &curr, DUK_GETDESC_FLAG_PUSH_VALUE);
DUK_UNREF(rc);
DUK_ASSERT(rc != 0);
@@ -57332,7 +58854,7 @@ duk_bool_t duk_hobject_define_property_helper(duk_context *ctx,
if (curr.e_idx >= 0) {
DUK_ASSERT(!DUK_HOBJECT_E_SLOT_IS_ACCESSOR(thr->heap, obj, curr.e_idx));
- tv2 = duk_require_tval(ctx, idx_value);
+ tv2 = duk_require_tval(thr, idx_value);
tv1 = DUK_HOBJECT_E_GET_VALUE_TVAL_PTR(thr->heap, obj, curr.e_idx);
DUK_TVAL_SET_TVAL_UPDREF(thr, tv1, tv2); /* side effects; may invalidate e_idx */
} else {
@@ -57462,17 +58984,17 @@ duk_bool_t duk_hobject_define_property_helper(duk_context *ctx,
DUK_DDD(DUK_DDDPRINT("defineProperty successful, key mapped to arguments 'map', "
"update bound value (variable/argument)"));
- varname = duk_require_hstring(ctx, -1);
+ varname = duk_require_hstring(thr, -1);
DUK_ASSERT(varname != NULL);
DUK_DDD(DUK_DDDPRINT("arguments object automatic putvar for a bound variable; "
"key=%!O, varname=%!O, value=%!T",
(duk_heaphdr *) key,
(duk_heaphdr *) varname,
- (duk_tval *) duk_require_tval(ctx, idx_value)));
+ (duk_tval *) duk_require_tval(thr, idx_value)));
/* strict flag for putvar comes from our caller (currently: fixed) */
- duk_js_putvar_envrec(thr, varenv, varname, duk_require_tval(ctx, idx_value), 1 /*throw_flag*/);
+ duk_js_putvar_envrec(thr, varenv, varname, duk_require_tval(thr, idx_value), 1 /*throw_flag*/);
}
if (has_writable && !is_writable) {
DUK_DDD(DUK_DDDPRINT("defineProperty successful, key mapped to arguments 'map', "
@@ -57512,23 +59034,22 @@ duk_bool_t duk_hobject_define_property_helper(duk_context *ctx,
* Object.prototype.hasOwnProperty() and Object.prototype.propertyIsEnumerable().
*/
-DUK_INTERNAL duk_bool_t duk_hobject_object_ownprop_helper(duk_context *ctx, duk_small_uint_t required_desc_flags) {
- duk_hthread *thr = (duk_hthread *) ctx;
+DUK_INTERNAL duk_bool_t duk_hobject_object_ownprop_helper(duk_hthread *thr, duk_small_uint_t required_desc_flags) {
duk_hstring *h_v;
duk_hobject *h_obj;
duk_propdesc desc;
duk_bool_t ret;
/* coercion order matters */
- h_v = duk_to_hstring_acceptsymbol(ctx, 0);
+ h_v = duk_to_hstring_acceptsymbol(thr, 0);
DUK_ASSERT(h_v != NULL);
- h_obj = duk_push_this_coercible_to_object(ctx);
+ h_obj = duk_push_this_coercible_to_object(thr);
DUK_ASSERT(h_obj != NULL);
ret = duk_hobject_get_own_propdesc(thr, h_obj, h_v, &desc, 0 /*flags*/); /* don't push value */
- duk_push_boolean(ctx, ret && ((desc.flags & required_desc_flags) == required_desc_flags));
+ duk_push_boolean(thr, ret && ((desc.flags & required_desc_flags) == required_desc_flags));
return 1;
}
@@ -57694,7 +59215,7 @@ DUK_INTERNAL duk_ucodepoint_t duk_hstring_char_code_at_raw(duk_hthread *thr, duk
DUK_ASSERT_DISABLE(pos >= 0); /* unsigned */
DUK_ASSERT(pos < (duk_uint_t) DUK_HSTRING_GET_CHARLEN(h));
- boff = duk_heap_strcache_offset_char2byte(thr, h, (duk_uint32_t) pos);
+ boff = (duk_uint32_t) duk_heap_strcache_offset_char2byte(thr, h, (duk_uint32_t) pos);
DUK_DDD(DUK_DDDPRINT("charCodeAt: pos=%ld -> boff=%ld, str=%!O",
(long) pos, (long) boff, (duk_heaphdr *) h));
DUK_ASSERT_DISABLE(boff >= 0);
@@ -57719,7 +59240,7 @@ DUK_INTERNAL duk_ucodepoint_t duk_hstring_char_code_at_raw(duk_hthread *thr, duk
cp2 = 0; /* If call fails, this is left untouched and won't match cp2 check. */
(void) duk_unicode_decode_xutf8(thr, &p, p_start, p_end, &cp2);
if (cp2 >= 0xdc00UL && cp2 <= 0xdfffUL) {
- cp1 = ((cp1 - 0xd800UL) << 10) + (cp2 - 0xdc00UL) + 0x10000UL;
+ cp1 = (duk_ucodepoint_t) (((cp1 - 0xd800UL) << 10) + (cp2 - 0xdc00UL) + 0x10000UL);
}
}
} else {
@@ -57730,9 +59251,46 @@ DUK_INTERNAL duk_ucodepoint_t duk_hstring_char_code_at_raw(duk_hthread *thr, duk
}
/*
- * duk_hstring charlen access
+ * duk_hstring charlen, when lazy charlen disabled
*/
+#if !defined(DUK_USE_HSTRING_LAZY_CLEN)
+#if !defined(DUK_USE_HSTRING_CLEN)
+#error non-lazy duk_hstring charlen but DUK_USE_HSTRING_CLEN not set
+#endif
+DUK_INTERNAL void duk_hstring_init_charlen(duk_hstring *h) {
+ duk_uint32_t clen;
+
+ DUK_ASSERT(h != NULL);
+ DUK_ASSERT(!DUK_HSTRING_HAS_ASCII(h));
+ DUK_ASSERT(!DUK_HEAPHDR_HAS_READONLY((duk_heaphdr *) h));
+
+ clen = duk_unicode_unvalidated_utf8_length(DUK_HSTRING_GET_DATA(h), DUK_HSTRING_GET_BYTELEN(h));
+#if defined(DUK_USE_STRLEN16)
+ DUK_ASSERT(clen <= 0xffffUL); /* Bytelength checked during interning. */
+ h->clen16 = (duk_uint16_t) clen;
+#else
+ h->clen = (duk_uint32_t) clen;
+#endif
+ if (DUK_LIKELY(clen == DUK_HSTRING_GET_BYTELEN(h))) {
+ DUK_HSTRING_SET_ASCII(h);
+ }
+}
+
+DUK_INTERNAL DUK_HOT duk_size_t duk_hstring_get_charlen(duk_hstring *h) {
+#if defined(DUK_USE_STRLEN16)
+ return h->clen16;
+#else
+ return h->clen;
+#endif
+}
+#endif /* !DUK_USE_HSTRING_LAZY_CLEN */
+
+/*
+ * duk_hstring charlen, when lazy charlen enabled
+ */
+
+#if defined(DUK_USE_HSTRING_LAZY_CLEN)
#if defined(DUK_USE_HSTRING_CLEN)
DUK_LOCAL DUK_COLD duk_size_t duk__hstring_get_charlen_slowpath(duk_hstring *h) {
duk_size_t res;
@@ -57810,6 +59368,27 @@ DUK_INTERNAL DUK_HOT duk_size_t duk_hstring_get_charlen(duk_hstring *h) {
return duk__hstring_get_charlen_slowpath(h);
}
#endif /* DUK_USE_HSTRING_CLEN */
+#endif /* DUK_USE_HSTRING_LAZY_CLEN */
+
+/*
+ * Compare duk_hstring to an ASCII cstring.
+ */
+
+DUK_INTERNAL duk_bool_t duk_hstring_equals_ascii_cstring(duk_hstring *h, const char *cstr) {
+ duk_size_t len;
+
+ DUK_ASSERT(h != NULL);
+ DUK_ASSERT(cstr != NULL);
+
+ len = DUK_STRLEN(cstr);
+ if (len != DUK_HSTRING_GET_BYTELEN(h)) {
+ return 0;
+ }
+ if (DUK_MEMCMP((const void *) cstr, (const void *) DUK_HSTRING_GET_DATA(h), len) == 0) {
+ return 1;
+ }
+ return 0;
+}
/*
* duk_hthread allocation and freeing.
*/
@@ -57830,23 +59409,21 @@ DUK_INTERNAL duk_bool_t duk_hthread_init_stacks(duk_heap *heap, duk_hthread *thr
DUK_ASSERT(thr != NULL);
DUK_ASSERT(thr->valstack == NULL);
DUK_ASSERT(thr->valstack_end == NULL);
+ DUK_ASSERT(thr->valstack_alloc_end == NULL);
DUK_ASSERT(thr->valstack_bottom == NULL);
DUK_ASSERT(thr->valstack_top == NULL);
- DUK_ASSERT(thr->callstack == NULL);
DUK_ASSERT(thr->callstack_curr == NULL);
- DUK_ASSERT(thr->catchstack == NULL);
/* valstack */
+ DUK_ASSERT(DUK_VALSTACK_API_ENTRY_MINIMUM <= DUK_VALSTACK_INITIAL_SIZE);
alloc_size = sizeof(duk_tval) * DUK_VALSTACK_INITIAL_SIZE;
thr->valstack = (duk_tval *) DUK_ALLOC(heap, alloc_size);
if (!thr->valstack) {
goto fail;
}
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_end = thr->valstack + DUK_VALSTACK_API_ENTRY_MINIMUM;
+ thr->valstack_alloc_end = thr->valstack + DUK_VALSTACK_INITIAL_SIZE;
thr->valstack_bottom = thr->valstack;
thr->valstack_top = thr->valstack;
@@ -57854,37 +59431,13 @@ DUK_INTERNAL duk_bool_t duk_hthread_init_stacks(duk_heap *heap, duk_hthread *thr
DUK_TVAL_SET_UNDEFINED(&thr->valstack[i]);
}
- /* callstack */
- alloc_size = sizeof(duk_activation) * DUK_CALLSTACK_INITIAL_SIZE;
- thr->callstack = (duk_activation *) DUK_ALLOC(heap, alloc_size);
- if (!thr->callstack) {
- goto fail;
- }
- DUK_MEMZERO(thr->callstack, alloc_size);
- thr->callstack_size = DUK_CALLSTACK_INITIAL_SIZE;
- DUK_ASSERT(thr->callstack_top == 0);
- DUK_ASSERT(thr->callstack_curr == NULL);
-
- /* catchstack */
- alloc_size = sizeof(duk_catcher) * DUK_CATCHSTACK_INITIAL_SIZE;
- thr->catchstack = (duk_catcher *) DUK_ALLOC(heap, alloc_size);
- if (!thr->catchstack) {
- goto fail;
- }
- DUK_MEMZERO(thr->catchstack, alloc_size);
- thr->catchstack_size = DUK_CATCHSTACK_INITIAL_SIZE;
- DUK_ASSERT(thr->catchstack_top == 0);
-
return 1;
fail:
DUK_FREE(heap, thr->valstack);
- DUK_FREE(heap, thr->callstack);
- DUK_FREE(heap, thr->catchstack);
+ DUK_ASSERT(thr->callstack_curr == NULL);
thr->valstack = NULL;
- thr->callstack = NULL;
- thr->catchstack = NULL;
return 0;
}
@@ -57895,18 +59448,6 @@ DUK_INTERNAL void *duk_hthread_get_valstack_ptr(duk_heap *heap, void *ud) {
DUK_UNREF(heap);
return (void *) thr->valstack;
}
-
-DUK_INTERNAL void *duk_hthread_get_callstack_ptr(duk_heap *heap, void *ud) {
- duk_hthread *thr = (duk_hthread *) ud;
- DUK_UNREF(heap);
- return (void *) thr->callstack;
-}
-
-DUK_INTERNAL void *duk_hthread_get_catchstack_ptr(duk_heap *heap, void *ud) {
- duk_hthread *thr = (duk_hthread *) ud;
- DUK_UNREF(heap);
- return (void *) thr->catchstack;
-}
/*
* Initialize built-in objects. Current thread must have a valstack
* and initialization errors may longjmp, so a setjmp() catch point
@@ -57943,7 +59484,6 @@ DUK_INTERNAL void *duk_hthread_get_catchstack_ptr(duk_heap *heap, void *ud) {
#if defined(DUK_USE_ROM_OBJECTS)
#if defined(DUK_USE_ROM_GLOBAL_CLONE) || defined(DUK_USE_ROM_GLOBAL_INHERIT)
DUK_LOCAL void duk__duplicate_ram_global_object(duk_hthread *thr) {
- duk_context *ctx;
duk_hobject *h_global;
#if defined(DUK_USE_ROM_GLOBAL_CLONE)
duk_hobject *h_oldglobal;
@@ -57952,13 +59492,11 @@ DUK_LOCAL void duk__duplicate_ram_global_object(duk_hthread *thr) {
#endif
duk_hobject *h_objenv;
- ctx = (duk_context *) thr;
-
/* XXX: refactor into internal helper, duk_clone_hobject() */
#if defined(DUK_USE_ROM_GLOBAL_INHERIT)
/* Inherit from ROM-based global object: less RAM usage, less transparent. */
- h_global = duk_push_object_helper(ctx,
+ h_global = duk_push_object_helper(thr,
DUK_HOBJECT_FLAG_EXTENSIBLE |
DUK_HOBJECT_FLAG_FASTREFS |
DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_GLOBAL),
@@ -57969,7 +59507,7 @@ DUK_LOCAL void duk__duplicate_ram_global_object(duk_hthread *thr) {
* fully RAM-based global object. Uses more memory than the inherit
* model but more compliant.
*/
- h_global = duk_push_object_helper(ctx,
+ h_global = duk_push_object_helper(thr,
DUK_HOBJECT_FLAG_EXTENSIBLE |
DUK_HOBJECT_FLAG_FASTREFS |
DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_GLOBAL),
@@ -58020,7 +59558,7 @@ DUK_LOCAL void duk__duplicate_ram_global_object(duk_hthread *thr) {
DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_OBJENV));
DUK_ASSERT(h_objenv != NULL);
DUK_ASSERT(DUK_HOBJECT_GET_PROTOTYPE(thr->heap, h_objenv) == NULL);
- duk_push_hobject(ctx, h_objenv);
+ duk_push_hobject(thr, h_objenv);
DUK_ASSERT(h_global != NULL);
((duk_hobjenv *) h_objenv)->target = h_global;
@@ -58035,7 +59573,7 @@ DUK_LOCAL void duk__duplicate_ram_global_object(duk_hthread *thr) {
DUK_ASSERT_HOBJENV_VALID((duk_hobjenv *) h_objenv);
- duk_pop_2(ctx); /* Pop global object and global env. */
+ duk_pop_2(thr); /* Pop global object and global env. */
}
#endif /* DUK_USE_ROM_GLOBAL_CLONE || DUK_USE_ROM_GLOBAL_INHERIT */
@@ -58062,15 +59600,15 @@ DUK_INTERNAL void duk_hthread_create_builtin_objects(duk_hthread *thr) {
#endif
}
#else /* DUK_USE_ROM_OBJECTS */
-DUK_LOCAL void duk__push_stridx(duk_context *ctx, duk_bitdecoder_ctx *bd) {
+DUK_LOCAL void duk__push_stridx(duk_hthread *thr, duk_bitdecoder_ctx *bd) {
duk_small_uint_t n;
n = (duk_small_uint_t) duk_bd_decode_varuint(bd);
DUK_ASSERT_DISABLE(n >= 0); /* unsigned */
DUK_ASSERT(n < DUK_HEAP_NUM_STRINGS);
- duk_push_hstring_stridx(ctx, n);
+ duk_push_hstring_stridx(thr, n);
}
-DUK_LOCAL void duk__push_string(duk_context *ctx, duk_bitdecoder_ctx *bd) {
+DUK_LOCAL void duk__push_string(duk_hthread *thr, duk_bitdecoder_ctx *bd) {
/* XXX: built-ins data could provide a maximum length that is
* actually needed; bitpacked max length is now 256 bytes.
*/
@@ -58078,21 +59616,21 @@ DUK_LOCAL void duk__push_string(duk_context *ctx, duk_bitdecoder_ctx *bd) {
duk_small_uint_t len;
len = duk_bd_decode_bitpacked_string(bd, tmp);
- duk_push_lstring(ctx, (const char *) tmp, (duk_size_t) len);
+ duk_push_lstring(thr, (const char *) tmp, (duk_size_t) len);
}
-DUK_LOCAL void duk__push_stridx_or_string(duk_context *ctx, duk_bitdecoder_ctx *bd) {
+DUK_LOCAL void duk__push_stridx_or_string(duk_hthread *thr, duk_bitdecoder_ctx *bd) {
duk_small_uint_t n;
n = (duk_small_uint_t) duk_bd_decode_varuint(bd);
if (n == 0) {
- duk__push_string(ctx, bd);
+ duk__push_string(thr, bd);
} else {
n--;
DUK_ASSERT(n < DUK_HEAP_NUM_STRINGS);
- duk_push_hstring_stridx(ctx, n);
+ duk_push_hstring_stridx(thr, n);
}
}
-DUK_LOCAL void duk__push_double(duk_context *ctx, duk_bitdecoder_ctx *bd) {
+DUK_LOCAL void duk__push_double(duk_hthread *thr, duk_bitdecoder_ctx *bd) {
duk_double_union du;
duk_small_uint_t i;
@@ -58103,11 +59641,10 @@ DUK_LOCAL void duk__push_double(duk_context *ctx, duk_bitdecoder_ctx *bd) {
du.uc[i] = (duk_uint8_t) duk_bd_decode(bd, 8);
}
- duk_push_number(ctx, du.d); /* push operation normalizes NaNs */
+ duk_push_number(thr, du.d); /* push operation normalizes NaNs */
}
DUK_INTERNAL void duk_hthread_create_builtin_objects(duk_hthread *thr) {
- duk_context *ctx = (duk_context *) thr;
duk_bitdecoder_ctx bd_ctx;
duk_bitdecoder_ctx *bd = &bd_ctx; /* convenience */
duk_hobject *h;
@@ -58130,12 +59667,14 @@ DUK_INTERNAL void duk_hthread_create_builtin_objects(duk_hthread *thr) {
* into thr->builtins[]. These are objects referenced in some way
* from thr->builtins[] roots but which don't need to be indexed by
* Duktape through thr->builtins[] (e.g. user custom objects).
+ *
+ * Internal prototypes will be incorrect (NULL) at this stage.
*/
- duk_require_stack(ctx, DUK_NUM_ALL_BUILTINS);
+ duk_require_stack(thr, DUK_NUM_ALL_BUILTINS);
DUK_DD(DUK_DDPRINT("create empty built-ins"));
- DUK_ASSERT_TOP(ctx, 0);
+ DUK_ASSERT_TOP(thr, 0);
for (i = 0; i < DUK_NUM_ALL_BUILTINS; i++) {
duk_small_uint_t class_num;
duk_small_int_t len = -1; /* must be signed */
@@ -58163,9 +59702,8 @@ DUK_INTERNAL void duk_hthread_create_builtin_objects(duk_hthread *thr) {
}
/* XXX: set magic directly here? (it could share the c_nargs arg) */
- duk_push_c_function_noexotic(ctx, c_func, c_nargs);
-
- h = duk_known_hobject(ctx, -1);
+ (void) duk_push_c_function_builtin(thr, c_func, c_nargs);
+ h = duk_known_hobject(thr, -1);
/* Currently all built-in native functions are strict.
* duk_push_c_function() now sets strict flag, so
@@ -58175,14 +59713,14 @@ DUK_INTERNAL void duk_hthread_create_builtin_objects(duk_hthread *thr) {
/* XXX: function properties */
- duk__push_stridx_or_string(ctx, bd);
+ duk__push_stridx_or_string(thr, bd);
#if defined(DUK_USE_FUNC_NAME_PROPERTY)
- duk_xdef_prop_stridx_short(ctx,
+ duk_xdef_prop_stridx_short(thr,
-2,
DUK_STRIDX_NAME,
DUK_PROPDESC_FLAGS_C);
#else
- duk_pop(ctx); /* Not very ideal but good enough for now. */
+ duk_pop(thr); /* Not very ideal but good enough for now. */
#endif
/* Almost all global level Function objects are constructable
@@ -58199,7 +59737,7 @@ DUK_INTERNAL void duk_hthread_create_builtin_objects(duk_hthread *thr) {
magic = (duk_int16_t) duk_bd_decode_varuint(bd);
((duk_hnatfunc *) h)->magic = magic;
} else if (class_num == DUK_HOBJECT_CLASS_ARRAY) {
- duk_push_array(ctx);
+ duk_push_array(thr);
} else if (class_num == DUK_HOBJECT_CLASS_OBJENV) {
duk_hobjenv *env;
duk_hobject *global;
@@ -58211,9 +59749,9 @@ DUK_INTERNAL void duk_hthread_create_builtin_objects(duk_hthread *thr) {
DUK_HOBJECT_FLAG_EXTENSIBLE |
DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_OBJENV));
DUK_ASSERT(env->target == NULL);
- duk_push_hobject(ctx, (duk_hobject *) env);
+ duk_push_hobject(thr, (duk_hobject *) env);
- global = duk_known_hobject(ctx, DUK_BIDX_GLOBAL);
+ global = duk_known_hobject(thr, DUK_BIDX_GLOBAL);
DUK_ASSERT(global != NULL);
env->target = global;
DUK_HOBJECT_INCREF(thr, global);
@@ -58223,14 +59761,14 @@ DUK_INTERNAL void duk_hthread_create_builtin_objects(duk_hthread *thr) {
} else {
DUK_ASSERT(class_num != DUK_HOBJECT_CLASS_DECENV);
- (void) duk_push_object_helper(ctx,
+ (void) duk_push_object_helper(thr,
DUK_HOBJECT_FLAG_FASTREFS |
DUK_HOBJECT_FLAG_EXTENSIBLE,
-1); /* no prototype or class yet */
}
- h = duk_known_hobject(ctx, -1);
+ h = duk_known_hobject(thr, -1);
DUK_HOBJECT_SET_CLASS_NUMBER(h, class_num);
if (i < DUK_NUM_BUILTINS) {
@@ -58250,8 +59788,8 @@ DUK_INTERNAL void duk_hthread_create_builtin_objects(duk_hthread *thr) {
*/
DUK_ASSERT(class_num != DUK_HOBJECT_CLASS_ARRAY); /* .length is virtual */
- duk_push_int(ctx, len);
- duk_xdef_prop_stridx_short(ctx,
+ duk_push_int(thr, len);
+ duk_xdef_prop_stridx_short(thr,
-2,
DUK_STRIDX_LENGTH,
DUK_PROPDESC_FLAGS_C);
@@ -58289,7 +59827,8 @@ DUK_INTERNAL void duk_hthread_create_builtin_objects(duk_hthread *thr) {
/*
* Then decode the builtins init data (see genbuiltins.py) to
- * init objects
+ * init objects. Internal prototypes are set at this stage,
+ * with thr->builtins[] populated.
*/
DUK_DD(DUK_DDPRINT("initialize built-in object properties"));
@@ -58298,13 +59837,20 @@ DUK_INTERNAL void duk_hthread_create_builtin_objects(duk_hthread *thr) {
duk_small_uint_t num;
DUK_DDD(DUK_DDDPRINT("initializing built-in object at index %ld", (long) i));
- h = duk_known_hobject(ctx, i);
+ h = duk_known_hobject(thr, (duk_idx_t) i);
t = (duk_small_uint_t) duk_bd_decode_varuint(bd);
if (t > 0) {
t--;
DUK_DDD(DUK_DDDPRINT("set internal prototype: built-in %ld", (long) t));
- DUK_HOBJECT_SET_PROTOTYPE_UPDREF(thr, h, duk_known_hobject(ctx, t));
+ DUK_HOBJECT_SET_PROTOTYPE_UPDREF(thr, h, duk_known_hobject(thr, (duk_idx_t) t));
+ } else if (DUK_HOBJECT_IS_NATFUNC(h)) {
+ /* Standard native built-ins cannot inherit from
+ * %NativeFunctionPrototype%, they are required to
+ * inherit from Function.prototype directly.
+ */
+ DUK_ASSERT(thr->builtins[DUK_BIDX_FUNCTION_PROTOTYPE] != NULL);
+ DUK_HOBJECT_SET_PROTOTYPE_UPDREF(thr, h, thr->builtins[DUK_BIDX_FUNCTION_PROTOTYPE]);
}
t = (duk_small_uint_t) duk_bd_decode_varuint(bd);
@@ -58316,7 +59862,8 @@ DUK_INTERNAL void duk_hthread_create_builtin_objects(duk_hthread *thr) {
*/
t--;
DUK_DDD(DUK_DDDPRINT("set external prototype: built-in %ld", (long) t));
- duk_xdef_prop_stridx_builtin(ctx, i, DUK_STRIDX_PROTOTYPE, t, DUK_PROPDESC_FLAGS_NONE);
+ duk_dup(thr, (duk_idx_t) t);
+ duk_xdef_prop_stridx(thr, (duk_idx_t) i, DUK_STRIDX_PROTOTYPE, DUK_PROPDESC_FLAGS_NONE);
}
t = (duk_small_uint_t) duk_bd_decode_varuint(bd);
@@ -58328,7 +59875,8 @@ DUK_INTERNAL void duk_hthread_create_builtin_objects(duk_hthread *thr) {
*/
t--;
DUK_DDD(DUK_DDDPRINT("set external constructor: built-in %ld", (long) t));
- duk_xdef_prop_stridx_builtin(ctx, i, DUK_STRIDX_CONSTRUCTOR, t, DUK_PROPDESC_FLAGS_WC);
+ duk_dup(thr, (duk_idx_t) t);
+ duk_xdef_prop_stridx(thr, (duk_idx_t) i, DUK_STRIDX_CONSTRUCTOR, DUK_PROPDESC_FLAGS_WC);
}
/* normal valued properties */
@@ -58337,7 +59885,7 @@ DUK_INTERNAL void duk_hthread_create_builtin_objects(duk_hthread *thr) {
for (j = 0; j < num; j++) {
duk_small_uint_t defprop_flags;
- duk__push_stridx_or_string(ctx, bd);
+ duk__push_stridx_or_string(thr, bd);
/*
* Property attribute defaults are defined in E5 Section 15 (first
@@ -58367,38 +59915,38 @@ DUK_INTERNAL void duk_hthread_create_builtin_objects(duk_hthread *thr) {
t = (duk_small_uint_t) duk_bd_decode(bd, DUK__PROP_TYPE_BITS);
DUK_DDD(DUK_DDDPRINT("built-in %ld, normal-valued property %ld, key %!T, flags 0x%02lx, type %ld",
- (long) i, (long) j, duk_get_tval(ctx, -1), (unsigned long) defprop_flags, (long) t));
+ (long) i, (long) j, duk_get_tval(thr, -1), (unsigned long) defprop_flags, (long) t));
switch (t) {
case DUK__PROP_TYPE_DOUBLE: {
- duk__push_double(ctx, bd);
+ duk__push_double(thr, bd);
break;
}
case DUK__PROP_TYPE_STRING: {
- duk__push_string(ctx, bd);
+ duk__push_string(thr, bd);
break;
}
case DUK__PROP_TYPE_STRIDX: {
- duk__push_stridx(ctx, bd);
+ duk__push_stridx(thr, bd);
break;
}
case DUK__PROP_TYPE_BUILTIN: {
duk_small_uint_t bidx;
bidx = (duk_small_uint_t) duk_bd_decode_varuint(bd);
- duk_dup(ctx, (duk_idx_t) bidx);
+ duk_dup(thr, (duk_idx_t) bidx);
break;
}
case DUK__PROP_TYPE_UNDEFINED: {
- duk_push_undefined(ctx);
+ duk_push_undefined(thr);
break;
}
case DUK__PROP_TYPE_BOOLEAN_TRUE: {
- duk_push_true(ctx);
+ duk_push_true(thr);
break;
}
case DUK__PROP_TYPE_BOOLEAN_FALSE: {
- duk_push_false(ctx);
+ duk_push_false(thr);
break;
}
case DUK__PROP_TYPE_ACCESSOR: {
@@ -58409,18 +59957,18 @@ DUK_INTERNAL void duk_hthread_create_builtin_objects(duk_hthread *thr) {
duk_c_function c_func_setter;
DUK_DDD(DUK_DDDPRINT("built-in accessor property: objidx=%ld, key=%!T, getteridx=%ld, setteridx=%ld, flags=0x%04lx",
- (long) i, duk_get_tval(ctx, -1), (long) natidx_getter, (long) natidx_setter, (unsigned long) defprop_flags));
+ (long) i, duk_get_tval(thr, -1), (long) natidx_getter, (long) natidx_setter, (unsigned long) defprop_flags));
c_func_getter = duk_bi_native_functions[natidx_getter];
if (c_func_getter != NULL) {
- duk_push_c_function_noconstruct_noexotic(ctx, c_func_getter, 0); /* always 0 args */
- duk_set_magic(ctx, -1, (duk_int_t) accessor_magic);
+ duk_push_c_function_builtin_noconstruct(thr, c_func_getter, 0); /* always 0 args */
+ duk_set_magic(thr, -1, (duk_int_t) accessor_magic);
defprop_flags |= DUK_DEFPROP_HAVE_GETTER;
}
c_func_setter = duk_bi_native_functions[natidx_setter];
if (c_func_setter != NULL) {
- duk_push_c_function_noconstruct_noexotic(ctx, c_func_setter, 1); /* always 1 arg */
- duk_set_magic(ctx, -1, (duk_int_t) accessor_magic);
+ duk_push_c_function_builtin_noconstruct(thr, c_func_setter, 1); /* always 1 arg */
+ duk_set_magic(thr, -1, (duk_int_t) accessor_magic);
defprop_flags |= DUK_DEFPROP_HAVE_SETTER;
}
@@ -58437,8 +59985,8 @@ DUK_INTERNAL void duk_hthread_create_builtin_objects(duk_hthread *thr) {
}
}
- duk_def_prop(ctx, i, defprop_flags);
- DUK_ASSERT_TOP(ctx, DUK_NUM_ALL_BUILTINS);
+ duk_def_prop(thr, (duk_idx_t) i, defprop_flags);
+ DUK_ASSERT_TOP(thr, DUK_NUM_ALL_BUILTINS);
}
/* native function properties */
@@ -58456,13 +60004,13 @@ DUK_INTERNAL void duk_hthread_create_builtin_objects(duk_hthread *thr) {
duk_small_int_t lightfunc_eligible;
#endif
- duk__push_stridx_or_string(ctx, bd);
- h_key = duk_known_hstring(ctx, -1);
+ duk__push_stridx_or_string(thr, bd);
+ h_key = duk_known_hstring(thr, -1);
DUK_UNREF(h_key);
natidx = (duk_small_uint_t) duk_bd_decode_varuint(bd);
c_length = (duk_small_uint_t) duk_bd_decode(bd, DUK__LENGTH_PROP_BITS);
- c_nargs = (duk_int_t) duk_bd_decode_flagged(bd, DUK__NARGS_BITS, (duk_int32_t) c_length /*def_value*/);
+ c_nargs = (duk_int_t) duk_bd_decode_flagged(bd, DUK__NARGS_BITS, (duk_uint32_t) c_length /*def_value*/);
if (c_nargs == DUK__NARGS_VARARGS_MARKER) {
c_nargs = DUK_VARARGS;
}
@@ -58482,24 +60030,33 @@ DUK_INTERNAL void duk_hthread_create_builtin_objects(duk_hthread *thr) {
(c_length <= DUK_LFUNC_LENGTH_MAX) &&
(magic >= DUK_LFUNC_MAGIC_MIN && magic <= DUK_LFUNC_MAGIC_MAX);
- if (h_key == DUK_HTHREAD_STRING_EVAL(thr) ||
- h_key == DUK_HTHREAD_STRING_YIELD(thr) ||
- h_key == DUK_HTHREAD_STRING_RESUME(thr)) {
- /* These functions have trouble working as lightfuncs.
- * Some of them have specific asserts and some may have
- * additional properties (e.g. 'require.id' may be written).
- */
- DUK_D(DUK_DPRINT("reject as lightfunc: key=%!O, i=%d, j=%d", (duk_heaphdr *) h_key, (int) i, (int) j));
+ /* These functions have trouble working as lightfuncs.
+ * Some of them have specific asserts and some may have
+ * additional properties (e.g. 'require.id' may be written).
+ */
+ if (c_func == duk_bi_global_object_eval) {
+ lightfunc_eligible = 0;
+ }
+#if defined(DUK_USE_COROUTINE_SUPPORT)
+ if (c_func == duk_bi_thread_yield ||
+ c_func == duk_bi_thread_resume) {
+ lightfunc_eligible = 0;
+ }
+#endif
+ if (c_func == duk_bi_function_prototype_call ||
+ c_func == duk_bi_function_prototype_apply ||
+ c_func == duk_bi_reflect_apply ||
+ c_func == duk_bi_reflect_construct) {
lightfunc_eligible = 0;
}
if (lightfunc_eligible) {
duk_tval tv_lfunc;
- duk_small_uint_t lf_nargs = (c_nargs == DUK_VARARGS ? DUK_LFUNC_NARGS_VARARGS : c_nargs);
+ duk_small_uint_t lf_nargs = (duk_small_uint_t) (c_nargs == DUK_VARARGS ? DUK_LFUNC_NARGS_VARARGS : c_nargs);
duk_small_uint_t lf_flags = DUK_LFUNC_FLAGS_PACK(magic, c_length, lf_nargs);
DUK_TVAL_SET_LIGHTFUNC(&tv_lfunc, c_func, lf_flags);
- duk_push_tval(ctx, &tv_lfunc);
- DUK_D(DUK_DPRINT("built-in function eligible as light function: i=%d, j=%d c_length=%ld, c_nargs=%ld, magic=%ld -> %!iT", (int) i, (int) j, (long) c_length, (long) c_nargs, (long) magic, duk_get_tval(ctx, -1)));
+ duk_push_tval(thr, &tv_lfunc);
+ DUK_D(DUK_DPRINT("built-in function eligible as light function: i=%d, j=%d c_length=%ld, c_nargs=%ld, magic=%ld -> %!iT", (int) i, (int) j, (long) c_length, (long) c_nargs, (long) magic, duk_get_tval(thr, -1)));
goto lightfunc_skip;
}
@@ -58508,10 +60065,21 @@ DUK_INTERNAL void duk_hthread_create_builtin_objects(duk_hthread *thr) {
/* [ (builtin objects) name ] */
- duk_push_c_function_noconstruct_noexotic(ctx, c_func, c_nargs);
- h_func = duk_known_hnatfunc(ctx, -1);
+ duk_push_c_function_builtin_noconstruct(thr, c_func, c_nargs);
+ h_func = duk_known_hnatfunc(thr, -1);
DUK_UNREF(h_func);
+ /* XXX: add into init data? */
+
+ /* Special call handling, not described in init data. */
+ if (c_func == duk_bi_global_object_eval ||
+ c_func == duk_bi_function_prototype_call ||
+ c_func == duk_bi_function_prototype_apply ||
+ c_func == duk_bi_reflect_apply ||
+ c_func == duk_bi_reflect_construct) {
+ DUK_HOBJECT_SET_SPECIAL_CALL((duk_hobject *) h_func);
+ }
+
/* Currently all built-in native functions are strict.
* This doesn't matter for many functions, but e.g.
* String.prototype.charAt (and other string functions)
@@ -58532,16 +60100,16 @@ DUK_INTERNAL void duk_hthread_create_builtin_objects(duk_hthread *thr) {
/* [ (builtin objects) name func ] */
- duk_push_int(ctx, c_length);
- duk_xdef_prop_stridx_short(ctx, -2, DUK_STRIDX_LENGTH, DUK_PROPDESC_FLAGS_C);
+ duk_push_uint(thr, c_length);
+ duk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_LENGTH, DUK_PROPDESC_FLAGS_C);
- duk_dup_m2(ctx);
- duk_xdef_prop_stridx_short(ctx, -2, DUK_STRIDX_NAME, DUK_PROPDESC_FLAGS_C);
+ duk_dup_m2(thr);
+ duk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_NAME, DUK_PROPDESC_FLAGS_C);
/* XXX: other properties of function instances; 'arguments', 'caller'. */
DUK_DD(DUK_DDPRINT("built-in object %ld, function property %ld -> %!T",
- (long) i, (long) j, (duk_tval *) duk_get_tval(ctx, -1)));
+ (long) i, (long) j, (duk_tval *) duk_get_tval(thr, -1)));
/* [ (builtin objects) name func ] */
@@ -58554,7 +60122,10 @@ DUK_INTERNAL void duk_hthread_create_builtin_objects(duk_hthread *thr) {
lightfunc_skip:
#endif
- duk_xdef_prop(ctx, i, DUK_PROPDESC_FLAGS_WC);
+ /* XXX: So far all ES builtins are 'wc' but e.g.
+ * performance.now() should be 'wec'.
+ */
+ duk_xdef_prop(thr, (duk_idx_t) i, DUK_PROPDESC_FLAGS_WC);
/* [ (builtin objects) ] */
}
@@ -58578,11 +60149,11 @@ DUK_INTERNAL void duk_hthread_create_builtin_objects(duk_hthread *thr) {
*/
#if defined(DUK_USE_DATE_BUILTIN)
- duk_get_prop_stridx_short(ctx, DUK_BIDX_DATE_PROTOTYPE, DUK_STRIDX_TO_UTC_STRING);
- duk_xdef_prop_stridx_short(ctx, DUK_BIDX_DATE_PROTOTYPE, DUK_STRIDX_TO_GMT_STRING, DUK_PROPDESC_FLAGS_WC);
+ duk_get_prop_stridx_short(thr, DUK_BIDX_DATE_PROTOTYPE, DUK_STRIDX_TO_UTC_STRING);
+ duk_xdef_prop_stridx_short(thr, DUK_BIDX_DATE_PROTOTYPE, DUK_STRIDX_TO_GMT_STRING, DUK_PROPDESC_FLAGS_WC);
#endif
- h = duk_known_hobject(ctx, DUK_BIDX_DOUBLE_ERROR);
+ h = duk_known_hobject(thr, DUK_BIDX_DOUBLE_ERROR);
DUK_HOBJECT_CLEAR_EXTENSIBLE(h);
#if !defined(DUK_USE_ES6_OBJECT_PROTO_PROPERTY)
@@ -58596,7 +60167,7 @@ DUK_INTERNAL void duk_hthread_create_builtin_objects(duk_hthread *thr) {
#endif
/* XXX: relocate */
- duk_push_string(ctx,
+ duk_push_string(thr,
/* Endianness indicator */
#if defined(DUK_USE_INTEGER_LE)
"l"
@@ -58697,7 +60268,7 @@ DUK_INTERNAL void duk_hthread_create_builtin_objects(duk_hthread *thr) {
DUK_USE_OS_STRING
" "
DUK_USE_COMPILER_STRING);
- duk_xdef_prop_stridx_short(ctx, DUK_BIDX_DUKTAPE, DUK_STRIDX_ENV, DUK_PROPDESC_FLAGS_WC);
+ duk_xdef_prop_stridx_short(thr, DUK_BIDX_DUKTAPE, DUK_STRIDX_ENV, DUK_PROPDESC_FLAGS_WC);
/*
* Since built-ins are not often extended, compact them.
@@ -58705,7 +60276,7 @@ DUK_INTERNAL void duk_hthread_create_builtin_objects(duk_hthread *thr) {
DUK_DD(DUK_DDPRINT("compact built-ins"));
for (i = 0; i < DUK_NUM_ALL_BUILTINS; i++) {
- duk_hobject_compact_props(thr, duk_known_hobject(ctx, i));
+ duk_hobject_compact_props(thr, duk_known_hobject(thr, (duk_idx_t) i));
}
DUK_D(DUK_DPRINT("INITBUILTINS END"));
@@ -58713,7 +60284,7 @@ DUK_INTERNAL void duk_hthread_create_builtin_objects(duk_hthread *thr) {
#if defined(DUK_USE_DEBUG_LEVEL) && (DUK_USE_DEBUG_LEVEL >= 1)
for (i = 0; i < DUK_NUM_ALL_BUILTINS; i++) {
DUK_DD(DUK_DDPRINT("built-in object %ld after initialization and compacting: %!@iO",
- (long) i, (duk_heaphdr *) duk_require_hobject(ctx, i)));
+ (long) i, (duk_heaphdr *) duk_require_hobject(thr, i)));
}
#endif
@@ -58723,8 +60294,8 @@ DUK_INTERNAL void duk_hthread_create_builtin_objects(duk_hthread *thr) {
* through builtins[].
*/
- duk_set_top(ctx, 0);
- DUK_ASSERT_TOP(ctx, 0);
+ duk_set_top(thr, 0);
+ DUK_ASSERT_TOP(thr, 0);
}
#endif /* DUK_USE_ROM_OBJECTS */
@@ -58760,29 +60331,25 @@ DUK_INTERNAL void duk_hthread_copy_builtin_objects(duk_hthread *thr_from, duk_ht
DUK_INTERNAL void duk_hthread_terminate(duk_hthread *thr) {
DUK_ASSERT(thr != NULL);
- /* Order of unwinding is important */
-
- duk_hthread_catchstack_unwind(thr, 0);
- duk_hthread_callstack_unwind(thr, 0); /* side effects, possibly errors */
+ while (thr->callstack_curr != NULL) {
+ duk_hthread_activation_unwind_norz(thr);
+ }
thr->valstack_bottom = thr->valstack;
- duk_set_top((duk_context *) thr, 0); /* unwinds valstack, updating refcounts */
+ duk_set_top(thr, 0); /* unwinds valstack, updating refcounts */
thr->state = DUK_HTHREAD_STATE_TERMINATED;
/* Here we could remove references to built-ins, but it may not be
* worth the effort because built-ins are quite likely to be shared
* with another (unterminated) thread, and terminated threads are also
- * usually garbage collected quite quickly. Also, doing DECREFs
- * could trigger finalization, which would run on the current thread
- * and have access to only some of the built-ins. Garbage collection
- * deals with this correctly already.
+ * usually garbage collected quite quickly.
+ *
+ * We could also shrink the value stack here, but that also may not
+ * be worth the effort for the same reason.
*/
- /* XXX: Shrink the stacks to minimize memory usage? May not
- * be worth the effort because terminated threads are usually
- * garbage collected quite soon.
- */
+ DUK_REFZERO_CHECK_SLOW(thr);
}
#if defined(DUK_USE_DEBUGGER_SUPPORT)
@@ -58853,585 +60420,411 @@ DUK_INTERNAL void duk_hthread_sync_and_null_currpc(duk_hthread *thr) {
}
}
/*
- * Manipulation of thread stacks (valstack, callstack, catchstack).
- *
- * Ideally unwinding of stacks should have no side effects, which would
- * then favor separate unwinding and shrink check primitives for each
- * stack type. A shrink check may realloc and thus have side effects.
+ * Thread stack (mainly call stack) primitives: allocation of activations,
+ * unwinding catchers and activations, etc.
*
- * However, currently callstack unwinding itself has side effects, as it
- * needs to DECREF multiple objects, close environment records, etc.
- * Stacks must thus be unwound in the correct order by the caller.
- *
- * (XXX: This should be probably reworked so that there is a shared
- * unwind primitive which handles all stacks as requested, and knows
- * the proper order for unwinding.)
- *
- * Valstack entries above 'top' are always kept initialized to
- * "undefined unused". Callstack and catchstack entries above 'top'
- * are not zeroed and are left as garbage.
- *
- * Value stack handling is mostly a part of the API implementation.
+ * Value stack handling is a part of the API implementation.
*/
/* #include duk_internal.h -> already included */
-DUK_LOCAL DUK_COLD DUK_NOINLINE void duk__hthread_do_callstack_grow(duk_hthread *thr) {
- duk_activation *new_ptr;
- duk_size_t old_size;
- duk_size_t new_size;
+/* Unwind the topmost catcher of the current activation (caller must check that
+ * both exist) without side effects.
+ */
+DUK_INTERNAL void duk_hthread_catcher_unwind_norz(duk_hthread *thr, duk_activation *act) {
+ duk_catcher *cat;
DUK_ASSERT(thr != NULL);
- DUK_ASSERT_DISABLE(thr->callstack_top >= 0); /* avoid warning (unsigned) */
- DUK_ASSERT(thr->callstack_size >= thr->callstack_top);
-
- old_size = thr->callstack_size;
- new_size = old_size + DUK_CALLSTACK_GROW_STEP;
-
- /* this is a bit approximate (errors out before max is reached); this is OK */
- if (new_size >= thr->callstack_max) {
- DUK_ERROR_RANGE(thr, DUK_STR_CALLSTACK_LIMIT);
- }
+ DUK_ASSERT(act != NULL);
+ DUK_ASSERT(act->cat != NULL); /* caller must check */
+ cat = act->cat;
+ DUK_ASSERT(cat != NULL);
- DUK_DD(DUK_DDPRINT("growing callstack %ld -> %ld", (long) old_size, (long) new_size));
+ DUK_DDD(DUK_DDDPRINT("unwinding catch stack entry %p (lexenv check is done)", (void *) cat));
- /*
- * Note: must use indirect variant of DUK_REALLOC() because underlying
- * pointer may be changed by mark-and-sweep.
- */
+ if (DUK_CAT_HAS_LEXENV_ACTIVE(cat)) {
+ duk_hobject *env;
- DUK_ASSERT(new_size > 0);
- new_ptr = (duk_activation *) DUK_REALLOC_INDIRECT(thr->heap, duk_hthread_get_callstack_ptr, (void *) thr, sizeof(duk_activation) * new_size);
- if (!new_ptr) {
- /* No need for a NULL/zero-size check because new_size > 0) */
- DUK_ERROR_ALLOC_FAILED(thr);
- }
- thr->callstack = new_ptr;
- thr->callstack_size = new_size;
+ env = act->lex_env; /* current lex_env of the activation (created for catcher) */
+ DUK_ASSERT(env != NULL); /* must be, since env was created when catcher was created */
+ act->lex_env = DUK_HOBJECT_GET_PROTOTYPE(thr->heap, env); /* prototype is lex_env before catcher created */
+ DUK_HOBJECT_INCREF(thr, act->lex_env);
+ DUK_HOBJECT_DECREF_NORZ(thr, env);
- if (thr->callstack_top > 0) {
- thr->callstack_curr = thr->callstack + thr->callstack_top - 1;
- } else {
- thr->callstack_curr = NULL;
+ /* There is no need to decref anything else than 'env': if 'env'
+ * becomes unreachable, refzero will handle decref'ing its prototype.
+ */
}
- /* note: any entries above the callstack top are garbage and not zeroed */
-}
-
-/* check that there is space for at least one new entry */
-DUK_INTERNAL void duk_hthread_callstack_grow(duk_hthread *thr) {
- DUK_ASSERT(thr != NULL);
- DUK_ASSERT_DISABLE(thr->callstack_top >= 0); /* avoid warning (unsigned) */
- DUK_ASSERT(thr->callstack_size >= thr->callstack_top);
-
- if (DUK_LIKELY(thr->callstack_top < thr->callstack_size)) {
- return;
- }
- duk__hthread_do_callstack_grow(thr);
+ act->cat = cat->parent;
+ duk_hthread_catcher_free(thr, cat);
}
-DUK_LOCAL DUK_COLD DUK_NOINLINE void duk__hthread_do_callstack_shrink(duk_hthread *thr) {
- duk_size_t new_size;
- duk_activation *p;
+/* Same as above, but caller is certain no catcher-related lexenv may exist. */
+DUK_INTERNAL void duk_hthread_catcher_unwind_nolexenv_norz(duk_hthread *thr, duk_activation *act) {
+ duk_catcher *cat;
DUK_ASSERT(thr != NULL);
- DUK_ASSERT_DISABLE(thr->callstack_top >= 0); /* avoid warning (unsigned) */
- DUK_ASSERT(thr->callstack_size >= thr->callstack_top);
-
- new_size = thr->callstack_top + DUK_CALLSTACK_SHRINK_SPARE;
- DUK_ASSERT(new_size >= thr->callstack_top);
+ DUK_ASSERT(act != NULL);
+ DUK_ASSERT(act->cat != NULL); /* caller must check */
+ cat = act->cat;
+ DUK_ASSERT(cat != NULL);
- DUK_DD(DUK_DDPRINT("shrinking callstack %ld -> %ld", (long) thr->callstack_size, (long) new_size));
+ DUK_DDD(DUK_DDDPRINT("unwinding catch stack entry %p (lexenv check is not done)", (void *) cat));
- /*
- * Note: must use indirect variant of DUK_REALLOC() because underlying
- * pointer may be changed by mark-and-sweep.
- */
+ DUK_ASSERT(!DUK_CAT_HAS_LEXENV_ACTIVE(cat));
- /* shrink failure is not fatal */
- p = (duk_activation *) DUK_REALLOC_INDIRECT(thr->heap, duk_hthread_get_callstack_ptr, (void *) thr, sizeof(duk_activation) * new_size);
- if (p) {
- thr->callstack = p;
- thr->callstack_size = new_size;
+ act->cat = cat->parent;
+ duk_hthread_catcher_free(thr, cat);
+}
- if (thr->callstack_top > 0) {
- thr->callstack_curr = thr->callstack + thr->callstack_top - 1;
- } else {
- thr->callstack_curr = NULL;
- }
- } else {
- /* Because new_size != 0, if condition doesn't need to be
- * (p != NULL || new_size == 0).
- */
- DUK_ASSERT(new_size != 0);
- DUK_D(DUK_DPRINT("callstack shrink failed, ignoring"));
- }
+DUK_LOCAL
+#if defined(DUK_USE_CACHE_CATCHER)
+DUK_NOINLINE
+#endif
+duk_catcher *duk__hthread_catcher_alloc_slow(duk_hthread *thr) {
+ duk_catcher *cat;
- /* note: any entries above the callstack top are garbage and not zeroed */
+ cat = (duk_catcher *) DUK_ALLOC_CHECKED(thr, sizeof(duk_catcher));
+ DUK_ASSERT(cat != NULL);
+ return cat;
}
-DUK_INTERNAL void duk_hthread_callstack_shrink_check(duk_hthread *thr) {
+#if defined(DUK_USE_CACHE_CATCHER)
+DUK_INTERNAL DUK_INLINE duk_catcher *duk_hthread_catcher_alloc(duk_hthread *thr) {
+ duk_catcher *cat;
+
DUK_ASSERT(thr != NULL);
- DUK_ASSERT_DISABLE(thr->callstack_top >= 0); /* avoid warning (unsigned) */
- DUK_ASSERT(thr->callstack_size >= thr->callstack_top);
- if (DUK_LIKELY(thr->callstack_size - thr->callstack_top < DUK_CALLSTACK_SHRINK_THRESHOLD)) {
- return;
+ cat = thr->heap->catcher_free;
+ if (DUK_LIKELY(cat != NULL)) {
+ thr->heap->catcher_free = cat->parent;
+ return cat;
}
- duk__hthread_do_callstack_shrink(thr);
+ return duk__hthread_catcher_alloc_slow(thr);
}
+#else /* DUK_USE_CACHE_CATCHER */
+DUK_INTERNAL duk_catcher *duk_hthread_catcher_alloc(duk_hthread *thr) {
+ return duk__hthread_catcher_alloc_slow(thr);
+}
+#endif /* DUK_USE_CACHE_CATCHER */
-DUK_INTERNAL void duk_hthread_callstack_unwind_norz(duk_hthread *thr, duk_size_t new_top) {
- duk_size_t idx;
-
- DUK_DDD(DUK_DDDPRINT("unwind callstack top of thread %p from %ld to %ld",
- (void *) thr,
- (thr != NULL ? (long) thr->callstack_top : (long) -1),
- (long) new_top));
-
- DUK_ASSERT(thr);
- DUK_ASSERT(thr->heap);
- DUK_ASSERT_DISABLE(new_top >= 0); /* unsigned */
- DUK_ASSERT((duk_size_t) new_top <= thr->callstack_top); /* cannot grow */
+DUK_INTERNAL void duk_hthread_catcher_free(duk_hthread *thr, duk_catcher *cat) {
+ DUK_ASSERT(thr != NULL);
+ DUK_ASSERT(cat != NULL);
- /*
- * The loop below must avoid issues with potential callstack
- * reallocations. A resize (and other side effects) may happen
- * e.g. due to finalizer/errhandler calls caused by a refzero or
- * mark-and-sweep. Arbitrary finalizers may run, because when
- * an environment record is refzero'd, it may refer to arbitrary
- * values which also become refzero'd.
- *
- * So, the pointer 'p' is re-looked-up below whenever a side effect
- * might have changed it.
- */
+#if defined(DUK_USE_CACHE_CATCHER)
+ /* Unconditional caching for now; freed in mark-and-sweep. */
+ cat->parent = thr->heap->catcher_free;
+ thr->heap->catcher_free = cat;
+#else
+ DUK_FREE_CHECKED(thr, (void *) cat);
+#endif
+}
- idx = thr->callstack_top;
- while (idx > new_top) {
- duk_activation *act;
- duk_hobject *func;
- duk_hobject *tmp;
-#if defined(DUK_USE_DEBUGGER_SUPPORT)
- duk_heap *heap;
+DUK_LOCAL
+#if defined(DUK_USE_CACHE_ACTIVATION)
+DUK_NOINLINE
#endif
+duk_activation *duk__hthread_activation_alloc_slow(duk_hthread *thr) {
+ duk_activation *act;
- idx--;
- DUK_ASSERT_DISABLE(idx >= 0); /* unsigned */
- DUK_ASSERT((duk_size_t) idx < thr->callstack_size); /* true, despite side effect resizes */
+ act = (duk_activation *) DUK_ALLOC_CHECKED(thr, sizeof(duk_activation));
+ DUK_ASSERT(act != NULL);
+ return act;
+}
+
+#if defined(DUK_USE_CACHE_ACTIVATION)
+DUK_INTERNAL DUK_INLINE duk_activation *duk_hthread_activation_alloc(duk_hthread *thr) {
+ duk_activation *act;
- act = thr->callstack + idx;
- /* With lightfuncs, act 'func' may be NULL */
+ DUK_ASSERT(thr != NULL);
-#if defined(DUK_USE_NONSTD_FUNC_CALLER_PROPERTY)
- /*
- * Restore 'caller' property for non-strict callee functions.
- */
+ act = thr->heap->activation_free;
+ if (DUK_LIKELY(act != NULL)) {
+ thr->heap->activation_free = act->parent;
+ return act;
+ }
- func = DUK_ACT_GET_FUNC(act);
- if (func != NULL && !DUK_HOBJECT_HAS_STRICT(func)) {
- duk_tval *tv_caller;
- duk_tval tv_tmp;
- duk_hobject *h_tmp;
+ return duk__hthread_activation_alloc_slow(thr);
+}
+#else /* DUK_USE_CACHE_ACTIVATION */
+DUK_INTERNAL duk_activation *duk_hthread_activation_alloc(duk_hthread *thr) {
+ return duk__hthread_activation_alloc_slow(thr);
+}
+#endif /* DUK_USE_CACHE_ACTIVATION */
- tv_caller = duk_hobject_find_existing_entry_tval_ptr(thr->heap, func, DUK_HTHREAD_STRING_CALLER(thr));
- /* The act->prev_caller should only be set if the entry for 'caller'
- * exists (as it is only set in that case, and the property is not
- * configurable), but handle all the cases anyway.
- */
+DUK_INTERNAL void duk_hthread_activation_free(duk_hthread *thr, duk_activation *act) {
+ DUK_ASSERT(thr != NULL);
+ DUK_ASSERT(act != NULL);
- if (tv_caller) {
- DUK_TVAL_SET_TVAL(&tv_tmp, tv_caller);
- if (act->prev_caller) {
- /* Just transfer the refcount from act->prev_caller to tv_caller,
- * so no need for a refcount update. This is the expected case.
- */
- DUK_TVAL_SET_OBJECT(tv_caller, act->prev_caller);
- act->prev_caller = NULL;
- } else {
- DUK_TVAL_SET_NULL(tv_caller); /* no incref needed */
- DUK_ASSERT(act->prev_caller == NULL);
- }
- DUK_TVAL_DECREF_NORZ(thr, &tv_tmp);
- } else {
- h_tmp = act->prev_caller;
- if (h_tmp) {
- act->prev_caller = NULL;
- DUK_HOBJECT_DECREF_NORZ(thr, h_tmp);
- }
- }
- act = thr->callstack + idx; /* avoid side effects */
- DUK_ASSERT(act->prev_caller == NULL);
- }
+#if defined(DUK_USE_CACHE_ACTIVATION)
+ /* Unconditional caching for now; freed in mark-and-sweep. */
+ act->parent = thr->heap->activation_free;
+ thr->heap->activation_free = act;
+#else
+ DUK_FREE_CHECKED(thr, (void *) act);
#endif
+}
- /*
- * Unwind debugger state. If we unwind while stepping
- * (either step over or step into), pause execution.
- */
-
+/* Internal helper: process the unwind for the topmost activation of a thread,
+ * but leave the duk_activation in place for possible tailcall reuse.
+ */
+DUK_LOCAL void duk__activation_unwind_nofree_norz(duk_hthread *thr) {
#if defined(DUK_USE_DEBUGGER_SUPPORT)
- heap = thr->heap;
- if (heap->dbg_step_thread == thr &&
- heap->dbg_step_csindex == idx) {
- /* Pause for all step types: step into, step over, step out.
- * This is the only place explicitly handling a step out.
- */
- if (duk_debug_is_paused(heap)) {
- DUK_D(DUK_DPRINT("step pause trigger but already paused, ignoring"));
- } else {
- duk_debug_set_paused(heap);
- DUK_ASSERT(heap->dbg_step_thread == NULL);
- }
- }
+ duk_heap *heap;
#endif
+ duk_activation *act;
+ duk_hobject *func;
+ duk_hobject *tmp;
- /*
- * Close environment record(s) if they exist.
- *
- * Only variable environments are closed. If lex_env != var_env, it
- * cannot currently contain any register bound declarations.
- *
- * Only environments created for a NEWENV function are closed. If an
- * environment is created for e.g. an eval call, it must not be closed.
- */
+ DUK_ASSERT(thr != NULL);
+ DUK_ASSERT(thr->callstack_curr != NULL); /* caller must check */
+ DUK_ASSERT(thr->callstack_top > 0);
+ act = thr->callstack_curr;
+ DUK_ASSERT(act != NULL);
+ /* With lightfuncs, act 'func' may be NULL. */
- func = DUK_ACT_GET_FUNC(act);
- if (func != NULL && !DUK_HOBJECT_HAS_NEWENV(func)) {
- DUK_DDD(DUK_DDDPRINT("skip closing environments, envs not owned by this activation"));
- goto skip_env_close;
- }
- /* func is NULL for lightfunc */
+ /* With duk_activation records allocated separately, 'act' is a stable
+ * pointer and not affected by side effects.
+ */
- /* Catch sites are required to clean up their environments
- * in FINALLY part before propagating, so this should
- * always hold here.
- */
- DUK_ASSERT(act->lex_env == act->var_env);
+#if defined(DUK_USE_NONSTD_FUNC_CALLER_PROPERTY)
+ /*
+ * Restore 'caller' property for non-strict callee functions.
+ */
- if (act->var_env != NULL) {
- DUK_DDD(DUK_DDDPRINT("closing var_env record %p -> %!O",
- (void *) act->var_env, (duk_heaphdr *) act->var_env));
- duk_js_close_environment_record(thr, act->var_env);
- act = thr->callstack + idx; /* avoid side effect issues */
- }
+ func = DUK_ACT_GET_FUNC(act);
+ if (func != NULL && !DUK_HOBJECT_HAS_STRICT(func)) {
+ duk_tval *tv_caller;
+ duk_tval tv_tmp;
+ duk_hobject *h_tmp;
- skip_env_close:
+ tv_caller = duk_hobject_find_existing_entry_tval_ptr(thr->heap, func, DUK_HTHREAD_STRING_CALLER(thr));
- /*
- * Update preventcount
+ /* The act->prev_caller should only be set if the entry for 'caller'
+ * exists (as it is only set in that case, and the property is not
+ * configurable), but handle all the cases anyway.
*/
- if (act->flags & DUK_ACT_FLAG_PREVENT_YIELD) {
- DUK_ASSERT(thr->callstack_preventcount >= 1);
- thr->callstack_preventcount--;
+ if (tv_caller) {
+ DUK_TVAL_SET_TVAL(&tv_tmp, tv_caller);
+ if (act->prev_caller) {
+ /* Just transfer the refcount from act->prev_caller to tv_caller,
+ * so no need for a refcount update. This is the expected case.
+ */
+ DUK_TVAL_SET_OBJECT(tv_caller, act->prev_caller);
+ act->prev_caller = NULL;
+ } else {
+ DUK_TVAL_SET_NULL(tv_caller); /* no incref needed */
+ DUK_ASSERT(act->prev_caller == NULL);
+ }
+ DUK_TVAL_DECREF_NORZ(thr, &tv_tmp);
+ } else {
+ h_tmp = act->prev_caller;
+ if (h_tmp) {
+ act->prev_caller = NULL;
+ DUK_HOBJECT_DECREF_NORZ(thr, h_tmp);
+ }
}
-
- /*
- * Reference count updates, using NORZ macros so we don't
- * need to handle side effects.
- */
-
- DUK_HOBJECT_DECREF_NORZ_ALLOWNULL(thr, act->var_env);
- act->var_env = NULL;
- DUK_HOBJECT_DECREF_NORZ_ALLOWNULL(thr, act->lex_env);
- act->lex_env = NULL;
-
- /* Note: this may cause a corner case situation where a finalizer
- * may see a currently reachable activation whose 'func' is NULL.
- */
- tmp = DUK_ACT_GET_FUNC(act);
- DUK_HOBJECT_DECREF_NORZ_ALLOWNULL(thr, tmp);
- DUK_UNREF(tmp);
- act->func = NULL;
- }
-
- thr->callstack_top = new_top;
- if (new_top > 0) {
- thr->callstack_curr = thr->callstack + new_top - 1;
- } else {
- thr->callstack_curr = NULL;
+ DUK_ASSERT(act->prev_caller == NULL);
}
+#endif
/*
- * We could clear the book-keeping variables for the topmost activation,
- * but don't do so now.
+ * Unwind debugger state. If we unwind while stepping
+ * (for any step type), pause execution. This is the
+ * only place explicitly handling a step out.
*/
-#if 0
- if (thr->callstack_curr != NULL) {
- duk_activation *act = thr->callstack_curr;
- act->idx_retval = 0;
+
+#if defined(DUK_USE_DEBUGGER_SUPPORT)
+ heap = thr->heap;
+ if (heap->dbg_pause_act == thr->callstack_curr) {
+ if (heap->dbg_pause_flags & DUK_PAUSE_FLAG_FUNC_EXIT) {
+ DUK_D(DUK_DPRINT("PAUSE TRIGGERED by function exit"));
+ duk_debug_set_paused(heap);
+ } else {
+ DUK_D(DUK_DPRINT("unwound past dbg_pause_act, set to NULL"));
+ heap->dbg_pause_act = NULL; /* avoid stale pointers */
+ }
+ DUK_ASSERT(heap->dbg_pause_act == NULL);
}
#endif
- /* Note: any entries above the callstack top are garbage and not zeroed.
- * Also topmost activation idx_retval is garbage (not zeroed), and must
- * be ignored.
+ /*
+ * Unwind catchers.
+ *
+ * Since there are no references in the catcher structure,
+ * unwinding is quite simple. The only thing we need to
+ * look out for is popping a possible lexical environment
+ * established for an active catch clause.
*/
-}
-DUK_INTERNAL void duk_hthread_callstack_unwind(duk_hthread *thr, duk_size_t new_top) {
- duk_hthread_callstack_unwind_norz(thr, new_top);
- DUK_REFZERO_CHECK_FAST(thr);
-}
-
-DUK_LOCAL DUK_COLD DUK_NOINLINE void duk__hthread_do_catchstack_grow(duk_hthread *thr) {
- duk_catcher *new_ptr;
- duk_size_t old_size;
- duk_size_t new_size;
-
- DUK_ASSERT(thr != NULL);
- DUK_ASSERT_DISABLE(thr->catchstack_top); /* avoid warning (unsigned) */
- DUK_ASSERT(thr->catchstack_size >= thr->catchstack_top);
-
- old_size = thr->catchstack_size;
- new_size = old_size + DUK_CATCHSTACK_GROW_STEP;
-
- /* this is a bit approximate (errors out before max is reached); this is OK */
- if (new_size >= thr->catchstack_max) {
- DUK_ERROR_RANGE(thr, DUK_STR_CATCHSTACK_LIMIT);
+ while (act->cat != NULL) {
+ duk_hthread_catcher_unwind_norz(thr, act);
}
- DUK_DD(DUK_DDPRINT("growing catchstack %ld -> %ld", (long) old_size, (long) new_size));
-
/*
- * Note: must use indirect variant of DUK_REALLOC() because underlying
- * pointer may be changed by mark-and-sweep.
+ * Close environment record(s) if they exist.
+ *
+ * Only variable environments are closed. If lex_env != var_env, it
+ * cannot currently contain any register bound declarations.
+ *
+ * Only environments created for a NEWENV function are closed. If an
+ * environment is created for e.g. an eval call, it must not be closed.
*/
- DUK_ASSERT(new_size > 0);
- new_ptr = (duk_catcher *) DUK_REALLOC_INDIRECT(thr->heap, duk_hthread_get_catchstack_ptr, (void *) thr, sizeof(duk_catcher) * new_size);
- if (!new_ptr) {
- /* No need for a NULL/zero-size check because new_size > 0) */
- DUK_ERROR_ALLOC_FAILED(thr);
+ func = DUK_ACT_GET_FUNC(act);
+ if (func != NULL && !DUK_HOBJECT_HAS_NEWENV(func)) {
+ DUK_DDD(DUK_DDDPRINT("skip closing environments, envs not owned by this activation"));
+ goto skip_env_close;
}
- thr->catchstack = new_ptr;
- thr->catchstack_size = new_size;
+ /* func is NULL for lightfunc */
- /* note: any entries above the catchstack top are garbage and not zeroed */
-}
-
-DUK_INTERNAL void duk_hthread_catchstack_grow(duk_hthread *thr) {
- DUK_ASSERT(thr != NULL);
- DUK_ASSERT_DISABLE(thr->catchstack_top); /* avoid warning (unsigned) */
- DUK_ASSERT(thr->catchstack_size >= thr->catchstack_top);
+ /* Catch sites are required to clean up their environments
+ * in FINALLY part before propagating, so this should
+ * always hold here.
+ */
+ DUK_ASSERT(act->lex_env == act->var_env);
- if (DUK_LIKELY(thr->catchstack_top < thr->catchstack_size)) {
- return;
+ /* XXX: Closing the environment record copies values from registers
+ * into the scope object. It's side effect free as such, but may
+ * currently run out of memory which causes an error throw. This is
+ * an actual sandboxing problem for error unwinds, and needs to be
+ * fixed e.g. by preallocating the scope property slots.
+ */
+ if (act->var_env != NULL) {
+ DUK_DDD(DUK_DDDPRINT("closing var_env record %p -> %!O",
+ (void *) act->var_env, (duk_heaphdr *) act->var_env));
+ duk_js_close_environment_record(thr, act->var_env);
}
- duk__hthread_do_catchstack_grow(thr);
-}
-
-DUK_LOCAL DUK_COLD DUK_NOINLINE void duk__hthread_do_catchstack_shrink(duk_hthread *thr) {
- duk_size_t new_size;
- duk_catcher *p;
-
- DUK_ASSERT(thr != NULL);
- DUK_ASSERT_DISABLE(thr->catchstack_top >= 0); /* avoid warning (unsigned) */
- DUK_ASSERT(thr->catchstack_size >= thr->catchstack_top);
-
- new_size = thr->catchstack_top + DUK_CATCHSTACK_SHRINK_SPARE;
- DUK_ASSERT(new_size >= thr->catchstack_top);
-
- DUK_DD(DUK_DDPRINT("shrinking catchstack %ld -> %ld", (long) thr->catchstack_size, (long) new_size));
+ skip_env_close:
/*
- * Note: must use indirect variant of DUK_REALLOC() because underlying
- * pointer may be changed by mark-and-sweep.
+ * Update preventcount
*/
- /* shrink failure is not fatal */
- p = (duk_catcher *) DUK_REALLOC_INDIRECT(thr->heap, duk_hthread_get_catchstack_ptr, (void *) thr, sizeof(duk_catcher) * new_size);
- if (p) {
- thr->catchstack = p;
- thr->catchstack_size = new_size;
- } else {
- /* Because new_size != 0, if condition doesn't need to be
- * (p != NULL || new_size == 0).
- */
- DUK_ASSERT(new_size != 0);
- DUK_D(DUK_DPRINT("catchstack shrink failed, ignoring"));
+ if (act->flags & DUK_ACT_FLAG_PREVENT_YIELD) {
+ DUK_ASSERT(thr->callstack_preventcount >= 1);
+ thr->callstack_preventcount--;
}
- /* note: any entries above the catchstack top are garbage and not zeroed */
-}
-
-DUK_INTERNAL void duk_hthread_catchstack_shrink_check(duk_hthread *thr) {
- DUK_ASSERT(thr != NULL);
- DUK_ASSERT_DISABLE(thr->catchstack_top >= 0); /* avoid warning (unsigned) */
- DUK_ASSERT(thr->catchstack_size >= thr->catchstack_top);
-
- if (DUK_LIKELY(thr->catchstack_size - thr->catchstack_top < DUK_CATCHSTACK_SHRINK_THRESHOLD)) {
- return;
- }
+ /*
+ * Reference count updates, using NORZ macros so we don't
+ * need to handle side effects.
+ *
+ * duk_activation pointers like act->var_env are intentionally
+ * left as garbage and not NULLed. Without side effects they
+ * can't be used when the values are dangling/garbage.
+ */
- duk__hthread_do_catchstack_shrink(thr);
+ DUK_HOBJECT_DECREF_NORZ_ALLOWNULL(thr, act->var_env);
+ DUK_HOBJECT_DECREF_NORZ_ALLOWNULL(thr, act->lex_env);
+ tmp = DUK_ACT_GET_FUNC(act);
+ DUK_HOBJECT_DECREF_NORZ_ALLOWNULL(thr, tmp);
+ DUK_UNREF(tmp);
}
-DUK_INTERNAL void duk_hthread_catchstack_unwind_norz(duk_hthread *thr, duk_size_t new_top) {
- duk_size_t idx;
+/* Unwind topmost duk_activation of a thread, caller must ensure that an
+ * activation exists. The call is side effect free, except that scope
+ * closure may currently throw an out-of-memory error.
+ */
+DUK_INTERNAL void duk_hthread_activation_unwind_norz(duk_hthread *thr) {
+ duk_activation *act;
- DUK_DDD(DUK_DDDPRINT("unwind catchstack top of thread %p from %ld to %ld",
- (void *) thr,
- (thr != NULL ? (long) thr->catchstack_top : (long) -1),
- (long) new_top));
+ duk__activation_unwind_nofree_norz(thr);
- DUK_ASSERT(thr);
- DUK_ASSERT(thr->heap);
- DUK_ASSERT_DISABLE(new_top >= 0); /* unsigned */
- DUK_ASSERT((duk_size_t) new_top <= thr->catchstack_top); /* cannot grow */
+ DUK_ASSERT(thr->callstack_curr != NULL);
+ DUK_ASSERT(thr->callstack_top > 0);
+ act = thr->callstack_curr;
+ thr->callstack_curr = act->parent;
+ thr->callstack_top--;
- /*
- * Since there are no references in the catcher structure,
- * unwinding is quite simple. The only thing we need to
- * look out for is popping a possible lexical environment
- * established for an active catch clause.
+ /* Ideally we'd restore value stack reserve here to caller's value.
+ * This doesn't work for current unwind call sites however, because
+ * the current (unwound) value stack top may be above the reserve.
+ * Thus value stack reserve is restored by the call sites.
*/
- idx = thr->catchstack_top;
- while (idx > new_top) {
- duk_catcher *p;
- duk_activation *act;
- duk_hobject *env;
-
- idx--;
- DUK_ASSERT_DISABLE(idx >= 0); /* unsigned */
- DUK_ASSERT((duk_size_t) idx < thr->catchstack_size);
+ /* XXX: inline for performance builds? */
+ duk_hthread_activation_free(thr, act);
- p = thr->catchstack + idx;
+ /* We could clear the book-keeping variables like retval_byteoff for
+ * the topmost activation, but don't do so now as it's not necessary.
+ */
+}
- if (DUK_CAT_HAS_LEXENV_ACTIVE(p)) {
- DUK_DDD(DUK_DDDPRINT("unwinding catchstack idx %ld, callstack idx %ld, callstack top %ld: lexical environment active",
- (long) idx, (long) p->callstack_index, (long) thr->callstack_top));
+DUK_INTERNAL void duk_hthread_activation_unwind_reuse_norz(duk_hthread *thr) {
+ duk__activation_unwind_nofree_norz(thr);
+}
- /* XXX: Here we have a nasty dependency: the need to manipulate
- * the callstack means that catchstack must always be unwound by
- * the caller before unwinding the callstack. This should be fixed
- * later.
- */
+/* Get duk_activation for given callstack level or NULL if level is invalid
+ * or deeper than the call stack. Level -1 refers to current activation, -2
+ * to its caller, etc. Starting from Duktape 2.2 finding the activation is
+ * a linked list scan which gets more expensive the deeper the lookup is.
+ */
+DUK_INTERNAL duk_activation *duk_hthread_get_activation_for_level(duk_hthread *thr, duk_int_t level) {
+ duk_activation *act;
- /* Note that multiple catchstack entries may refer to the same
- * callstack entry.
- */
- act = thr->callstack + p->callstack_index;
- DUK_ASSERT(act >= thr->callstack);
- DUK_ASSERT(act < thr->callstack + thr->callstack_top);
-
- DUK_DDD(DUK_DDDPRINT("catchstack_index=%ld, callstack_index=%ld, lex_env=%!iO",
- (long) idx, (long) p->callstack_index,
- (duk_heaphdr *) act->lex_env));
-
- env = act->lex_env; /* current lex_env of the activation (created for catcher) */
- DUK_ASSERT(env != NULL); /* must be, since env was created when catcher was created */
- act->lex_env = DUK_HOBJECT_GET_PROTOTYPE(thr->heap, env); /* prototype is lex_env before catcher created */
- DUK_HOBJECT_INCREF(thr, act->lex_env);
- DUK_HOBJECT_DECREF_NORZ(thr, env);
-
- /* There is no need to decref anything else than 'env': if 'env'
- * becomes unreachable, refzero will handle decref'ing its prototype.
- */
+ if (level >= 0) {
+ return NULL;
+ }
+ act = thr->callstack_curr;
+ for (;;) {
+ if (act == NULL) {
+ return act;
+ }
+ if (level == -1) {
+ return act;
}
+ level++;
+ act = act->parent;
}
-
- thr->catchstack_top = new_top;
-
- /* note: any entries above the catchstack top are garbage and not zeroed */
-}
-
-DUK_INTERNAL void duk_hthread_catchstack_unwind(duk_hthread *thr, duk_size_t new_top) {
- duk_hthread_catchstack_unwind_norz(thr, new_top);
- DUK_REFZERO_CHECK_FAST(thr);
+ /* never here */
}
#if defined(DUK_USE_FINALIZER_TORTURE)
DUK_INTERNAL void duk_hthread_valstack_torture_realloc(duk_hthread *thr) {
duk_size_t alloc_size;
duk_tval *new_ptr;
+ duk_ptrdiff_t alloc_end_off;
duk_ptrdiff_t end_off;
duk_ptrdiff_t bottom_off;
duk_ptrdiff_t top_off;
if (thr->valstack == NULL) {
+ DUK_D(DUK_DPRINT("skip valstack torture realloc, valstack is NULL"));
return;
}
+ alloc_end_off = (duk_ptrdiff_t) ((duk_uint8_t *) thr->valstack_alloc_end - (duk_uint8_t *) thr->valstack);
end_off = (duk_ptrdiff_t) ((duk_uint8_t *) thr->valstack_end - (duk_uint8_t *) thr->valstack);
bottom_off = (duk_ptrdiff_t) ((duk_uint8_t *) thr->valstack_bottom - (duk_uint8_t *) thr->valstack);
top_off = (duk_ptrdiff_t) ((duk_uint8_t *) thr->valstack_top - (duk_uint8_t *) thr->valstack);
- alloc_size = (duk_size_t) end_off;
+ alloc_size = (duk_size_t) alloc_end_off;
if (alloc_size == 0) {
+ DUK_D(DUK_DPRINT("skip valstack torture realloc, alloc_size is zero"));
return;
}
- new_ptr = (duk_tval *) DUK_ALLOC(thr->heap, alloc_size);
+ /* Use DUK_ALLOC_RAW() to avoid side effects. */
+ new_ptr = (duk_tval *) DUK_ALLOC_RAW(thr->heap, alloc_size);
if (new_ptr != NULL) {
DUK_MEMCPY((void *) new_ptr, (const void *) thr->valstack, alloc_size);
DUK_MEMSET((void *) thr->valstack, 0x55, alloc_size);
- DUK_FREE(thr->heap, (void *) thr->valstack);
+ DUK_FREE_CHECKED(thr, (void *) thr->valstack);
thr->valstack = new_ptr;
+ thr->valstack_alloc_end = (duk_tval *) ((duk_uint8_t *) new_ptr + alloc_end_off);
thr->valstack_end = (duk_tval *) ((duk_uint8_t *) new_ptr + end_off);
thr->valstack_bottom = (duk_tval *) ((duk_uint8_t *) new_ptr + bottom_off);
thr->valstack_top = (duk_tval *) ((duk_uint8_t *) new_ptr + top_off);
- /* No change in size. */
} else {
DUK_D(DUK_DPRINT("failed to realloc valstack for torture, ignore"));
}
}
-
-DUK_INTERNAL void duk_hthread_callstack_torture_realloc(duk_hthread *thr) {
- duk_size_t alloc_size;
- duk_activation *new_ptr;
- duk_ptrdiff_t curr_off;
-
- if (thr->callstack == NULL) {
- return;
- }
-
- curr_off = (duk_ptrdiff_t) ((duk_uint8_t *) thr->callstack_curr - (duk_uint8_t *) thr->callstack);
- alloc_size = sizeof(duk_activation) * thr->callstack_size;
- if (alloc_size == 0) {
- return;
- }
-
- new_ptr = (duk_activation *) DUK_ALLOC(thr->heap, alloc_size);
- if (new_ptr != NULL) {
- DUK_MEMCPY((void *) new_ptr, (const void *) thr->callstack, alloc_size);
- DUK_MEMSET((void *) thr->callstack, 0x55, alloc_size);
- DUK_FREE(thr->heap, (void *) thr->callstack);
- thr->callstack = new_ptr;
- thr->callstack_curr = (duk_activation *) ((duk_uint8_t *) new_ptr + curr_off);
- /* No change in size. */
- } else {
- DUK_D(DUK_DPRINT("failed to realloc callstack for torture, ignore"));
- }
-}
-
-DUK_INTERNAL void duk_hthread_catchstack_torture_realloc(duk_hthread *thr) {
- duk_size_t alloc_size;
- duk_catcher *new_ptr;
-
- if (thr->catchstack == NULL) {
- return;
- }
-
- alloc_size = sizeof(duk_catcher) * thr->catchstack_size;
- if (alloc_size == 0) {
- return;
- }
-
- new_ptr = (duk_catcher *) DUK_ALLOC(thr->heap, alloc_size);
- if (new_ptr != NULL) {
- DUK_MEMCPY((void *) new_ptr, (const void *) thr->catchstack, alloc_size);
- DUK_MEMSET((void *) thr->catchstack, 0x55, alloc_size);
- DUK_FREE(thr->heap, (void *) thr->catchstack);
- thr->catchstack = new_ptr;
- /* No change in size. */
- } else {
- DUK_D(DUK_DPRINT("failed to realloc catchstack for torture, ignore"));
- }
-}
#endif /* DUK_USE_FINALIZER_TORTURE */
/*
* Shared helpers for arithmetic operations
@@ -59573,22 +60966,30 @@ DUK_INTERNAL double duk_js_arith_pow(double x, double y) {
/*
* Call handling.
*
- * Main functions are:
+ * duk_handle_call_unprotected():
*
- * - duk_handle_call_unprotected(): unprotected call to Ecmascript or
- * Duktape/C function
- * - duk_handle_call_protected(): protected call to Ecmascript or
- * Duktape/C function
- * - duk_handle_safe_call(): make a protected C call within current
- * activation
- * - duk_handle_ecma_call_setup(): Ecmascript-to-Ecmascript calls
- * (not always possible), including tail calls and coroutine resume
+ * - Unprotected call to Ecmascript or Duktape/C function, from native
+ * code or bytecode executor.
*
- * See 'execution.rst'.
+ * - Also handles Ecma-to-Ecma calls which reuses a currently running
+ * executor instance to avoid native recursion. Call setup is done
+ * normally, but just before calling the bytecode executor a special
+ * return code is used to indicate that a calling executor is reused.
+ *
+ * - Also handles tailcalls, i.e. reuse of current duk_activation.
+ *
+ * - Also handles setup for initial Duktape.Thread.resume().
+ *
+ * duk_handle_safe_call():
*
- * Note: setjmp() and local variables have a nasty interaction,
- * see execution.rst; non-volatile locals modified after setjmp()
- * call are not guaranteed to keep their value.
+ * - Protected C call within current activation.
+ *
+ * setjmp() and local variables have a nasty interaction, see execution.rst;
+ * non-volatile locals modified after setjmp() call are not guaranteed to
+ * keep their value and can cause compiler or compiler version specific
+ * difficult to replicate issues.
+ *
+ * See 'execution.rst'.
*/
/* #include duk_internal.h -> already included */
@@ -59596,46 +60997,78 @@ DUK_INTERNAL double duk_js_arith_pow(double x, double y) {
/* XXX: heap->error_not_allowed for success path too? */
/*
- * Forward declarations.
- */
-
-DUK_LOCAL void duk__handle_call_inner(duk_hthread *thr,
- duk_idx_t num_stack_args,
- duk_small_uint_t call_flags,
- duk_idx_t idx_func);
-DUK_LOCAL void duk__handle_call_error(duk_hthread *thr,
- duk_size_t entry_valstack_bottom_index,
- duk_size_t entry_valstack_end,
- duk_size_t entry_catchstack_top,
- duk_size_t entry_callstack_top,
- 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_idx_t idx_func,
- duk_jmpbuf *old_jmpbuf_ptr);
-DUK_LOCAL void duk__handle_safe_call_inner(duk_hthread *thr,
- duk_safe_call_function func,
- void *udata,
- duk_idx_t idx_retbase,
- duk_idx_t num_stack_rets,
- duk_size_t entry_valstack_bottom_index,
- duk_size_t entry_callstack_top,
- duk_size_t entry_catchstack_top);
-DUK_LOCAL void duk__handle_safe_call_error(duk_hthread *thr,
- duk_idx_t idx_retbase,
- duk_idx_t num_stack_rets,
- duk_size_t entry_valstack_bottom_index,
- duk_size_t entry_callstack_top,
- duk_size_t entry_catchstack_top,
- duk_jmpbuf *old_jmpbuf_ptr);
-DUK_LOCAL void duk__handle_safe_call_shared(duk_hthread *thr,
- duk_idx_t idx_retbase,
- duk_idx_t num_stack_rets,
- 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);
+ * Limit check helpers.
+ */
+
+/* Allow headroom for calls during error augmentation (see GH-191).
+ * We allow space for 10 additional recursions, with one extra
+ * for, e.g. a print() call at the deepest level, and an extra
+ * +1 for protected call wrapping.
+ */
+#define DUK__AUGMENT_CALL_RELAX_COUNT (10 + 2)
+
+DUK_LOCAL DUK_NOINLINE void duk__call_c_recursion_limit_check_slowpath(duk_hthread *thr) {
+ /* When augmenting an error, the effective limit is a bit higher.
+ * Check for it only if the fast path check fails.
+ */
+#if defined(DUK_USE_AUGMENT_ERROR_THROW) || defined(DUK_USE_AUGMENT_ERROR_CREATE)
+ if (thr->heap->augmenting_error) {
+ if (thr->heap->call_recursion_depth < thr->heap->call_recursion_limit + DUK__AUGMENT_CALL_RELAX_COUNT) {
+ DUK_D(DUK_DPRINT("C recursion limit reached but augmenting error and within relaxed limit"));
+ return;
+ }
+ }
+#endif
+
+ DUK_D(DUK_DPRINT("call prevented because C recursion limit reached"));
+ DUK_ERROR_RANGE(thr, DUK_STR_C_CALLSTACK_LIMIT);
+}
+
+DUK_LOCAL DUK_ALWAYS_INLINE void duk__call_c_recursion_limit_check(duk_hthread *thr) {
+ DUK_ASSERT(thr->heap->call_recursion_depth >= 0);
+ DUK_ASSERT(thr->heap->call_recursion_depth <= thr->heap->call_recursion_limit);
+
+ /* This check is forcibly inlined because it's very cheap and almost
+ * always passes. The slow path is forcibly noinline.
+ */
+ if (DUK_LIKELY(thr->heap->call_recursion_depth < thr->heap->call_recursion_limit)) {
+ return;
+ }
+
+ duk__call_c_recursion_limit_check_slowpath(thr);
+}
+
+DUK_LOCAL DUK_NOINLINE void duk__call_callstack_limit_check_slowpath(duk_hthread *thr) {
+ /* When augmenting an error, the effective limit is a bit higher.
+ * Check for it only if the fast path check fails.
+ */
+#if defined(DUK_USE_AUGMENT_ERROR_THROW) || defined(DUK_USE_AUGMENT_ERROR_CREATE)
+ if (thr->heap->augmenting_error) {
+ if (thr->callstack_top < DUK_USE_CALLSTACK_LIMIT + DUK__AUGMENT_CALL_RELAX_COUNT) {
+ DUK_D(DUK_DPRINT("call stack limit reached but augmenting error and within relaxed limit"));
+ return;
+ }
+ }
+#endif
+
+ /* XXX: error message is a bit misleading: we reached a recursion
+ * limit which is also essentially the same as a C callstack limit
+ * (except perhaps with some relaxed threading assumptions).
+ */
+ DUK_D(DUK_DPRINT("call prevented because call stack limit reached"));
+ DUK_ERROR_RANGE(thr, DUK_STR_CALLSTACK_LIMIT);
+}
+
+DUK_LOCAL DUK_ALWAYS_INLINE void duk__call_callstack_limit_check(duk_hthread *thr) {
+ /* This check is forcibly inlined because it's very cheap and almost
+ * always passes. The slow path is forcibly noinline.
+ */
+ if (DUK_LIKELY(thr->callstack_top < DUK_USE_CALLSTACK_LIMIT)) {
+ return;
+ }
+
+ duk__call_callstack_limit_check_slowpath(thr);
+}
/*
* Interrupt counter fixup (for development only).
@@ -59684,9 +61117,7 @@ DUK_LOCAL void duk__interrupt_fixup(duk_hthread *thr, duk_hthread *entry_curr_th
DUK_LOCAL void duk__create_arguments_object(duk_hthread *thr,
duk_hobject *func,
duk_hobject *varenv,
- duk_idx_t idx_argbase, /* idx of first argument on stack */
- duk_idx_t num_stack_args) { /* num args starting from idx_argbase */
- duk_context *ctx = (duk_context *) thr;
+ duk_idx_t idx_args) {
duk_hobject *arg; /* 'arguments' */
duk_hobject *formals; /* formals for 'func' (may be NULL if func is a C function) */
duk_idx_t i_arg;
@@ -59696,30 +61127,30 @@ DUK_LOCAL void duk__create_arguments_object(duk_hthread *thr,
duk_idx_t i_argbase;
duk_idx_t n_formals;
duk_idx_t idx;
+ duk_idx_t num_stack_args;
duk_bool_t need_map;
- DUK_DDD(DUK_DDDPRINT("creating arguments object for func=%!iO, varenv=%!iO, "
- "idx_argbase=%ld, num_stack_args=%ld",
- (duk_heaphdr *) func, (duk_heaphdr *) varenv,
- (long) idx_argbase, (long) num_stack_args));
-
DUK_ASSERT(thr != NULL);
DUK_ASSERT(func != NULL);
DUK_ASSERT(DUK_HOBJECT_IS_NONBOUND_FUNCTION(func));
DUK_ASSERT(varenv != NULL);
- DUK_ASSERT(idx_argbase >= 0); /* assumed to bottom relative */
- DUK_ASSERT(num_stack_args >= 0);
+
+ /* [ ... func this arg1(@idx_args) ... argN envobj ]
+ * [ arg1(@idx_args) ... argN envobj ] (for tailcalls)
+ */
need_map = 0;
- i_argbase = idx_argbase;
+ i_argbase = idx_args;
+ num_stack_args = duk_get_top(thr) - i_argbase - 1;
DUK_ASSERT(i_argbase >= 0);
+ DUK_ASSERT(num_stack_args >= 0);
- duk_push_hobject(ctx, func);
- duk_get_prop_stridx_short(ctx, -1, DUK_STRIDX_INT_FORMALS);
- formals = duk_get_hobject(ctx, -1);
+ duk_push_hobject(thr, func);
+ duk_get_prop_stridx_short(thr, -1, DUK_STRIDX_INT_FORMALS);
+ formals = duk_get_hobject(thr, -1);
if (formals) {
- n_formals = (duk_idx_t) duk_get_length(ctx, -1);
+ n_formals = (duk_idx_t) duk_get_length(thr, -1);
} else {
/* This shouldn't happen without tampering of internal
* properties: if a function accesses 'arguments', _Formals
@@ -59729,8 +61160,8 @@ DUK_LOCAL void duk__create_arguments_object(duk_hthread *thr,
DUK_D(DUK_DPRINT("_Formals is undefined when creating arguments, use n_formals == 0"));
n_formals = 0;
}
- duk_remove_m2(ctx); /* leave formals on stack for later use */
- i_formals = duk_require_top_index(ctx);
+ duk_remove_m2(thr); /* leave formals on stack for later use */
+ i_formals = duk_require_top_index(thr);
DUK_ASSERT(n_formals >= 0);
DUK_ASSERT(formals != NULL || n_formals == 0);
@@ -59748,24 +61179,24 @@ DUK_LOCAL void duk__create_arguments_object(duk_hthread *thr,
* - 'mappedNames' object: temporary value used during construction
*/
- arg = duk_push_object_helper(ctx,
+ arg = duk_push_object_helper(thr,
DUK_HOBJECT_FLAG_EXTENSIBLE |
DUK_HOBJECT_FLAG_FASTREFS |
DUK_HOBJECT_FLAG_ARRAY_PART |
DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_ARGUMENTS),
DUK_BIDX_OBJECT_PROTOTYPE);
DUK_ASSERT(arg != NULL);
- (void) duk_push_object_helper(ctx,
+ (void) duk_push_object_helper(thr,
DUK_HOBJECT_FLAG_EXTENSIBLE |
DUK_HOBJECT_FLAG_FASTREFS |
DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_OBJECT),
-1); /* no prototype */
- (void) duk_push_object_helper(ctx,
+ (void) duk_push_object_helper(thr,
DUK_HOBJECT_FLAG_EXTENSIBLE |
DUK_HOBJECT_FLAG_FASTREFS |
DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_OBJECT),
-1); /* no prototype */
- i_arg = duk_get_top(ctx) - 3;
+ i_arg = duk_get_top(thr) - 3;
i_map = i_arg + 1;
i_mappednames = i_arg + 2;
@@ -59775,19 +61206,19 @@ DUK_LOCAL void duk__create_arguments_object(duk_hthread *thr,
"arguments at index %ld -> %!O "
"map at index %ld -> %!O "
"mappednames at index %ld -> %!O",
- (long) i_arg, (duk_heaphdr *) duk_get_hobject(ctx, i_arg),
- (long) i_map, (duk_heaphdr *) duk_get_hobject(ctx, i_map),
- (long) i_mappednames, (duk_heaphdr *) duk_get_hobject(ctx, i_mappednames)));
+ (long) i_arg, (duk_heaphdr *) duk_get_hobject(thr, i_arg),
+ (long) i_map, (duk_heaphdr *) duk_get_hobject(thr, i_map),
+ (long) i_mappednames, (duk_heaphdr *) duk_get_hobject(thr, i_mappednames)));
/*
* Init arguments properties, map, etc.
*/
- duk_push_int(ctx, num_stack_args);
- duk_xdef_prop_stridx(ctx, i_arg, DUK_STRIDX_LENGTH, DUK_PROPDESC_FLAGS_WC);
+ duk_push_int(thr, num_stack_args);
+ duk_xdef_prop_stridx(thr, i_arg, DUK_STRIDX_LENGTH, DUK_PROPDESC_FLAGS_WC);
/*
- * Init argument related properties
+ * Init argument related properties.
*/
/* step 11 */
@@ -59797,8 +61228,8 @@ DUK_LOCAL void duk__create_arguments_object(duk_hthread *thr,
(long) idx, (long) i_argbase, (long) (i_argbase + idx)));
DUK_DDD(DUK_DDDPRINT("define arguments[%ld]=arg", (long) idx));
- duk_dup(ctx, i_argbase + idx);
- duk_xdef_prop_index_wec(ctx, i_arg, (duk_uarridx_t) idx);
+ duk_dup(thr, i_argbase + idx);
+ duk_xdef_prop_index_wec(thr, i_arg, (duk_uarridx_t) idx);
DUK_DDD(DUK_DDDPRINT("defined arguments[%ld]=arg", (long) idx));
/* step 11.c is relevant only if non-strict (checked in 11.c.ii) */
@@ -59808,12 +61239,12 @@ DUK_LOCAL void duk__create_arguments_object(duk_hthread *thr,
DUK_DDD(DUK_DDDPRINT("strict function, index within formals (%ld < %ld)",
(long) idx, (long) n_formals));
- duk_get_prop_index(ctx, i_formals, idx);
- DUK_ASSERT(duk_is_string(ctx, -1));
+ duk_get_prop_index(thr, i_formals, (duk_uarridx_t) idx);
+ DUK_ASSERT(duk_is_string(thr, -1));
- duk_dup_top(ctx); /* [ ... name name ] */
+ duk_dup_top(thr); /* [ ... name name ] */
- if (!duk_has_prop(ctx, i_mappednames)) {
+ if (!duk_has_prop(thr, i_mappednames)) {
/* steps 11.c.ii.1 - 11.c.ii.4, but our internal book-keeping
* differs from the reference model
*/
@@ -59823,23 +61254,23 @@ DUK_LOCAL void duk__create_arguments_object(duk_hthread *thr,
need_map = 1;
DUK_DDD(DUK_DDDPRINT("set mappednames[%s]=%ld",
- (const char *) duk_get_string(ctx, -1),
+ (const char *) duk_get_string(thr, -1),
(long) idx));
- duk_dup_top(ctx); /* name */
- (void) duk_push_uint_to_hstring(ctx, (duk_uint_t) idx); /* index */
- duk_xdef_prop_wec(ctx, i_mappednames); /* out of spec, must be configurable */
+ duk_dup_top(thr); /* name */
+ (void) duk_push_uint_to_hstring(thr, (duk_uint_t) idx); /* index */
+ duk_xdef_prop_wec(thr, i_mappednames); /* out of spec, must be configurable */
DUK_DDD(DUK_DDDPRINT("set map[%ld]=%s",
(long) idx,
- duk_get_string(ctx, -1)));
- duk_dup_top(ctx); /* name */
- duk_xdef_prop_index_wec(ctx, i_map, (duk_uarridx_t) idx); /* out of spec, must be configurable */
+ duk_get_string(thr, -1)));
+ duk_dup_top(thr); /* name */
+ duk_xdef_prop_index_wec(thr, i_map, (duk_uarridx_t) idx); /* out of spec, must be configurable */
} else {
/* duk_has_prop() popped the second 'name' */
}
/* [ ... name ] */
- duk_pop(ctx); /* pop 'name' */
+ duk_pop(thr); /* pop 'name' */
}
idx--;
@@ -59854,8 +61285,8 @@ DUK_LOCAL void duk__create_arguments_object(duk_hthread *thr,
/* should never happen for a strict callee */
DUK_ASSERT(!DUK_HOBJECT_HAS_STRICT(func));
- duk_dup(ctx, i_map);
- duk_xdef_prop_stridx(ctx, i_arg, DUK_STRIDX_INT_MAP, DUK_PROPDESC_FLAGS_NONE); /* out of spec, don't care */
+ duk_dup(thr, i_map);
+ duk_xdef_prop_stridx(thr, i_arg, DUK_STRIDX_INT_MAP, DUK_PROPDESC_FLAGS_NONE); /* out of spec, don't care */
/* The variable environment for magic variable bindings needs to be
* given by the caller and recorded in the arguments object.
@@ -59866,8 +61297,8 @@ DUK_LOCAL void duk__create_arguments_object(duk_hthread *thr,
* an explicit (internal) callee property is not needed.
*/
- duk_push_hobject(ctx, varenv);
- duk_xdef_prop_stridx(ctx, i_arg, DUK_STRIDX_INT_VARENV, DUK_PROPDESC_FLAGS_NONE); /* out of spec, don't care */
+ duk_push_hobject(thr, varenv);
+ duk_xdef_prop_stridx(thr, i_arg, DUK_STRIDX_INT_VARENV, DUK_PROPDESC_FLAGS_NONE); /* out of spec, don't care */
}
/* steps 13-14 */
@@ -59887,12 +61318,12 @@ DUK_LOCAL void duk__create_arguments_object(duk_hthread *thr,
DUK_DDD(DUK_DDDPRINT("strict function, setting caller/callee to throwers"));
- duk_xdef_prop_stridx_thrower(ctx, i_arg, DUK_STRIDX_CALLER);
- duk_xdef_prop_stridx_thrower(ctx, i_arg, DUK_STRIDX_CALLEE);
+ duk_xdef_prop_stridx_thrower(thr, i_arg, DUK_STRIDX_CALLER);
+ duk_xdef_prop_stridx_thrower(thr, i_arg, DUK_STRIDX_CALLEE);
} else {
DUK_DDD(DUK_DDDPRINT("non-strict function, setting callee to actual value"));
- duk_push_hobject(ctx, func);
- duk_xdef_prop_stridx(ctx, i_arg, DUK_STRIDX_CALLEE, DUK_PROPDESC_FLAGS_WC);
+ duk_push_hobject(thr, func);
+ duk_xdef_prop_stridx(thr, i_arg, DUK_STRIDX_CALLEE, DUK_PROPDESC_FLAGS_WC);
}
/* set exotic behavior only after we're done */
@@ -59920,47 +61351,42 @@ DUK_LOCAL void duk__create_arguments_object(duk_hthread *thr,
"arguments at index %ld -> %!O "
"map at index %ld -> %!O "
"mappednames at index %ld -> %!O",
- (long) i_arg, (duk_heaphdr *) duk_get_hobject(ctx, i_arg),
- (long) i_map, (duk_heaphdr *) duk_get_hobject(ctx, i_map),
- (long) i_mappednames, (duk_heaphdr *) duk_get_hobject(ctx, i_mappednames)));
+ (long) i_arg, (duk_heaphdr *) duk_get_hobject(thr, i_arg),
+ (long) i_map, (duk_heaphdr *) duk_get_hobject(thr, i_map),
+ (long) i_mappednames, (duk_heaphdr *) duk_get_hobject(thr, i_mappednames)));
- /* [ args(n) [crud] formals arguments map mappednames ] */
+ /* [ args(n) envobj formals arguments map mappednames ] */
- duk_pop_2(ctx);
- duk_remove_m2(ctx);
+ duk_pop_2(thr);
+ duk_remove_m2(thr);
- /* [ args [crud] arguments ] */
+ /* [ args(n) envobj arguments ] */
}
/* Helper for creating the arguments object and adding it to the env record
- * on top of the value stack. This helper has a very strict dependency on
- * the shape of the input stack.
+ * on top of the value stack.
*/
DUK_LOCAL void duk__handle_createargs_for_call(duk_hthread *thr,
duk_hobject *func,
duk_hobject *env,
- duk_idx_t num_stack_args) {
- duk_context *ctx = (duk_context *) thr;
-
+ duk_idx_t idx_args) {
DUK_DDD(DUK_DDDPRINT("creating arguments object for function call"));
DUK_ASSERT(thr != NULL);
DUK_ASSERT(func != NULL);
DUK_ASSERT(env != NULL);
DUK_ASSERT(DUK_HOBJECT_HAS_CREATEARGS(func));
- DUK_ASSERT(duk_get_top(ctx) >= num_stack_args + 1);
/* [ ... arg1 ... argN envobj ] */
duk__create_arguments_object(thr,
func,
env,
- duk_get_top(ctx) - num_stack_args - 1, /* idx_argbase */
- num_stack_args);
+ idx_args);
/* [ ... arg1 ... argN envobj argobj ] */
- duk_xdef_prop_stridx_short(ctx,
+ duk_xdef_prop_stridx_short(thr,
-2,
DUK_STRIDX_LC_ARGUMENTS,
DUK_HOBJECT_HAS_STRICT(func) ? DUK_PROPDESC_FLAGS_E : /* strict: non-deletable, non-writable */
@@ -59969,117 +61395,189 @@ DUK_LOCAL void duk__handle_createargs_for_call(duk_hthread *thr,
}
/*
- * Helper for handling a "bound function" chain when a call is being made.
+ * Helpers for constructor call handling.
+ *
+ * There are two [[Construct]] operations in the specification:
*
- * Follows the bound function chain until a non-bound function is found.
- * Prepends the bound arguments to the value stack (at idx_func + 2),
- * updating 'num_stack_args' in the process. The 'this' binding is also
- * updated if necessary (at idx_func + 1). Note that for constructor calls
- * the 'this' binding is never updated by [[BoundThis]].
+ * - E5 Section 13.2.2: for Function objects
+ * - E5 Section 15.3.4.5.2: for "bound" Function objects
*
- * XXX: bound function chains could be collapsed at bound function creation
- * time so that each bound function would point directly to a non-bound
- * function. This would make call time handling much easier.
+ * The chain of bound functions is resolved in Section 15.3.4.5.2,
+ * with arguments "piling up" until the [[Construct]] internal
+ * method is called on the final, actual Function object. Note
+ * that the "prototype" property is looked up *only* from the
+ * final object, *before* calling the constructor.
+ *
+ * Since Duktape 2.2 bound functions are represented with the
+ * duk_hboundfunc internal type, and bound function chains are
+ * collapsed when a bound function is created. As a result, the
+ * direct target of a duk_hboundfunc is always non-bound and the
+ * this/argument lists have been resolved.
+ *
+ * When constructing new Array instances, an unnecessary object is
+ * created and discarded now: the standard [[Construct]] creates an
+ * object, and calls the Array constructor. The Array constructor
+ * returns an Array instance, which is used as the result value for
+ * the "new" operation; the object created before the Array constructor
+ * call is discarded.
+ *
+ * This would be easy to fix, e.g. by knowing that the Array constructor
+ * will always create a replacement object and skip creating the fallback
+ * object in that case.
+ */
+
+/* Update default instance prototype for constructor call. */
+DUK_LOCAL void duk__update_default_instance_proto(duk_hthread *thr, duk_idx_t idx_func) {
+ duk_hobject *proto;
+ duk_hobject *fallback;
+
+ DUK_ASSERT(duk_is_constructable(thr, idx_func));
+
+ duk_get_prop_stridx_short(thr, idx_func, DUK_STRIDX_PROTOTYPE);
+ proto = duk_get_hobject(thr, -1);
+ if (proto == NULL) {
+ DUK_DDD(DUK_DDDPRINT("constructor has no 'prototype' property, or value not an object "
+ "-> leave standard Object prototype as fallback prototype"));
+ } else {
+ DUK_DDD(DUK_DDDPRINT("constructor has 'prototype' property with object value "
+ "-> set fallback prototype to that value: %!iO", (duk_heaphdr *) proto));
+ /* Original fallback (default instance) is untouched when
+ * resolving bound functions etc.
+ */
+ fallback = duk_known_hobject(thr, idx_func + 1);
+ DUK_ASSERT(fallback != NULL);
+ DUK_HOBJECT_SET_PROTOTYPE_UPDREF(thr, fallback, proto);
+ }
+ duk_pop(thr);
+}
+
+/* Postprocess: return value special handling, error augmentation. */
+DUK_INTERNAL void duk_call_construct_postprocess(duk_hthread *thr, duk_small_uint_t proxy_invariant) {
+ /* Use either fallback (default instance) or retval depending
+ * on retval type. Needs to be called before unwind because
+ * the default instance is read from the current (immutable)
+ * 'this' binding.
+ *
+ * For Proxy 'construct' calls the return value must be an
+ * Object (we accept object-like values like buffers and
+ * lightfuncs too). If not, TypeError.
+ */
+ if (duk_check_type_mask(thr, -1, DUK_TYPE_MASK_OBJECT |
+ DUK_TYPE_MASK_BUFFER |
+ DUK_TYPE_MASK_LIGHTFUNC)) {
+ DUK_DDD(DUK_DDDPRINT("replacement value"));
+ } else {
+ if (DUK_UNLIKELY(proxy_invariant != 0U)) {
+ /* Proxy 'construct' return value invariant violated. */
+ DUK_ERROR_TYPE_INVALID_TRAP_RESULT(thr);
+ }
+ /* XXX: direct value stack access */
+ duk_pop(thr);
+ duk_push_this(thr);
+ }
+
+#if defined(DUK_USE_AUGMENT_ERROR_CREATE)
+ /* Augment created errors upon creation, not when they are thrown or
+ * rethrown. __FILE__ and __LINE__ are not desirable here; the call
+ * stack reflects the caller which is correct. Skip topmost, unwound
+ * activation when creating a traceback. If thr->ptr_curr_pc was !=
+ * NULL we'd need to sync the current PC so that the traceback comes
+ * out right; however it is always synced here so just assert for it.
+ */
+ DUK_ASSERT(thr->ptr_curr_pc == NULL);
+ duk_err_augment_error_create(thr, thr, NULL, 0, DUK_AUGMENT_FLAG_NOBLAME_FILELINE |
+ DUK_AUGMENT_FLAG_SKIP_ONE);
+#endif
+}
+
+/*
+ * Helper for handling a bound function when a call is being made.
+ *
+ * Assumes that bound function chains have been "collapsed" so that either
+ * the target is non-bound or there is one bound function that points to a
+ * nonbound target.
+ *
+ * Prepends the bound arguments to the value stack (at idx_func + 2).
+ * The 'this' binding is also updated if necessary (at idx_func + 1).
+ * Note that for constructor calls the 'this' binding is never updated by
+ * [[BoundThis]].
*/
DUK_LOCAL void duk__handle_bound_chain_for_call(duk_hthread *thr,
duk_idx_t idx_func,
- duk_idx_t *p_num_stack_args, /* may be changed by call */
duk_bool_t is_constructor_call) {
- duk_context *ctx = (duk_context *) thr;
- duk_idx_t num_stack_args;
duk_tval *tv_func;
duk_hobject *func;
- duk_uint_t sanity;
+ duk_idx_t len;
DUK_ASSERT(thr != NULL);
- DUK_ASSERT(p_num_stack_args != NULL);
/* On entry, item at idx_func is a bound, non-lightweight function,
* but we don't rely on that below.
*/
- num_stack_args = *p_num_stack_args;
+ DUK_ASSERT(duk_get_top(thr) >= idx_func + 2);
- sanity = DUK_HOBJECT_BOUND_CHAIN_SANITY;
- do {
- duk_idx_t i, len;
+ tv_func = duk_require_tval(thr, idx_func);
+ DUK_ASSERT(tv_func != NULL);
- tv_func = duk_require_tval(ctx, idx_func);
- DUK_ASSERT(tv_func != NULL);
+ if (DUK_TVAL_IS_OBJECT(tv_func)) {
+ func = DUK_TVAL_GET_OBJECT(tv_func);
- if (DUK_TVAL_IS_LIGHTFUNC(tv_func)) {
- /* Lightweight function: never bound, so terminate. */
- break;
- } else if (DUK_TVAL_IS_OBJECT(tv_func)) {
- func = DUK_TVAL_GET_OBJECT(tv_func);
- if (!DUK_HOBJECT_HAS_BOUNDFUNC(func)) {
- /* Normal non-bound function. */
- break;
- }
- } else {
- /* Function.prototype.bind() should never let this happen,
- * ugly error message is enough.
- */
- DUK_ERROR_INTERNAL(thr);
- }
- DUK_ASSERT(DUK_TVAL_GET_OBJECT(tv_func) != NULL);
+ /* XXX: separate helper function, out of fast path? */
+ if (DUK_HOBJECT_HAS_BOUNDFUNC(func)) {
+ duk_hboundfunc *h_bound;
+ duk_tval *tv_args;
+ duk_tval *tv_gap;
- /* XXX: this could be more compact by accessing the internal properties
- * directly as own properties (they cannot be inherited, and are not
- * externally visible).
- */
+ h_bound = (duk_hboundfunc *) func;
+ tv_args = h_bound->args;
+ len = h_bound->nargs;
+ DUK_ASSERT(len == 0 || tv_args != NULL);
- DUK_DDD(DUK_DDDPRINT("bound function encountered, ptr=%p, num_stack_args=%ld: %!T",
- (void *) DUK_TVAL_GET_OBJECT(tv_func), (long) num_stack_args, tv_func));
+ DUK_DDD(DUK_DDDPRINT("bound function encountered, ptr=%p: %!T",
+ (void *) DUK_TVAL_GET_OBJECT(tv_func), tv_func));
- /* [ ... func this arg1 ... argN ] */
+ /* [ ... func this arg1 ... argN ] */
- if (is_constructor_call) {
- /* See: tests/ecmascript/test-spec-bound-constructor.js */
- DUK_DDD(DUK_DDDPRINT("constructor call: don't update this binding"));
- } else {
- duk_get_prop_stridx(ctx, idx_func, DUK_STRIDX_INT_THIS);
- duk_replace(ctx, idx_func + 1); /* idx_this = idx_func + 1 */
- }
+ if (is_constructor_call) {
+ /* See: tests/ecmascript/test-spec-bound-constructor.js */
+ DUK_DDD(DUK_DDDPRINT("constructor call: don't update this binding"));
+ } else {
+ /* XXX: duk_replace_tval */
+ duk_push_tval(thr, &h_bound->this_binding);
+ duk_replace(thr, idx_func + 1); /* idx_this = idx_func + 1 */
+ }
- /* [ ... func this arg1 ... argN ] */
+ /* [ ... func this arg1 ... argN ] */
- /* XXX: duk_get_length? */
- duk_get_prop_stridx(ctx, idx_func, DUK_STRIDX_INT_ARGS); /* -> [ ... func this arg1 ... argN _Args ] */
- duk_get_prop_stridx_short(ctx, -1, DUK_STRIDX_LENGTH); /* -> [ ... func this arg1 ... argN _Args length ] */
- len = (duk_idx_t) duk_require_int(ctx, -1);
- duk_pop(ctx);
- for (i = 0; i < len; i++) {
- /* XXX: very slow - better to bulk allocate a gap, and copy
- * from args_array directly (we know it has a compact array
- * part, etc).
- */
+ duk_require_stack(thr, len);
- /* [ ... func this <some bound args> arg1 ... argN _Args ] */
- duk_get_prop_index(ctx, -1, i);
- duk_insert(ctx, idx_func + 2 + i); /* idx_args = idx_func + 2 */
- }
- num_stack_args += len; /* must be updated to work properly (e.g. creation of 'arguments') */
- duk_pop(ctx);
-
- /* [ ... func this <bound args> arg1 ... argN ] */
+ tv_gap = duk_reserve_gap(thr, idx_func + 2, len);
+ duk_copy_tvals_incref(thr, tv_gap, tv_args, (duk_size_t) len);
- duk_get_prop_stridx(ctx, idx_func, DUK_STRIDX_INT_TARGET);
- duk_replace(ctx, idx_func); /* replace in stack */
+ /* [ ... func this <bound args> arg1 ... argN ] */
- DUK_DDD(DUK_DDDPRINT("bound function handled, num_stack_args=%ld, idx_func=%ld, curr func=%!T",
- (long) num_stack_args, (long) idx_func, duk_get_tval(ctx, idx_func)));
- } while (--sanity > 0);
+ duk_push_tval(thr, &h_bound->target);
+ duk_replace(thr, idx_func); /* replace in stack */
- if (DUK_UNLIKELY(sanity == 0)) {
- DUK_ERROR_RANGE(thr, DUK_STR_BOUND_CHAIN_LIMIT);
+ DUK_DDD(DUK_DDDPRINT("bound function handled, idx_func=%ld, curr func=%!T",
+ (long) idx_func, duk_get_tval(thr, idx_func)));
+ }
+ } else if (DUK_TVAL_IS_LIGHTFUNC(tv_func)) {
+ /* Lightweight function: never bound, so terminate. */
+ ;
+ } else {
+ /* Shouldn't happen, so ugly error is enough. */
+ DUK_ERROR_INTERNAL(thr);
}
- DUK_DDD(DUK_DDDPRINT("final non-bound function is: %!T", duk_get_tval(ctx, idx_func)));
+ DUK_ASSERT(duk_get_top(thr) >= idx_func + 2);
+
+ DUK_DDD(DUK_DDDPRINT("final non-bound function is: %!T", duk_get_tval(thr, idx_func)));
#if defined(DUK_USE_ASSERTIONS)
- tv_func = duk_require_tval(ctx, idx_func);
+ tv_func = duk_require_tval(thr, idx_func);
DUK_ASSERT(DUK_TVAL_IS_LIGHTFUNC(tv_func) || DUK_TVAL_IS_OBJECT(tv_func));
if (DUK_TVAL_IS_OBJECT(tv_func)) {
func = DUK_TVAL_GET_OBJECT(tv_func);
@@ -60089,12 +61587,326 @@ DUK_LOCAL void duk__handle_bound_chain_for_call(duk_hthread *thr,
DUK_HOBJECT_HAS_NATFUNC(func));
}
#endif
+}
+
+/*
+ * Helper for inline handling of .call(), .apply(), and .construct().
+ */
+
+DUK_LOCAL duk_bool_t duk__handle_specialfuncs_for_call(duk_hthread *thr, duk_idx_t idx_func, duk_hobject *func, duk_small_uint_t *call_flags, duk_bool_t first) {
+#if defined(DUK_USE_ASSERTIONS)
+ duk_c_function natfunc;
+#endif
+ duk_tval *tv_args;
+
+ DUK_ASSERT(func != NULL);
+ DUK_ASSERT((*call_flags & DUK_CALL_FLAG_CONSTRUCT) == 0); /* Caller. */
+
+#if defined(DUK_USE_ASSERTIONS)
+ natfunc = ((duk_hnatfunc *) func)->func;
+ DUK_ASSERT(natfunc != NULL);
+#endif
+
+ /* On every round of function resolution at least target function and
+ * 'this' binding are set. We can assume that here, and must guarantee
+ * it on exit. Value stack reserve is extended for bound function and
+ * .apply() unpacking so we don't need to extend it here when we need a
+ * few slots.
+ */
+ DUK_ASSERT(duk_get_top(thr) >= idx_func + 2);
+
+ /* Handle native 'eval' specially. A direct eval check is only made
+ * for the first resolution attempt; e.g. a bound eval call is -not-
+ * a direct eval call.
+ */
+ if (DUK_UNLIKELY(((duk_hnatfunc *) func)->magic == 15)) {
+ /* For now no special handling except for direct eval
+ * detection.
+ */
+ DUK_ASSERT(((duk_hnatfunc *) func)->func == duk_bi_global_object_eval);
+ if (first && (*call_flags & DUK_CALL_FLAG_CALLED_AS_EVAL)) {
+ *call_flags = (*call_flags & ~DUK_CALL_FLAG_CALLED_AS_EVAL) | DUK_CALL_FLAG_DIRECT_EVAL;
+ }
+ DUK_ASSERT(duk_get_top(thr) >= idx_func + 2);
+ return 1; /* stop resolving */
+ }
+
+ /* Handle special functions based on the DUK_HOBJECT_FLAG_SPECIAL_CALL
+ * flag; their magic value is used for switch-case.
+ *
+ * NOTE: duk_unpack_array_like() reserves value stack space
+ * for the result values (unlike most other value stack calls).
+ */
+ switch (((duk_hnatfunc *) func)->magic) {
+ case 0: { /* 0=Function.prototype.call() */
+ /* Value stack:
+ * idx_func + 0: Function.prototype.call() [removed]
+ * idx_func + 1: this binding for .call (target function)
+ * idx_func + 2: 1st argument to .call, desired 'this' binding
+ * idx_func + 3: 2nd argument to .call, desired 1st argument for ultimate target
+ * ...
+ *
+ * Remove idx_func + 0 to get:
+ * idx_func + 0: target function
+ * idx_func + 1: this binding
+ * idx_func + 2: call arguments
+ * ...
+ */
+ DUK_ASSERT(natfunc == duk_bi_function_prototype_call);
+ duk_remove_unsafe(thr, idx_func);
+ tv_args = thr->valstack_bottom + idx_func + 2;
+ if (thr->valstack_top < tv_args) {
+ DUK_ASSERT(tv_args <= thr->valstack_end);
+ thr->valstack_top = tv_args; /* at least target function and 'this' binding present */
+ }
+ break;
+ }
+ case 1: { /* 1=Function.prototype.apply() */
+ /* Value stack:
+ * idx_func + 0: Function.prototype.apply() [removed]
+ * idx_func + 1: this binding for .apply (target function)
+ * idx_func + 2: 1st argument to .apply, desired 'this' binding
+ * idx_func + 3: 2nd argument to .apply, argArray
+ * [anything after this MUST be ignored]
+ *
+ * Remove idx_func + 0 and unpack the argArray to get:
+ * idx_func + 0: target function
+ * idx_func + 1: this binding
+ * idx_func + 2: call arguments
+ * ...
+ */
+ DUK_ASSERT(natfunc == duk_bi_function_prototype_apply);
+ duk_remove_unsafe(thr, idx_func);
+ goto apply_shared;
+ }
+#if defined(DUK_USE_REFLECT_BUILTIN)
+ case 2: { /* 2=Reflect.apply() */
+ /* Value stack:
+ * idx_func + 0: Reflect.apply() [removed]
+ * idx_func + 1: this binding for .apply (ignored, usually Reflect) [removed]
+ * idx_func + 2: 1st argument to .apply, target function
+ * idx_func + 3: 2nd argument to .apply, desired 'this' binding
+ * idx_func + 4: 3rd argument to .apply, argArray
+ * [anything after this MUST be ignored]
+ *
+ * Remove idx_func + 0 and idx_func + 1, and unpack the argArray to get:
+ * idx_func + 0: target function
+ * idx_func + 1: this binding
+ * idx_func + 2: call arguments
+ * ...
+ */
+ DUK_ASSERT(natfunc == duk_bi_reflect_apply);
+ duk_remove_n_unsafe(thr, idx_func, 2);
+ goto apply_shared;
+ }
+ case 3: { /* 3=Reflect.construct() */
+ /* Value stack:
+ * idx_func + 0: Reflect.construct() [removed]
+ * idx_func + 1: this binding for .construct (ignored, usually Reflect) [removed]
+ * idx_func + 2: 1st argument to .construct, target function
+ * idx_func + 3: 2nd argument to .construct, argArray
+ * idx_func + 4: 3rd argument to .construct, newTarget
+ * [anything after this MUST be ignored]
+ *
+ * Remove idx_func + 0 and idx_func + 1, unpack the argArray,
+ * and insert default instance (prototype not yet updated), to get:
+ * idx_func + 0: target function
+ * idx_func + 1: this binding (default instance)
+ * idx_func + 2: constructor call arguments
+ * ...
+ *
+ * Call flags must be updated to reflect the fact that we're
+ * now dealing with a constructor call, and e.g. the 'this'
+ * binding cannot be overwritten if the target is bound.
+ *
+ * newTarget is checked but not yet passed onwards.
+ */
+
+ duk_idx_t top;
+
+ DUK_ASSERT(natfunc == duk_bi_reflect_construct);
+ *call_flags |= DUK_CALL_FLAG_CONSTRUCT;
+ duk_remove_n_unsafe(thr, idx_func, 2);
+ top = duk_get_top(thr);
+ if (!duk_is_constructable(thr, idx_func)) {
+ /* Target constructability must be checked before
+ * unpacking argArray (which may cause side effects).
+ * Just return; caller will throw the error.
+ */
+ duk_set_top_unsafe(thr, idx_func + 2); /* satisfy asserts */
+ break;
+ }
+ duk_push_object(thr);
+ duk_insert(thr, idx_func + 1); /* default instance */
+
+ /* [ ... func default_instance argArray newTarget? ] */
+
+ top = duk_get_top(thr);
+ if (top < idx_func + 3) {
+ /* argArray is a mandatory argument for Reflect.construct(). */
+ DUK_ERROR_TYPE_INVALID_ARGS(thr);
+ }
+ if (top > idx_func + 3) {
+ if (!duk_strict_equals(thr, idx_func, idx_func + 3)) {
+ /* XXX: [[Construct]] newTarget currently unsupported */
+ DUK_ERROR_UNSUPPORTED(thr);
+ }
+ duk_set_top_unsafe(thr, idx_func + 3); /* remove any args beyond argArray */
+ }
+ DUK_ASSERT(duk_get_top(thr) == idx_func + 3);
+ DUK_ASSERT(duk_is_valid_index(thr, idx_func + 2));
+ (void) duk_unpack_array_like(thr, idx_func + 2); /* XXX: should also remove target to be symmetric with duk_pack()? */
+ duk_remove(thr, idx_func + 2);
+ DUK_ASSERT(duk_get_top(thr) >= idx_func + 2);
+ break;
+ }
+#endif /* DUK_USE_REFLECT_BUILTIN */
+ default: {
+ DUK_ASSERT(0);
+ DUK_UNREACHABLE();
+ }
+ }
+
+ DUK_ASSERT(duk_get_top(thr) >= idx_func + 2);
+ return 0; /* keep resolving */
- /* write back */
- *p_num_stack_args = num_stack_args;
+ apply_shared:
+ tv_args = thr->valstack_bottom + idx_func + 2;
+ if (thr->valstack_top <= tv_args) {
+ DUK_ASSERT(tv_args <= thr->valstack_end);
+ thr->valstack_top = tv_args; /* at least target func and 'this' binding present */
+ /* No need to check for argArray. */
+ } else {
+ DUK_ASSERT(duk_get_top(thr) >= idx_func + 3); /* idx_func + 2 covered above */
+ if (thr->valstack_top > tv_args + 1) {
+ duk_set_top_unsafe(thr, idx_func + 3); /* remove any args beyond argArray */
+ }
+ DUK_ASSERT(duk_is_valid_index(thr, idx_func + 2));
+ if (!duk_is_callable(thr, idx_func)) {
+ /* Avoid unpack side effects if the target isn't callable.
+ * Calling code will throw the actual error.
+ */
+ } else {
+ (void) duk_unpack_array_like(thr, idx_func + 2);
+ duk_remove(thr, idx_func + 2);
+ }
+ }
+ DUK_ASSERT(duk_get_top(thr) >= idx_func + 2);
+ return 0; /* keep resolving */
}
/*
+ * Helper for Proxy handling.
+ */
+
+#if defined(DUK_USE_ES6_PROXY)
+DUK_LOCAL void duk__handle_proxy_for_call(duk_hthread *thr, duk_idx_t idx_func, duk_hproxy *h_proxy, duk_small_uint_t *call_flags) {
+ duk_bool_t rc;
+
+ /* Value stack:
+ * idx_func + 0: Proxy object
+ * idx_func + 1: this binding for call
+ * idx_func + 2: 1st argument for call
+ * idx_func + 3: 2nd argument for call
+ * ...
+ *
+ * If Proxy doesn't have a trap for the call ('apply' or 'construct'),
+ * replace Proxy object with target object.
+ *
+ * If we're dealing with a normal call and the Proxy has an 'apply'
+ * trap, manipulate value stack to:
+ *
+ * idx_func + 0: trap
+ * idx_func + 1: Proxy's handler
+ * idx_func + 2: Proxy's target
+ * idx_func + 3: this binding for call (from idx_func + 1)
+ * idx_func + 4: call arguments packed to an array
+ *
+ * If we're dealing with a constructor call and the Proxy has a
+ * 'construct' trap, manipulate value stack to:
+ *
+ * idx_func + 0: trap
+ * idx_func + 1: Proxy's handler
+ * idx_func + 2: Proxy's target
+ * idx_func + 3: call arguments packed to an array
+ * idx_func + 4: newTarget == Proxy object here
+ *
+ * As we don't yet have proper newTarget support, the newTarget at
+ * idx_func + 3 is just the original constructor being called, i.e.
+ * the Proxy object (not the target). Note that the default instance
+ * (original 'this' binding) is dropped and ignored.
+ */
+
+ duk_push_hobject(thr, h_proxy->handler);
+ rc = duk_get_prop_stridx_short(thr, -1, (*call_flags & DUK_CALL_FLAG_CONSTRUCT) ? DUK_STRIDX_CONSTRUCT : DUK_STRIDX_APPLY);
+ if (rc == 0) {
+ /* Not found, continue to target. If this is a construct
+ * call, update default instance prototype using the Proxy,
+ * not the target.
+ */
+ if (*call_flags & DUK_CALL_FLAG_CONSTRUCT) {
+ if (!(*call_flags & DUK_CALL_FLAG_DEFAULT_INSTANCE_UPDATED)) {
+ *call_flags |= DUK_CALL_FLAG_DEFAULT_INSTANCE_UPDATED;
+ duk__update_default_instance_proto(thr, idx_func);
+ }
+ }
+ duk_pop_2(thr);
+ duk_push_hobject(thr, h_proxy->target);
+ duk_replace(thr, idx_func);
+ return;
+ }
+
+ /* Here we must be careful not to replace idx_func while
+ * h_proxy is still needed, otherwise h_proxy may become
+ * dangling. This could be improved e.g. using a
+ * duk_pack_slice() with a freeform slice.
+ */
+
+ /* Here:
+ * idx_func + 0: Proxy object
+ * idx_func + 1: this binding for call
+ * idx_func + 2: 1st argument for call
+ * idx_func + 3: 2nd argument for call
+ * ...
+ * idx_func + N: handler
+ * idx_func + N + 1: trap
+ */
+
+ duk_insert(thr, idx_func + 1);
+ duk_insert(thr, idx_func + 2);
+ duk_push_hobject(thr, h_proxy->target);
+ duk_insert(thr, idx_func + 3);
+ duk_pack(thr, duk_get_top(thr) - (idx_func + 5));
+
+ /* Here:
+ * idx_func + 0: Proxy object
+ * idx_func + 1: trap
+ * idx_func + 2: Proxy's handler
+ * idx_func + 3: Proxy's target
+ * idx_func + 4: this binding for call
+ * idx_func + 5: arguments array
+ */
+ DUK_ASSERT(duk_get_top(thr) == idx_func + 6);
+
+ if (*call_flags & DUK_CALL_FLAG_CONSTRUCT) {
+ *call_flags |= DUK_CALL_FLAG_CONSTRUCT_PROXY; /* Enable 'construct' trap return invariant check. */
+ *call_flags &= ~(DUK_CALL_FLAG_CONSTRUCT); /* Resume as non-constructor call to the trap. */
+
+ /* 'apply' args: target, thisArg, argArray
+ * 'construct' args: target, argArray, newTarget
+ */
+ duk_remove(thr, idx_func + 4);
+ duk_push_hobject(thr, (duk_hobject *) h_proxy);
+ }
+
+ /* Finalize value stack layout by removing Proxy reference. */
+ duk_remove(thr, idx_func);
+ h_proxy = NULL; /* invalidated */
+ DUK_ASSERT(duk_get_top(thr) == idx_func + 5);
+}
+#endif /* DUK_USE_ES6_PROXY */
+
+/*
* Helper for setting up var_env and lex_env of an activation,
* assuming it does NOT have the DUK_HOBJECT_FLAG_NEWENV flag.
*/
@@ -60149,7 +61961,7 @@ DUK_LOCAL void duk__update_func_caller_prop(duk_hthread *thr, duk_hobject *func)
DUK_ASSERT(thr->callstack_top > 0);
act_callee = thr->callstack_curr;
DUK_ASSERT(act_callee != NULL);
- act_caller = (thr->callstack_top >= 2 ? act_callee - 1 : NULL);
+ act_caller = (thr->callstack_top >= 2 ? act_callee->parent : NULL);
/* XXX: check .caller writability? */
@@ -60166,7 +61978,7 @@ DUK_LOCAL void duk__update_func_caller_prop(duk_hthread *thr, duk_hobject *func)
* because 'func' has been resolved to a non-bound function.
*/
- if (act_caller) {
+ if (act_caller != NULL) {
/* act_caller->func may be NULL in some finalization cases,
* just treat like we don't know the caller.
*/
@@ -60187,7 +61999,7 @@ DUK_LOCAL void duk__update_func_caller_prop(duk_hthread *thr, duk_hobject *func)
* is transferred to prev_caller.
*/
- if (act_caller) {
+ if (act_caller != NULL) {
DUK_ASSERT(act_caller->func != NULL);
DUK_TVAL_SET_OBJECT(tv_caller, act_caller->func);
DUK_TVAL_INCREF(thr, tv_caller);
@@ -60198,7 +62010,7 @@ DUK_LOCAL void duk__update_func_caller_prop(duk_hthread *thr, duk_hobject *func)
/* 'caller' must only take on 'null' or function value */
DUK_ASSERT(!DUK_TVAL_IS_HEAP_ALLOCATED(tv_caller));
DUK_ASSERT(act_callee->prev_caller == NULL);
- if (act_caller && act_caller->func) {
+ if (act_caller != NULL && act_caller->func) {
/* Tolerate act_caller->func == NULL which happens in
* some finalization cases; treat like unknown caller.
*/
@@ -60213,15 +62025,21 @@ DUK_LOCAL void duk__update_func_caller_prop(duk_hthread *thr, duk_hobject *func)
#endif /* DUK_USE_NONSTD_FUNC_CALLER_PROPERTY */
/*
- * Determine the effective 'this' binding and coerce the current value
- * on the valstack to the effective one (in-place, at idx_this).
+ * Shared helpers for resolving the final, non-bound target function of the
+ * call and the effective 'this' binding. Resolves bound functions and
+ * applies .call(), .apply(), and .construct() inline.
+ *
+ * Proxy traps are also handled inline so that if the target is a Proxy with
+ * a 'call' or 'construct' trap, the trap handler is called with a modified
+ * argument list.
*
- * The current this value in the valstack (at idx_this) represents either:
- * - the caller's requested 'this' binding; or
- * - a 'this' binding accumulated from the bound function chain
+ * Once the bound function / .call() / .apply() / .construct() sequence has
+ * been resolved, the value at idx_func + 1 may need coercion described in
+ * E5 Section 10.4.3.
*
- * The final 'this' binding for the target function may still be
- * different, and is determined as described in E5 Section 10.4.3.
+ * A call that begins as a non-constructor call may be converted into a
+ * constructor call during the resolution process if Reflect.construct()
+ * is invoked. This is handled by updating the caller's call_flags.
*
* For global and eval code (E5 Sections 10.4.1 and 10.4.2), we assume
* that the caller has provided the correct 'this' binding explicitly
@@ -60231,24 +62049,14 @@ DUK_LOCAL void duk__update_func_caller_prop(duk_hthread *thr, duk_hobject *func)
* - direct eval: this=copy from eval() caller's this binding
* - other eval: this=global object
*
- * Note: this function may cause a recursive function call with arbitrary
+ * The 'this' coercion may cause a recursive function call with arbitrary
* side effects, because ToObject() may be called.
*/
-DUK_LOCAL void duk__coerce_effective_this_binding(duk_hthread *thr,
- duk_hobject *func,
- duk_idx_t idx_this) {
- duk_context *ctx = (duk_context *) thr;
+DUK_LOCAL DUK_INLINE void duk__coerce_nonstrict_this_binding(duk_hthread *thr, duk_idx_t idx_this) {
duk_tval *tv_this;
duk_hobject *obj_global;
- if (func == NULL || DUK_HOBJECT_HAS_STRICT(func)) {
- /* Lightfuncs are always considered strict. */
- DUK_DDD(DUK_DDDPRINT("this binding: strict -> use directly"));
- return;
- }
-
- /* XXX: byte offset */
tv_this = thr->valstack_bottom + idx_this;
switch (DUK_TVAL_GET_TAG(tv_this)) {
case DUK_TAG_OBJECT:
@@ -60275,144 +62083,238 @@ DUK_LOCAL void duk__coerce_effective_this_binding(duk_hthread *thr,
default:
/* Plain buffers and lightfuncs are object coerced. Lightfuncs
* very rarely come here however, because the call target would
- * need to be a strict non-lightfunc (lightfuncs are considered
+ * need to be a non-strict non-lightfunc (lightfuncs are considered
* strict) with an explicit lightfunc 'this' binding.
*/
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 */
+ duk_to_object(thr, idx_this); /* may have side effects */
break;
}
}
-/*
- * Shared helper for non-bound func lookup.
- *
- * Returns duk_hobject * to the final non-bound function (NULL for lightfunc).
- */
+DUK_LOCAL DUK_ALWAYS_INLINE duk_bool_t duk__resolve_target_fastpath_check(duk_hthread *thr, duk_idx_t idx_func, duk_hobject **out_func, duk_small_uint_t call_flags) {
+#if defined(DUK_USE_PREFER_SIZE)
+ DUK_UNREF(thr);
+ DUK_UNREF(idx_func);
+ DUK_UNREF(out_func);
+ DUK_UNREF(call_flags);
+#else /* DUK_USE_PREFER_SIZE */
+ duk_tval *tv_func;
+ duk_hobject *func;
-DUK_LOCAL duk_hobject *duk__nonbound_func_lookup(duk_context *ctx,
- duk_idx_t idx_func,
- duk_idx_t *out_num_stack_args,
- duk_tval **out_tv_func,
- duk_small_uint_t call_flags) {
- duk_hthread *thr = (duk_hthread *) ctx;
+ if (DUK_UNLIKELY(call_flags & DUK_CALL_FLAG_CONSTRUCT)) {
+ return 0;
+ }
+
+ tv_func = DUK_GET_TVAL_POSIDX(thr, idx_func);
+ DUK_ASSERT(tv_func != NULL);
+
+ if (DUK_LIKELY(DUK_TVAL_IS_OBJECT(tv_func))) {
+ func = DUK_TVAL_GET_OBJECT(tv_func);
+ if (DUK_HOBJECT_IS_CALLABLE(func) &&
+ !DUK_HOBJECT_HAS_BOUNDFUNC(func) &&
+ !DUK_HOBJECT_HAS_SPECIAL_CALL(func)) {
+ *out_func = func;
+
+ if (DUK_HOBJECT_HAS_STRICT(func)) {
+ /* Strict function: no 'this' coercion. */
+ return 1;
+ }
+
+ duk__coerce_nonstrict_this_binding(thr, idx_func + 1);
+ return 1;
+ }
+ } else if (DUK_TVAL_IS_LIGHTFUNC(tv_func)) {
+ *out_func = NULL;
+
+ /* Lightfuncs are considered strict, so 'this' binding is
+ * used as is. They're never bound, always constructable,
+ * and never special functions.
+ */
+ return 1;
+ }
+#endif /* DUK_USE_PREFER_SIZE */
+ return 0; /* let slow path deal with it */
+}
+
+DUK_LOCAL duk_hobject *duk__resolve_target_func_and_this_binding(duk_hthread *thr,
+ duk_idx_t idx_func,
+ duk_small_uint_t *call_flags) {
duk_tval *tv_func;
duk_hobject *func;
+ duk_bool_t first;
- for (;;) {
- /* Use loop to minimize code size of relookup after bound function case */
- tv_func = DUK_GET_TVAL_POSIDX(ctx, idx_func);
+ DUK_ASSERT(duk_get_top(thr) >= idx_func + 2);
+
+ for (first = 1;; first = 0) {
+ DUK_ASSERT(duk_get_top(thr) >= idx_func + 2);
+
+ tv_func = DUK_GET_TVAL_POSIDX(thr, idx_func);
DUK_ASSERT(tv_func != NULL);
if (DUK_TVAL_IS_OBJECT(tv_func)) {
func = DUK_TVAL_GET_OBJECT(tv_func);
- if (!DUK_HOBJECT_IS_CALLABLE(func)) {
- goto not_callable_error;
+
+ if (*call_flags & DUK_CALL_FLAG_CONSTRUCT) {
+ if (DUK_UNLIKELY(!DUK_HOBJECT_HAS_CONSTRUCTABLE(func))) {
+ goto not_constructable;
+ }
+ } else {
+ if (DUK_UNLIKELY(!DUK_HOBJECT_IS_CALLABLE(func))) {
+ goto not_callable;
+ }
}
+
+ if (DUK_LIKELY(!DUK_HOBJECT_HAS_BOUNDFUNC(func) &&
+ !DUK_HOBJECT_HAS_SPECIAL_CALL(func) &&
+ !DUK_HOBJECT_HAS_EXOTIC_PROXYOBJ(func))) {
+ /* Common case, so test for using a single bitfield test.
+ * Break out to handle this coercion etc.
+ */
+ break;
+ }
+
+ /* XXX: could set specialcall for boundfuncs too, simplify check above */
+
if (DUK_HOBJECT_HAS_BOUNDFUNC(func)) {
- duk__handle_bound_chain_for_call(thr, idx_func, out_num_stack_args, call_flags & DUK_CALL_FLAG_CONSTRUCTOR_CALL);
+ DUK_ASSERT(!DUK_HOBJECT_HAS_SPECIAL_CALL(func));
+ DUK_ASSERT(!DUK_HOBJECT_IS_NATFUNC(func));
- /* The final object may be a normal function or a lightfunc.
- * We need to re-lookup tv_func because it may have changed
- * (also value stack may have been resized). Loop again to
- * do that; we're guaranteed not to come here again.
+ /* Callable/constructable flags are the same
+ * for the bound function and its target, so
+ * we don't need to check them here, we can
+ * check them from the target only.
*/
- DUK_ASSERT(DUK_TVAL_IS_OBJECT(duk_require_tval(ctx, idx_func)) ||
- DUK_TVAL_IS_LIGHTFUNC(duk_require_tval(ctx, idx_func)));
- continue;
+ duk__handle_bound_chain_for_call(thr, idx_func, *call_flags & DUK_CALL_FLAG_CONSTRUCT);
+
+ DUK_ASSERT(DUK_TVAL_IS_OBJECT(duk_require_tval(thr, idx_func)) ||
+ DUK_TVAL_IS_LIGHTFUNC(duk_require_tval(thr, idx_func)));
+ } else {
+ DUK_ASSERT(DUK_HOBJECT_HAS_SPECIAL_CALL(func));
+
+#if defined(DUK_USE_ES6_PROXY)
+ if (DUK_HOBJECT_HAS_EXOTIC_PROXYOBJ(func)) {
+ /* If no trap, resume processing from Proxy trap.
+ * If trap exists, helper converts call into a trap
+ * call; this may change a constructor call into a
+ * normal (non-constructor) trap call. We must
+ * continue processing even when a trap is found as
+ * the trap may be bound.
+ */
+ duk__handle_proxy_for_call(thr, idx_func, (duk_hproxy *) func, call_flags);
+ }
+ else
+#endif
+ {
+ DUK_ASSERT(DUK_HOBJECT_IS_NATFUNC(func));
+ DUK_ASSERT(DUK_HOBJECT_HAS_CALLABLE(func));
+ DUK_ASSERT(!DUK_HOBJECT_HAS_CONSTRUCTABLE(func));
+ /* Constructable check already done above. */
+
+ if (duk__handle_specialfuncs_for_call(thr, idx_func, func, call_flags, first) != 0) {
+ /* Encountered native eval call, normal call
+ * context. Break out, handle this coercion etc.
+ */
+ break;
+ }
+ }
}
+ /* Retry loop. */
} else if (DUK_TVAL_IS_LIGHTFUNC(tv_func)) {
+ /* Lightfuncs are:
+ * - Always strict, so no 'this' coercion.
+ * - Always callable.
+ * - Always constructable.
+ * - Never specialfuncs.
+ */
func = NULL;
+ goto finished;
} else {
- goto not_callable_error;
+ goto not_callable;
}
- break;
}
- DUK_ASSERT((DUK_TVAL_IS_OBJECT(tv_func) && DUK_HOBJECT_IS_CALLABLE(DUK_TVAL_GET_OBJECT(tv_func))) ||
- DUK_TVAL_IS_LIGHTFUNC(tv_func));
- DUK_ASSERT(func == NULL || !DUK_HOBJECT_HAS_BOUNDFUNC(func));
- DUK_ASSERT(func == NULL || (DUK_HOBJECT_IS_COMPFUNC(func) ||
- DUK_HOBJECT_IS_NATFUNC(func)));
-
- *out_tv_func = tv_func;
- return func;
-
- not_callable_error:
- DUK_ASSERT(tv_func != NULL);
-#if defined(DUK_USE_PARANOID_ERRORS)
- DUK_ERROR_TYPE(thr, DUK_STR_NOT_CALLABLE);
-#else
- DUK_ERROR_FMT1(thr, DUK_ERR_TYPE_ERROR, "%s not callable", duk_push_string_tval_readable(ctx, tv_func));
-#endif
- DUK_UNREACHABLE();
- return NULL; /* never executed */
-}
-
-/*
- * Value stack resize and stack top adjustment helper.
- *
- * XXX: This should all be merged to duk_valstack_resize_raw().
- */
+ DUK_ASSERT(func != NULL);
-DUK_LOCAL void duk__adjust_valstack_and_top(duk_hthread *thr,
- duk_idx_t num_stack_args,
- duk_idx_t idx_args,
- duk_idx_t nregs,
- duk_idx_t nargs,
- duk_hobject *func) {
- duk_context *ctx = (duk_context *) thr;
- duk_size_t vs_min_size;
- duk_bool_t adjusted_top = 0;
-
- vs_min_size = (thr->valstack_bottom - thr->valstack) + /* bottom of current func */
- idx_args; /* bottom of new func */
-
- if (nregs >= 0) {
- DUK_ASSERT(nargs >= 0);
- DUK_ASSERT(nregs >= nargs);
- vs_min_size += nregs;
- } else {
- /* 'func' wants stack "as is" */
- vs_min_size += num_stack_args; /* num entries of new func at entry */
+ if (!DUK_HOBJECT_HAS_STRICT(func)) {
+ /* Non-strict target needs 'this' coercion.
+ * This has potential side effects invalidating
+ * 'tv_func'.
+ */
+ duk__coerce_nonstrict_this_binding(thr, idx_func + 1);
}
- if (func == NULL || DUK_HOBJECT_IS_NATFUNC(func)) {
- vs_min_size += DUK_VALSTACK_API_ENTRY_MINIMUM; /* Duktape/C API guaranteed entries (on top of args) */
+ if (*call_flags & DUK_CALL_FLAG_CONSTRUCT) {
+ if (!(*call_flags & DUK_CALL_FLAG_DEFAULT_INSTANCE_UPDATED)) {
+ *call_flags |= DUK_CALL_FLAG_DEFAULT_INSTANCE_UPDATED;
+ duk__update_default_instance_proto(thr, idx_func);
+ }
}
- vs_min_size += DUK_VALSTACK_INTERNAL_EXTRA; /* + spare */
- /* XXX: We can't resize the value stack to a size smaller than the
- * current top, so the order of the resize and adjusting the stack
- * top depends on the current vs. final size of the value stack.
- * The operations could be combined to avoid this, but the proper
- * fix is to only grow the value stack on a function call, and only
- * shrink it (without throwing if the shrink fails) on function
- * return.
- */
+ finished:
- if (vs_min_size < (duk_size_t) (thr->valstack_top - thr->valstack)) {
- DUK_DDD(DUK_DDDPRINT(("final size smaller, set top before resize")));
+#if defined(DUK_USE_ASSERTIONS)
+ {
+ duk_tval *tv_tmp;
- DUK_ASSERT(nregs >= 0); /* can't happen when keeping current stack size */
- duk_set_top(ctx, idx_args + nargs); /* clamp anything above nargs */
- duk_set_top(ctx, idx_args + nregs); /* extend with undefined */
- adjusted_top = 1;
+ tv_tmp = duk_get_tval(thr, idx_func);
+ DUK_ASSERT(tv_tmp != NULL);
+
+ DUK_ASSERT((DUK_TVAL_IS_OBJECT(tv_tmp) && DUK_HOBJECT_IS_CALLABLE(DUK_TVAL_GET_OBJECT(tv_tmp))) ||
+ DUK_TVAL_IS_LIGHTFUNC(tv_tmp));
+ DUK_ASSERT(func == NULL || !DUK_HOBJECT_HAS_BOUNDFUNC(func));
+ DUK_ASSERT(func == NULL || (DUK_HOBJECT_IS_COMPFUNC(func) ||
+ DUK_HOBJECT_IS_NATFUNC(func)));
+ DUK_ASSERT(func == NULL || (DUK_HOBJECT_HAS_CONSTRUCTABLE(func) ||
+ (*call_flags & DUK_CALL_FLAG_CONSTRUCT) == 0));
}
+#endif
- (void) duk_valstack_resize_raw((duk_context *) thr,
- vs_min_size,
- DUK_VSRESIZE_FLAG_SHRINK | /* flags */
- 0 /* no compact */ |
- DUK_VSRESIZE_FLAG_THROW);
+ return func;
- if (!adjusted_top) {
- if (nregs >= 0) {
- DUK_ASSERT(nregs >= nargs);
- duk_set_top(ctx, idx_args + nargs); /* clamp anything above nargs */
- duk_set_top(ctx, idx_args + nregs); /* extend with undefined */
+ not_callable:
+ DUK_ASSERT(tv_func != NULL);
+
+#if defined(DUK_USE_VERBOSE_ERRORS)
+ /* GETPROPC delayed error handling: when target is not callable,
+ * GETPROPC replaces idx_func+0 with an Error (non-callable) with
+ * a hidden Symbol to signify it's to be thrown as is here. The
+ * hidden Symbol is only checked as an own property, not inherited
+ * (which would be dangerous).
+ */
+ if (DUK_TVAL_IS_OBJECT(tv_func)) {
+ if (duk_hobject_find_existing_entry_tval_ptr(thr->heap, DUK_TVAL_GET_OBJECT(tv_func), DUK_HTHREAD_STRING_INT_TARGET(thr)) != NULL) {
+ duk_push_tval(thr, tv_func);
+ (void) duk_throw(thr);
}
}
+#endif
+
+#if defined(DUK_USE_VERBOSE_ERRORS)
+#if defined(DUK_USE_PARANOID_ERRORS)
+ DUK_ERROR_FMT1(thr, DUK_ERR_TYPE_ERROR, "%s not callable", duk_get_type_name(thr, idx_func));
+#else
+ DUK_ERROR_FMT1(thr, DUK_ERR_TYPE_ERROR, "%s not callable", duk_push_string_tval_readable(thr, tv_func));
+#endif
+#else
+ DUK_ERROR_TYPE(thr, DUK_STR_NOT_CALLABLE);
+#endif
+ DUK_UNREACHABLE();
+ return NULL; /* never executed */
+
+ not_constructable:
+ /* For now GETPROPC delayed error not needed for constructor calls. */
+#if defined(DUK_USE_VERBOSE_ERRORS)
+#if defined(DUK_USE_PARANOID_ERRORS)
+ DUK_ERROR_FMT1(thr, DUK_ERR_TYPE_ERROR, "%s not constructable", duk_get_type_name(thr, idx_func));
+#else
+ DUK_ERROR_FMT1(thr, DUK_ERR_TYPE_ERROR, "%s not constructable", duk_push_string_tval_readable(thr, tv_func));
+#endif
+#else
+ DUK_ERROR_TYPE(thr, DUK_STR_NOT_CONSTRUCTABLE);
+#endif
+ DUK_UNREACHABLE();
+ return NULL; /* never executed */
}
/*
@@ -60426,7 +62328,6 @@ DUK_LOCAL void duk__adjust_valstack_and_top(duk_hthread *thr,
*/
DUK_LOCAL void duk__safe_call_adjust_valstack(duk_hthread *thr, duk_idx_t idx_retbase, duk_idx_t num_stack_rets, duk_idx_t num_actual_rets) {
- duk_context *ctx = (duk_context *) thr;
duk_idx_t idx_rcbase;
DUK_ASSERT(thr != NULL);
@@ -60434,540 +62335,395 @@ DUK_LOCAL void duk__safe_call_adjust_valstack(duk_hthread *thr, duk_idx_t idx_re
DUK_ASSERT(num_stack_rets >= 0);
DUK_ASSERT(num_actual_rets >= 0);
- idx_rcbase = duk_get_top(ctx) - num_actual_rets; /* base of known return values */
+ idx_rcbase = duk_get_top(thr) - num_actual_rets; /* base of known return values */
+ if (DUK_UNLIKELY(idx_rcbase < 0)) {
+ DUK_ERROR_TYPE(thr, DUK_STR_INVALID_CFUNC_RC);
+ }
DUK_DDD(DUK_DDDPRINT("adjust valstack after func call: "
"num_stack_rets=%ld, num_actual_rets=%ld, stack_top=%ld, idx_retbase=%ld, idx_rcbase=%ld",
- (long) num_stack_rets, (long) num_actual_rets, (long) duk_get_top(ctx),
+ (long) num_stack_rets, (long) num_actual_rets, (long) duk_get_top(thr),
(long) idx_retbase, (long) idx_rcbase));
DUK_ASSERT(idx_rcbase >= 0); /* caller must check */
- /* Ensure space for final configuration (idx_retbase + num_stack_rets)
- * and intermediate configurations.
+ /* Space for num_stack_rets was reserved before the safe call.
+ * Because value stack reserve cannot shrink except in call returns,
+ * the reserve is still in place. Adjust valstack, carefully
+ * ensuring we don't overstep the reserve.
*/
- duk_require_stack_top(ctx,
- (idx_rcbase > idx_retbase ? idx_rcbase : idx_retbase) +
- num_stack_rets);
- /* Chop extra retvals away / extend with undefined. */
- duk_set_top(ctx, idx_rcbase + num_stack_rets);
-
- if (idx_rcbase >= idx_retbase) {
+ /* Match idx_rcbase with idx_retbase so that the return values
+ * start at the correct index.
+ */
+ if (idx_rcbase > idx_retbase) {
duk_idx_t count = idx_rcbase - idx_retbase;
- duk_idx_t i;
DUK_DDD(DUK_DDDPRINT("elements at/after idx_retbase have enough to cover func retvals "
"(idx_retbase=%ld, idx_rcbase=%ld)", (long) idx_retbase, (long) idx_rcbase));
- /* nuke values at idx_retbase to get the first retval (initially
- * at idx_rcbase) to idx_retbase
+ /* Remove values between irc_rcbase (start of intended return
+ * values) and idx_retbase to lower return values to idx_retbase.
*/
-
- DUK_ASSERT(count >= 0);
-
- for (i = 0; i < count; i++) {
- /* XXX: inefficient; block remove primitive */
- duk_remove(ctx, idx_retbase);
- }
+ DUK_ASSERT(count > 0);
+ duk_remove_n(thr, idx_retbase, count); /* may be NORZ */
} else {
duk_idx_t count = idx_retbase - idx_rcbase;
- duk_idx_t i;
DUK_DDD(DUK_DDDPRINT("not enough elements at/after idx_retbase to cover func retvals "
"(idx_retbase=%ld, idx_rcbase=%ld)", (long) idx_retbase, (long) idx_rcbase));
- /* insert 'undefined' values at idx_rcbase to get the
- * return values to idx_retbase
+ /* Insert 'undefined' at idx_rcbase (start of intended return
+ * values) to lift return values to idx_retbase.
*/
-
- DUK_ASSERT(count > 0);
-
- for (i = 0; i < count; i++) {
- /* XXX: inefficient; block insert primitive */
- duk_push_undefined(ctx);
- duk_insert(ctx, idx_rcbase);
- }
+ DUK_ASSERT(count >= 0);
+ DUK_ASSERT(thr->valstack_end - thr->valstack_top >= count); /* reserve cannot shrink */
+ duk_insert_undefined_n(thr, idx_rcbase, count);
}
-}
-
-/*
- * Misc shared helpers.
- */
-
-/* Get valstack index for the func argument or throw if insane stack. */
-DUK_LOCAL duk_idx_t duk__get_idx_func(duk_hthread *thr, duk_idx_t num_stack_args) {
- duk_size_t off_stack_top;
- duk_size_t off_stack_args;
- duk_size_t off_stack_all;
- duk_idx_t idx_func; /* valstack index of 'func' and retval (relative to entry valstack_bottom) */
- /* Argument validation and func/args offset. */
- off_stack_top = (duk_size_t) ((duk_uint8_t *) thr->valstack_top - (duk_uint8_t *) thr->valstack_bottom);
- off_stack_args = (duk_size_t) ((duk_size_t) num_stack_args * sizeof(duk_tval));
- off_stack_all = off_stack_args + 2 * sizeof(duk_tval);
- if (DUK_UNLIKELY(off_stack_all > off_stack_top)) {
- /* Since stack indices are not reliable, we can't do anything useful
- * here. Invoke the existing setjmp catcher, or if it doesn't exist,
- * call the fatal error handler.
- */
- DUK_ERROR_TYPE_INVALID_ARGS(thr);
- return 0;
- }
- idx_func = (duk_idx_t) ((off_stack_top - off_stack_all) / sizeof(duk_tval));
- return idx_func;
+ /* Chop extra retvals away / extend with undefined. */
+ duk_set_top_unsafe(thr, idx_retbase + num_stack_rets);
}
/*
- * duk_handle_call_protected() and duk_handle_call_unprotected():
- * call into a Duktape/C or an Ecmascript function from any state.
- *
- * Input stack (thr):
- *
- * [ func this arg1 ... argN ]
- *
- * Output stack (thr):
- *
- * [ retval ] (DUK_EXEC_SUCCESS)
- * [ errobj ] (DUK_EXEC_ERROR (normal error), protected call)
- *
- * Even when executing a protected call an error may be thrown in rare cases
- * such as an insane num_stack_args argument. If there is no catchpoint for
- * such errors, the fatal error handler is called.
- *
- * The error handling path should be error free, even for out-of-memory
- * errors, to ensure safe sandboxing. (As of Duktape 1.4.0 this is not
- * yet the case, see XXX notes below.)
+ * Activation setup for tailcalls and non-tailcalls.
*/
-DUK_INTERNAL duk_int_t duk_handle_call_protected(duk_hthread *thr,
- duk_idx_t num_stack_args,
- duk_small_uint_t call_flags) {
- duk_context *ctx;
- duk_size_t entry_valstack_bottom_index;
- duk_size_t entry_valstack_end;
- duk_size_t entry_callstack_top;
- duk_size_t entry_catchstack_top;
- 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_idx_t idx_func; /* valstack index of 'func' and retval (relative to entry valstack_bottom) */
+#if defined(DUK_USE_TAILCALL)
+DUK_LOCAL duk_small_uint_t duk__call_setup_act_attempt_tailcall(duk_hthread *thr,
+ duk_small_uint_t call_flags,
+ duk_idx_t idx_func,
+ duk_hobject *func,
+ duk_size_t entry_valstack_bottom_byteoff,
+ duk_size_t entry_valstack_end_byteoff,
+ duk_idx_t *out_nargs,
+ duk_idx_t *out_nregs,
+ duk_size_t *out_vs_min_bytes,
+ duk_activation **out_act) {
+ duk_activation *act;
+ duk_tval *tv1, *tv2;
+ duk_idx_t idx_args;
+ duk_small_uint_t flags1, flags2;
+#if defined(DUK_USE_DEBUGGER_SUPPORT)
+ duk_activation *prev_pause_act;
+#endif
- /* 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
- * pointer quickly as valstack + offset instead of calling duk_get_tval().
- */
+ DUK_UNREF(entry_valstack_end_byteoff);
- ctx = (duk_context *) thr;
- DUK_UNREF(ctx);
- DUK_ASSERT(thr != NULL);
- DUK_ASSERT_CTX_VALID(ctx);
- DUK_ASSERT(num_stack_args >= 0);
- /* XXX: currently NULL allocations are not supported; remove if later allowed */
- DUK_ASSERT(thr->valstack != NULL);
- DUK_ASSERT(thr->callstack != NULL);
- DUK_ASSERT(thr->catchstack != NULL);
+ /* Tailcall cannot be flagged to resume calls, and a
+ * previous frame must exist.
+ */
+ DUK_ASSERT(thr->callstack_top >= 1);
- /* Argument validation and func/args offset. */
- idx_func = duk__get_idx_func(thr, num_stack_args);
+ act = thr->callstack_curr;
+ DUK_ASSERT(act != NULL);
+ *out_act = act;
- /* Preliminaries, required by setjmp() handler. Must be careful not
- * to throw an unintended error here.
+ if (func == NULL || !DUK_HOBJECT_IS_COMPFUNC(func)) {
+ DUK_DDD(DUK_DDDPRINT("tail call prevented by target not being ecma function"));
+ return 0;
+ }
+ if (act->flags & DUK_ACT_FLAG_PREVENT_YIELD) {
+ DUK_DDD(DUK_DDDPRINT("tail call prevented by current activation having DUK_ACT_FLAG_PREVENT_YIELD"));
+ return 0;
+ }
+ /* Tailcall is only allowed if current and candidate
+ * function have identical return value handling. There
+ * are three possible return value handling cases:
+ * 1. Normal function call, no special return value handling.
+ * 2. Constructor call, return value replacement object check.
+ * 3. Proxy 'construct' trap call, return value invariant check.
*/
-
- 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;
+ flags1 = (duk_small_uint_t) ((act->flags & DUK_ACT_FLAG_CONSTRUCT) ? 1 : 0)
+#if defined(DUK_USE_ES6_PROXY)
+ | (duk_small_uint_t) ((act->flags & DUK_ACT_FLAG_CONSTRUCT_PROXY) ? 2 : 0)
#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 */
+ ;
+ flags2 = (duk_small_uint_t) ((call_flags & DUK_CALL_FLAG_CONSTRUCT) ? 1 : 0)
+#if defined(DUK_USE_ES6_PROXY)
+ | (duk_small_uint_t) ((call_flags & DUK_CALL_FLAG_CONSTRUCT_PROXY) ? 2 : 0);
+#endif
+ ;
+ if (flags1 != flags2) {
+ DUK_DDD(DUK_DDDPRINT("tail call prevented by incompatible return value handling"));
+ return 0;
+ }
+ DUK_ASSERT(((act->flags & DUK_ACT_FLAG_CONSTRUCT) && (call_flags & DUK_CALL_FLAG_CONSTRUCT)) ||
+ (!(act->flags & DUK_ACT_FLAG_CONSTRUCT) && !(call_flags & DUK_CALL_FLAG_CONSTRUCT)));
+ DUK_ASSERT(((act->flags & DUK_ACT_FLAG_CONSTRUCT_PROXY) && (call_flags & DUK_CALL_FLAG_CONSTRUCT_PROXY)) ||
+ (!(act->flags & DUK_ACT_FLAG_CONSTRUCT_PROXY) && !(call_flags & DUK_CALL_FLAG_CONSTRUCT_PROXY)));
+ if (DUK_HOBJECT_HAS_NOTAIL(func)) {
+ /* See: test-bug-tailcall-preventyield-assert.c. */
+ DUK_DDD(DUK_DDDPRINT("tail call prevented by function having a notail flag"));
+ return 0;
+ }
- DUK_DD(DUK_DDPRINT("duk_handle_call_protected: thr=%p, num_stack_args=%ld, "
- "call_flags=0x%08lx (ignorerec=%ld, constructor=%ld), "
- "valstack_top=%ld, idx_func=%ld, idx_args=%ld, rec_depth=%ld/%ld, "
- "entry_valstack_bottom_index=%ld, entry_callstack_top=%ld, entry_catchstack_top=%ld, "
- "entry_call_recursion_depth=%ld, entry_curr_thread=%p, entry_thread_state=%ld",
- (void *) thr,
- (long) num_stack_args,
- (unsigned long) call_flags,
- (long) ((call_flags & DUK_CALL_FLAG_IGNORE_RECLIMIT) != 0 ? 1 : 0),
- (long) ((call_flags & DUK_CALL_FLAG_CONSTRUCTOR_CALL) != 0 ? 1 : 0),
- (long) duk_get_top(ctx),
- (long) idx_func,
- (long) (idx_func + 2),
- (long) thr->heap->call_recursion_depth,
- (long) thr->heap->call_recursion_limit,
- (long) entry_valstack_bottom_index,
- (long) entry_callstack_top,
- (long) entry_catchstack_top,
- (long) entry_call_recursion_depth,
- (void *) entry_curr_thread,
- (long) entry_thread_state));
+ /*
+ * Tailcall handling
+ *
+ * Although the callstack entry is reused, we need to explicitly unwind
+ * 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 catchers need to be unwound
+ * because there may be non-error-catching label entries in valid tail calls.
+ *
+ * Special attention is needed for debugger and pause behavior when
+ * reusing an activation.
+ * - Disable StepOut processing for the activation unwind because
+ * we reuse the activation, see:
+ * https://github.com/svaarala/duktape/issues/1684.
+ * - Disable line change pause flag permanently (if set) because
+ * it would no longer be relevant, see:
+ * https://github.com/svaarala/duktape/issues/1726.
+ * - Check for function entry (e.g. StepInto) pause flag here, because
+ * the executor pause check won't trigger due to shared activation, see:
+ * https://github.com/svaarala/duktape/issues/1726.
+ */
+
+ DUK_DDD(DUK_DDDPRINT("is tail call, reusing activation at callstack top, at index %ld",
+ (long) (thr->callstack_top - 1)));
- old_jmpbuf_ptr = thr->heap->lj.jmpbuf_ptr;
- thr->heap->lj.jmpbuf_ptr = &our_jmpbuf;
+ DUK_ASSERT(!DUK_HOBJECT_HAS_BOUNDFUNC(func));
+ DUK_ASSERT(!DUK_HOBJECT_HAS_NATFUNC(func));
+ DUK_ASSERT(DUK_HOBJECT_HAS_COMPFUNC(func));
+ DUK_ASSERT((act->flags & DUK_ACT_FLAG_PREVENT_YIELD) == 0);
+ DUK_ASSERT(call_flags & DUK_CALL_FLAG_ALLOW_ECMATOECMA);
-#if defined(DUK_USE_CPP_EXCEPTIONS)
- try {
-#else
- DUK_ASSERT(thr->heap->lj.jmpbuf_ptr == &our_jmpbuf);
- if (DUK_SETJMP(our_jmpbuf.jb) == 0) {
+ /* Unwind the topmost callstack entry before reusing it. This
+ * also unwinds the catchers related to the topmost entry.
+ */
+ DUK_ASSERT(thr->callstack_top > 0);
+ DUK_ASSERT(thr->callstack_curr != NULL);
+#if defined(DUK_USE_DEBUGGER_SUPPORT)
+ prev_pause_act = thr->heap->dbg_pause_act;
+ thr->heap->dbg_pause_act = NULL;
+ thr->heap->dbg_pause_flags &= ~DUK_PAUSE_FLAG_LINE_CHANGE;
+ if (thr->heap->dbg_pause_flags & DUK_PAUSE_FLAG_FUNC_ENTRY) {
+ DUK_D(DUK_DPRINT("PAUSE TRIGGERED by function entry (tailcall)"));
+ duk_debug_set_paused(thr->heap);
+ }
#endif
- /* Call handling and success path. Success path exit cleans
- * up almost all state.
- */
- duk__handle_call_inner(thr, num_stack_args, call_flags, idx_func);
+ duk_hthread_activation_unwind_reuse_norz(thr);
+#if defined(DUK_USE_DEBUGGER_SUPPORT)
+ thr->heap->dbg_pause_act = prev_pause_act;
+#endif
+ DUK_ASSERT(act == thr->callstack_curr);
- thr->heap->lj.jmpbuf_ptr = old_jmpbuf_ptr;
+ /* XXX: We could restore the caller's value stack reserve
+ * here, as if we did an actual unwind-and-call. Without
+ * the restoration, value stack reserve may remain higher
+ * than would otherwise be possible until we return to a
+ * non-tailcall.
+ */
- return DUK_EXEC_SUCCESS;
-#if defined(DUK_USE_CPP_EXCEPTIONS)
- } catch (duk_internal_exception &exc) {
-#else
- } else {
+ /* Then reuse the unwound activation. */
+ act->cat = NULL;
+ act->var_env = NULL;
+ act->lex_env = NULL;
+ DUK_ASSERT(func != NULL);
+ DUK_ASSERT(DUK_HOBJECT_HAS_COMPFUNC(func));
+ act->func = func; /* don't want an intermediate exposed state with func == NULL */
+#if defined(DUK_USE_NONSTD_FUNC_CALLER_PROPERTY)
+ act->prev_caller = NULL;
#endif
- /* Error; error value is in heap->lj.value1. */
-
-#if defined(DUK_USE_CPP_EXCEPTIONS)
- DUK_UNREF(exc);
+ /* don't want an intermediate exposed state with invalid pc */
+ act->curr_pc = DUK_HCOMPFUNC_GET_CODE_BASE(thr->heap, (duk_hcompfunc *) func);
+#if defined(DUK_USE_DEBUGGER_SUPPORT)
+ act->prev_line = 0;
#endif
+ DUK_TVAL_SET_OBJECT(&act->tv_func, func); /* borrowed, no refcount */
+ DUK_HOBJECT_INCREF(thr, func);
- duk__handle_call_error(thr,
- entry_valstack_bottom_index,
- entry_valstack_end,
- entry_catchstack_top,
- entry_callstack_top,
- entry_call_recursion_depth,
- entry_curr_thread,
- entry_thread_state,
- entry_ptr_curr_pc,
- idx_func,
- old_jmpbuf_ptr);
-
- return DUK_EXEC_ERROR;
+ act->flags = DUK_ACT_FLAG_TAILCALLED;
+ if (DUK_HOBJECT_HAS_STRICT(func)) {
+ act->flags |= DUK_ACT_FLAG_STRICT;
}
-#if defined(DUK_USE_CPP_EXCEPTIONS)
- catch (std::exception &exc) {
- const char *what = exc.what();
- if (!what) {
- what = "unknown";
- }
- DUK_D(DUK_DPRINT("unexpected c++ std::exception (perhaps thrown by user code)"));
- try {
- DUK_ERROR_FMT1(thr, DUK_ERR_TYPE_ERROR, "caught invalid c++ std::exception '%s' (perhaps thrown by user code)", what);
- } catch (duk_internal_exception exc) {
- DUK_D(DUK_DPRINT("caught api error thrown from unexpected c++ std::exception"));
- DUK_UNREF(exc);
- duk__handle_call_error(thr,
- entry_valstack_bottom_index,
- entry_valstack_end,
- entry_catchstack_top,
- entry_callstack_top,
- entry_call_recursion_depth,
- entry_curr_thread,
- entry_thread_state,
- entry_ptr_curr_pc,
- idx_func,
- old_jmpbuf_ptr);
-
- return DUK_EXEC_ERROR;
- }
- } catch (...) {
- DUK_D(DUK_DPRINT("unexpected c++ exception (perhaps thrown by user code)"));
- try {
- DUK_ERROR_TYPE(thr, "caught invalid c++ exception (perhaps thrown by user code)");
- } catch (duk_internal_exception exc) {
- DUK_D(DUK_DPRINT("caught api error thrown from unexpected c++ exception"));
- DUK_UNREF(exc);
- duk__handle_call_error(thr,
- entry_valstack_bottom_index,
- entry_valstack_end,
- entry_catchstack_top,
- entry_callstack_top,
- entry_call_recursion_depth,
- entry_curr_thread,
- entry_thread_state,
- entry_ptr_curr_pc,
- idx_func,
- old_jmpbuf_ptr);
-
- return DUK_EXEC_ERROR;
- }
+ if (call_flags & DUK_CALL_FLAG_CONSTRUCT) {
+ act->flags |= DUK_ACT_FLAG_CONSTRUCT;
+ }
+#if defined(DUK_USE_ES6_PROXY)
+ if (call_flags & DUK_CALL_FLAG_CONSTRUCT_PROXY) {
+ act->flags |= DUK_ACT_FLAG_CONSTRUCT_PROXY;
}
#endif
-}
-
-DUK_INTERNAL void duk_handle_call_unprotected(duk_hthread *thr,
- duk_idx_t num_stack_args,
- duk_small_uint_t call_flags) {
- duk_idx_t idx_func; /* valstack index of 'func' and retval (relative to entry valstack_bottom) */
-
- /* Argument validation and func/args offset. */
- idx_func = duk__get_idx_func(thr, num_stack_args);
-
- duk__handle_call_inner(thr, num_stack_args, call_flags, idx_func);
-}
-
-DUK_LOCAL void duk__handle_call_inner(duk_hthread *thr,
- duk_idx_t num_stack_args,
- duk_small_uint_t call_flags,
- duk_idx_t idx_func) {
- duk_context *ctx;
- duk_size_t entry_valstack_bottom_index;
- duk_size_t entry_valstack_end;
- duk_size_t entry_callstack_top;
- duk_size_t entry_catchstack_top;
- 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_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") */
- duk_hobject *func; /* 'func' on stack (borrowed reference) */
- duk_tval *tv_func; /* duk_tval ptr for 'func' on stack (borrowed reference) or tv_func_copy */
- duk_tval tv_func_copy; /* to avoid relookups */
- duk_activation *act;
- duk_hobject *env;
- duk_ret_t rc;
-
- ctx = (duk_context *) thr;
- DUK_ASSERT(thr != NULL);
- DUK_ASSERT_CTX_VALID(ctx);
- DUK_ASSERT(ctx != NULL);
- DUK_ASSERT(num_stack_args >= 0);
- /* XXX: currently NULL allocations are not supported; remove if later allowed */
- DUK_ASSERT(thr->valstack != NULL);
- DUK_ASSERT(thr->callstack != NULL);
- DUK_ASSERT(thr->catchstack != NULL);
-
- DUK_DD(DUK_DDPRINT("duk__handle_call_inner: num_stack_args=%ld, call_flags=0x%08lx, top=%ld",
- (long) num_stack_args, (long) call_flags, (long) duk_get_top(ctx)));
-
- /*
- * Store entry state.
- */
- 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;
+ DUK_ASSERT(DUK_ACT_GET_FUNC(act) == func); /* already updated */
+ DUK_ASSERT(act->var_env == NULL);
+ DUK_ASSERT(act->lex_env == NULL);
+ act->bottom_byteoff = entry_valstack_bottom_byteoff; /* tail call -> reuse current "frame" */
+#if 0
+ /* Topmost activation retval_byteoff is considered garbage, no need to init. */
+ act->retval_byteoff = 0;
#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 */
-
- /* 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.
+ /* Filled in when final reserve is known, dummy value doesn't matter
+ * even in error unwind because reserve_byteoff is only used when
+ * returning to -this- activation.
*/
- duk_hthread_sync_and_null_currpc(thr);
-
- DUK_DD(DUK_DDPRINT("duk__handle_call_inner: thr=%p, num_stack_args=%ld, "
- "call_flags=0x%08lx (ignorerec=%ld, constructor=%ld), "
- "valstack_top=%ld, idx_func=%ld, idx_args=%ld, rec_depth=%ld/%ld, "
- "entry_valstack_bottom_index=%ld, entry_callstack_top=%ld, entry_catchstack_top=%ld, "
- "entry_call_recursion_depth=%ld, entry_curr_thread=%p, entry_thread_state=%ld",
- (void *) thr,
- (long) num_stack_args,
- (unsigned long) call_flags,
- (long) ((call_flags & DUK_CALL_FLAG_IGNORE_RECLIMIT) != 0 ? 1 : 0),
- (long) ((call_flags & DUK_CALL_FLAG_CONSTRUCTOR_CALL) != 0 ? 1 : 0),
- (long) duk_get_top(ctx),
- (long) idx_func,
- (long) (idx_func + 2),
- (long) thr->heap->call_recursion_depth,
- (long) thr->heap->call_recursion_limit,
- (long) entry_valstack_bottom_index,
- (long) entry_callstack_top,
- (long) entry_catchstack_top,
- (long) entry_call_recursion_depth,
- (void *) entry_curr_thread,
- (long) entry_thread_state));
-
+ act->reserve_byteoff = 0;
/*
- * Thread state check and book-keeping.
+ * Manipulate valstack so that args are on the current bottom and the
+ * previous caller's 'this' binding (which is the value preceding the
+ * current bottom) is replaced with the new 'this' binding:
+ *
+ * [ ... this_old | (crud) func this_new arg1 ... argN ]
+ * --> [ ... this_new | arg1 ... argN ]
+ *
+ * For tail calling to work properly, the valstack bottom must not grow
+ * here; otherwise crud would accumulate on the valstack.
*/
- if (thr == thr->heap->curr_thread) {
- /* same thread */
- if (thr->state != DUK_HTHREAD_STATE_RUNNING) {
- /* should actually never happen, but check anyway */
- goto thread_state_error;
- }
- } else {
- /* different thread */
- DUK_ASSERT(thr->heap->curr_thread == NULL ||
- thr->heap->curr_thread->state == DUK_HTHREAD_STATE_RUNNING);
- if (thr->state != DUK_HTHREAD_STATE_INACTIVE) {
- goto thread_state_error;
- }
- DUK_HEAP_SWITCH_THREAD(thr->heap, thr);
- thr->state = DUK_HTHREAD_STATE_RUNNING;
+ tv1 = thr->valstack_bottom - 1;
+ 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_UPDREF(thr, tv1, tv2); /* side effects */
- /* Note: multiple threads may be simultaneously in the RUNNING
- * state, but not in the same "resume chain".
- */
- }
- DUK_ASSERT(thr->heap->curr_thread == thr);
- DUK_ASSERT(thr->state == DUK_HTHREAD_STATE_RUNNING);
+ idx_args = idx_func + 2;
+ duk_remove_n(thr, 0, idx_args); /* may be NORZ */
- /*
- * C call recursion depth check, which provides a reasonable upper
- * bound on maximum C stack size (arbitrary C stack growth is only
- * possible by recursive handle_call / handle_safe_call calls).
- */
+ idx_func = 0; DUK_UNREF(idx_func); /* really 'not applicable' anymore, should not be referenced after this */
+ idx_args = 0;
- /* XXX: remove DUK_CALL_FLAG_IGNORE_RECLIMIT flag: there's now the
- * reclimit bump?
- */
+ *out_nargs = ((duk_hcompfunc *) func)->nargs;
+ *out_nregs = ((duk_hcompfunc *) func)->nregs;
+ DUK_ASSERT(*out_nregs >= 0);
+ DUK_ASSERT(*out_nregs >= *out_nargs);
+ *out_vs_min_bytes = entry_valstack_bottom_byteoff + sizeof(duk_tval) * ((duk_size_t) *out_nregs + DUK_VALSTACK_INTERNAL_EXTRA);
- DUK_ASSERT(thr->heap->call_recursion_depth >= 0);
- DUK_ASSERT(thr->heap->call_recursion_depth <= thr->heap->call_recursion_limit);
- if (call_flags & DUK_CALL_FLAG_IGNORE_RECLIMIT) {
- DUK_DD(DUK_DDPRINT("ignoring reclimit for this call (probably an errhandler call)"));
- } else {
- if (thr->heap->call_recursion_depth >= thr->heap->call_recursion_limit) {
- /* XXX: error message is a bit misleading: we reached a recursion
- * limit which is also essentially the same as a C callstack limit
- * (except perhaps with some relaxed threading assumptions).
- */
- DUK_ERROR_RANGE(thr, DUK_STR_C_CALLSTACK_LIMIT);
- }
- thr->heap->call_recursion_depth++;
- }
- /*
- * Check the function type, handle bound function chains, and prepare
- * parameters for the rest of the call handling. Also figure out the
- * effective 'this' binding, which replaces the current value at
- * idx_func + 1.
- *
- * If the target function is a 'bound' one, follow the chain of 'bound'
- * functions until a non-bound function is found. During this process,
- * bound arguments are 'prepended' to existing ones, and the "this"
- * binding is overridden. See E5 Section 15.3.4.5.1.
- *
- * Lightfunc detection happens here too. Note that lightweight functions
- * can be wrapped by (non-lightweight) bound functions so we must resolve
- * the bound function chain first.
+#if defined(DUK_USE_NONSTD_FUNC_CALLER_PROPERTY)
+#if defined(DUK_USE_TAILCALL)
+#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
+ * is in use.
*/
+ duk__update_func_caller_prop(thr, func);
+#endif
- func = duk__nonbound_func_lookup(ctx, idx_func, &num_stack_args, &tv_func, call_flags);
- DUK_TVAL_SET_TVAL(&tv_func_copy, tv_func);
- tv_func = &tv_func_copy; /* local copy to avoid relookups */
+ /* [ ... this_new | arg1 ... argN ] */
- DUK_ASSERT(func == NULL || !DUK_HOBJECT_HAS_BOUNDFUNC(func));
- DUK_ASSERT(func == NULL || (DUK_HOBJECT_IS_COMPFUNC(func) ||
- DUK_HOBJECT_IS_NATFUNC(func)));
+ return 1;
+}
+#endif /* DUK_USE_TAILCALL */
- duk__coerce_effective_this_binding(thr, func, idx_func + 1);
- DUK_DDD(DUK_DDDPRINT("effective 'this' binding is: %!T",
- (duk_tval *) duk_get_tval(ctx, idx_func + 1)));
+DUK_LOCAL void duk__call_setup_act_not_tailcall(duk_hthread *thr,
+ duk_small_uint_t call_flags,
+ duk_idx_t idx_func,
+ duk_hobject *func,
+ duk_size_t entry_valstack_bottom_byteoff,
+ duk_size_t entry_valstack_end_byteoff,
+ duk_idx_t *out_nargs,
+ duk_idx_t *out_nregs,
+ duk_size_t *out_vs_min_bytes,
+ duk_activation **out_act) {
+ duk_activation *act;
+ duk_activation *new_act;
- /* [ ... func this arg1 ... argN ] */
+ DUK_UNREF(entry_valstack_end_byteoff);
- /*
- * Setup a preliminary activation and figure out nargs/nregs.
- *
- * Don't touch valstack_bottom or valstack_top yet so that Duktape API
- * calls work normally.
- */
+ 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);
+ duk__call_callstack_limit_check(thr);
+ new_act = duk_hthread_activation_alloc(thr);
+ DUK_ASSERT(new_act != NULL);
act = thr->callstack_curr;
if (act != NULL) {
/*
- * Update idx_retval of current activation.
+ * Update return value stack index of current activation (if any).
*
* Although it might seem this is not necessary (bytecode executor
* does this for Ecmascript-to-Ecmascript calls; other calls are
* handled here), this turns out to be necessary for handling yield
* and resume. For them, an Ecmascript-to-native call happens, and
- * the Ecmascript call's idx_retval must be set for things to work.
+ * the Ecmascript call's retval_byteoff must be set for things to work.
*/
- act->idx_retval = entry_valstack_bottom_index + idx_func;
+ act->retval_byteoff = entry_valstack_bottom_byteoff + (duk_size_t) idx_func * sizeof(duk_tval);
}
- DUK_ASSERT(thr->callstack_top < thr->callstack_size);
- act = thr->callstack + thr->callstack_top;
+ new_act->parent = act;
+ thr->callstack_curr = new_act;
thr->callstack_top++;
- thr->callstack_curr = act;
- DUK_ASSERT(thr->callstack_top <= thr->callstack_size);
+ act = new_act;
+ *out_act = act;
+
DUK_ASSERT(thr->valstack_top > thr->valstack_bottom); /* at least effective 'this' */
DUK_ASSERT(func == NULL || !DUK_HOBJECT_HAS_BOUNDFUNC(func));
- act->flags = 0;
+ act->cat = NULL;
- /* For now all calls except Ecma-to-Ecma calls prevent a yield. */
- act->flags |= DUK_ACT_FLAG_PREVENT_YIELD;
- if (call_flags & DUK_CALL_FLAG_CONSTRUCTOR_CALL) {
+ act->flags = 0;
+ if (call_flags & DUK_CALL_FLAG_CONSTRUCT) {
act->flags |= DUK_ACT_FLAG_CONSTRUCT;
}
+#if defined(DUK_USE_ES6_PROXY)
+ if (call_flags & DUK_CALL_FLAG_CONSTRUCT_PROXY) {
+ act->flags |= DUK_ACT_FLAG_CONSTRUCT_PROXY;
+ }
+#endif
if (call_flags & DUK_CALL_FLAG_DIRECT_EVAL) {
act->flags |= DUK_ACT_FLAG_DIRECT_EVAL;
}
- /* These base values are never used, but if the compiler doesn't know
- * that DUK_ERROR() won't return, these are needed to silence warnings.
- * On the other hand, scan-build will warn about the values not being
- * used, so add a DUK_UNREF.
- */
- nargs = 0; DUK_UNREF(nargs);
- nregs = 0; DUK_UNREF(nregs);
-
+ /* start of arguments: idx_func + 2. */
+ act->func = func; /* NULL for lightfunc */
if (DUK_LIKELY(func != NULL)) {
+ DUK_TVAL_SET_OBJECT(&act->tv_func, func); /* borrowed, no refcount */
if (DUK_HOBJECT_HAS_STRICT(func)) {
act->flags |= DUK_ACT_FLAG_STRICT;
}
if (DUK_HOBJECT_IS_COMPFUNC(func)) {
- nargs = ((duk_hcompfunc *) func)->nargs;
- nregs = ((duk_hcompfunc *) func)->nregs;
- DUK_ASSERT(nregs >= nargs);
+ *out_nargs = ((duk_hcompfunc *) func)->nargs;
+ *out_nregs = ((duk_hcompfunc *) func)->nregs;
+ DUK_ASSERT(*out_nregs >= 0);
+ DUK_ASSERT(*out_nregs >= *out_nargs);
+ *out_vs_min_bytes = entry_valstack_bottom_byteoff +
+ sizeof(duk_tval) * ((duk_size_t) idx_func + 2U + (duk_size_t) *out_nregs + DUK_VALSTACK_INTERNAL_EXTRA);
} else {
/* True because of call target lookup checks. */
DUK_ASSERT(DUK_HOBJECT_IS_NATFUNC(func));
- /* Note: nargs (and nregs) may be negative for a native,
- * function, which indicates that the function wants the
- * input stack "as is" (i.e. handles "vararg" arguments).
- */
- nargs = ((duk_hnatfunc *) func)->nargs;
- nregs = nargs;
+ *out_nargs = ((duk_hnatfunc *) func)->nargs;
+ *out_nregs = *out_nargs;
+ if (*out_nargs >= 0) {
+ *out_vs_min_bytes = entry_valstack_bottom_byteoff +
+ sizeof(duk_tval) * ((duk_size_t) idx_func + 2U + (duk_size_t) *out_nregs + DUK_VALSTACK_API_ENTRY_MINIMUM + DUK_VALSTACK_INTERNAL_EXTRA);
+ } else {
+ /* Vararg function. */
+ duk_size_t valstack_top_byteoff = (duk_size_t) ((duk_uint8_t *) thr->valstack_top - ((duk_uint8_t *) thr->valstack));
+ *out_vs_min_bytes = valstack_top_byteoff +
+ sizeof(duk_tval) * (DUK_VALSTACK_API_ENTRY_MINIMUM + DUK_VALSTACK_INTERNAL_EXTRA);
+ }
}
} else {
duk_small_uint_t lf_flags;
+ duk_tval *tv_func;
+
+ act->flags |= DUK_ACT_FLAG_STRICT;
+ tv_func = DUK_GET_TVAL_POSIDX(thr, idx_func);
DUK_ASSERT(DUK_TVAL_IS_LIGHTFUNC(tv_func));
+ DUK_TVAL_SET_TVAL(&act->tv_func, tv_func); /* borrowed, no refcount */
+
lf_flags = DUK_TVAL_GET_LIGHTFUNC_FLAGS(tv_func);
- nargs = DUK_LFUNC_FLAGS_GET_NARGS(lf_flags);
- if (nargs == DUK_LFUNC_NARGS_VARARGS) {
- nargs = -1; /* vararg */
+ *out_nargs = DUK_LFUNC_FLAGS_GET_NARGS(lf_flags);
+ if (*out_nargs != DUK_LFUNC_NARGS_VARARGS) {
+ *out_vs_min_bytes = entry_valstack_bottom_byteoff +
+ sizeof(duk_tval) * ((duk_size_t) idx_func + 2U + (duk_size_t) *out_nargs + DUK_VALSTACK_API_ENTRY_MINIMUM + DUK_VALSTACK_INTERNAL_EXTRA);
+ } else {
+ duk_size_t valstack_top_byteoff = (duk_size_t) ((duk_uint8_t *) thr->valstack_top - ((duk_uint8_t *) thr->valstack));
+ *out_vs_min_bytes = valstack_top_byteoff +
+ sizeof(duk_tval) * (DUK_VALSTACK_API_ENTRY_MINIMUM + DUK_VALSTACK_INTERNAL_EXTRA);
+ *out_nargs = -1; /* vararg */
}
- nregs = nargs;
-
- act->flags |= DUK_ACT_FLAG_STRICT;
+ *out_nregs = *out_nargs;
}
- act->func = func; /* NULL for lightfunc */
act->var_env = NULL;
act->lex_env = NULL;
#if defined(DUK_USE_NONSTD_FUNC_CALLER_PROPERTY)
@@ -60977,20 +62733,15 @@ DUK_LOCAL void duk__handle_call_inner(duk_hthread *thr,
#if defined(DUK_USE_DEBUGGER_SUPPORT)
act->prev_line = 0;
#endif
- act->idx_bottom = entry_valstack_bottom_index + idx_func + 2;
-#if 0 /* topmost activation idx_retval is considered garbage, no need to init */
- act->idx_retval = 0;
+ act->bottom_byteoff = entry_valstack_bottom_byteoff + sizeof(duk_tval) * ((duk_size_t) idx_func + 2U);
+#if 0
+ act->retval_byteoff = 0; /* topmost activation retval_byteoff is considered garbage, no need to init */
#endif
- DUK_TVAL_SET_TVAL(&act->tv_func, tv_func); /* borrowed, no refcount */
-
- /* XXX: remove the preventcount and make yield walk the callstack?
- * Or perhaps just use a single flag, not a counter, faster to just
- * set and restore?
+ /* Filled in when final reserve is known, dummy value doesn't matter
+ * even in error unwind because reserve_byteoff is only used when
+ * returning to -this- activation.
*/
- if (act->flags & DUK_ACT_FLAG_PREVENT_YIELD) {
- /* duk_hthread_callstack_unwind() will decrease this on unwind */
- thr->callstack_preventcount++;
- }
+ act->reserve_byteoff = 0; /* filled in by caller */
/* XXX: Is this INCREF necessary? 'func' is always a borrowed
* reference reachable through the value stack? If changed, stack
@@ -61001,26 +62752,18 @@ DUK_LOCAL void duk__handle_call_inner(duk_hthread *thr,
#if defined(DUK_USE_NONSTD_FUNC_CALLER_PROPERTY)
if (func) {
duk__update_func_caller_prop(thr, func);
- act = thr->callstack_curr;
}
#endif
+}
- /* [ ... func this arg1 ... argN ] */
+/*
+ * Environment setup.
+ */
- /*
- * Environment record creation and 'arguments' object creation.
- * Named function expression name binding is handled by the
- * compiler; the compiled function's parent env will contain
- * the (immutable) binding already.
- *
- * This handling is now identical for C and Ecmascript functions.
- * C functions always have the 'NEWENV' flag set, so their
- * environment record initialization is delayed (which is good).
- *
- * Delayed creation (on demand) is handled in duk_js_var.c.
- */
+DUK_LOCAL void duk__call_env_setup(duk_hthread *thr, duk_hobject *func, duk_activation *act, duk_idx_t idx_args) {
+ duk_hobject *env;
- DUK_ASSERT(func == NULL || !DUK_HOBJECT_HAS_BOUNDFUNC(func)); /* bound function chain has already been resolved */
+ DUK_ASSERT(func == NULL || !DUK_HOBJECT_HAS_BOUNDFUNC(func)); /* bound function has already been resolved */
if (DUK_LIKELY(func != NULL)) {
if (DUK_LIKELY(DUK_HOBJECT_HAS_NEWENV(func))) {
@@ -61036,23 +62779,22 @@ DUK_LOCAL void duk__handle_call_inner(duk_hthread *thr,
* We need to initialize it right now.
*/
- /* third arg: absolute index (to entire valstack) of idx_bottom of new activation */
- env = duk_create_activation_environment_record(thr, func, act->idx_bottom);
+ /* third arg: absolute index (to entire valstack) of bottom_byteoff of new activation */
+ env = duk_create_activation_environment_record(thr, func, act->bottom_byteoff);
DUK_ASSERT(env != NULL);
/* [ ... func this arg1 ... argN envobj ] */
DUK_ASSERT(DUK_HOBJECT_HAS_CREATEARGS(func));
- duk__handle_createargs_for_call(thr, func, env, num_stack_args);
+ duk__handle_createargs_for_call(thr, func, env, idx_args);
/* [ ... func this arg1 ... argN envobj ] */
- act = thr->callstack_curr;
act->lex_env = env;
act->var_env = env;
DUK_HOBJECT_INCREF(thr, env);
DUK_HOBJECT_INCREF(thr, env); /* XXX: incref by count (2) directly */
- duk_pop(ctx);
+ duk_pop(thr);
}
} else {
/* Use existing env (e.g. for non-strict eval); cannot have
@@ -61062,7 +62804,6 @@ DUK_LOCAL void duk__handle_call_inner(duk_hthread *thr,
DUK_ASSERT(!DUK_HOBJECT_HAS_CREATEARGS(func));
duk__handle_oldenv_for_call(thr, func, act);
- /* No need to re-lookup 'act' at present: no side effects. */
DUK_ASSERT(act->lex_env != NULL);
DUK_ASSERT(act->var_env != NULL);
@@ -61072,51 +62813,324 @@ DUK_LOCAL void duk__handle_call_inner(duk_hthread *thr,
DUK_ASSERT(act->lex_env == NULL);
DUK_ASSERT(act->var_env == NULL);
}
+}
+
+/*
+ * Misc shared helpers.
+ */
+
+/* Check thread state, update current thread. */
+DUK_LOCAL void duk__call_thread_state_update(duk_hthread *thr) {
+ DUK_ASSERT(thr != NULL);
+
+ if (DUK_LIKELY(thr == thr->heap->curr_thread)) {
+ if (DUK_UNLIKELY(thr->state != DUK_HTHREAD_STATE_RUNNING)) {
+ /* Should actually never happen, but check anyway. */
+ goto thread_state_error;
+ }
+ } else {
+ DUK_ASSERT(thr->heap->curr_thread == NULL ||
+ thr->heap->curr_thread->state == DUK_HTHREAD_STATE_RUNNING);
+ if (DUK_UNLIKELY(thr->state != DUK_HTHREAD_STATE_INACTIVE)) {
+ goto thread_state_error;
+ }
+ DUK_HEAP_SWITCH_THREAD(thr->heap, thr);
+ thr->state = DUK_HTHREAD_STATE_RUNNING;
+
+ /* Multiple threads may be simultaneously in the RUNNING
+ * state, but not in the same "resume chain".
+ */
+ }
+ DUK_ASSERT(thr->heap->curr_thread == thr);
+ DUK_ASSERT(thr->state == DUK_HTHREAD_STATE_RUNNING);
+ return;
+
+ thread_state_error:
+ DUK_ERROR_FMT1(thr, DUK_ERR_TYPE_ERROR, "invalid thread state (%ld)", (long) thr->state);
+ DUK_UNREACHABLE();
+}
+
+/*
+ * Main unprotected call handler, handles:
+ *
+ * - All combinations of native/Ecmascript caller and native/Ecmascript
+ * target.
+ *
+ * - Optimized Ecmascript-to-Ecmascript call where call handling only
+ * sets up a new duk_activation but reuses an existing bytecode executor
+ * (the caller) without native recursion.
+ *
+ * - Tailcalls, where an activation is reused without increasing call
+ * stack (duk_activation) depth.
+ *
+ * - Setup for an initial Duktape.Thread.resume().
+ *
+ * The call handler doesn't provide any protection guarantees, protected calls
+ * must be implemented e.g. by wrapping the call in a duk_safe_call().
+ * Call setup may fail at any stage, even when the new activation is in
+ * place; the only guarantee is that the state is consistent for unwinding.
+ */
+
+DUK_LOCAL duk_int_t duk__handle_call_raw(duk_hthread *thr,
+ duk_idx_t idx_func,
+ duk_small_uint_t call_flags) {
+#if defined(DUK_USE_ASSERTIONS)
+ duk_activation *entry_act;
+ duk_size_t entry_callstack_top;
+#endif
+ duk_size_t entry_valstack_bottom_byteoff;
+ duk_size_t entry_valstack_end_byteoff;
+ 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_idx_t idx_args;
+ 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") */
+ duk_size_t vs_min_bytes; /* minimum value stack size (bytes) for handling call */
+ duk_hobject *func; /* 'func' on stack (borrowed reference) */
+ duk_activation *act;
+ duk_ret_t rc;
+ duk_small_uint_t use_tailcall;
+
+ DUK_ASSERT(thr != NULL);
+ DUK_ASSERT(thr->heap != NULL);
+ /* Asserts for heap->curr_thread omitted: it may be NULL, 'thr', or
+ * any other thread (e.g. when heap thread is used to run finalizers).
+ */
+ DUK_ASSERT_CTX_VALID(thr);
+ DUK_ASSERT(duk_is_valid_index(thr, idx_func));
+ DUK_ASSERT(idx_func >= 0);
+
+ DUK_STATS_INC(thr->heap, stats_call_all);
+
+ /* If a tail call:
+ * - an Ecmascript activation must be on top of the callstack
+ * - there cannot be any catch stack entries that would catch
+ * a return
+ */
+#if defined(DUK_USE_ASSERTIONS)
+ if (call_flags & DUK_CALL_FLAG_TAILCALL) {
+ duk_activation *tmp_act;
+ duk_catcher *tmp_cat;
+
+ DUK_ASSERT(thr->callstack_top >= 1);
+ DUK_ASSERT(DUK_ACT_GET_FUNC(thr->callstack_curr) != NULL);
+ DUK_ASSERT(DUK_HOBJECT_IS_COMPFUNC(DUK_ACT_GET_FUNC(thr->callstack_curr)));
+
+ /* No entry in the catch stack which would actually catch a
+ * throw can refer to the callstack entry being reused.
+ * There *can* be catch stack entries referring to the current
+ * callstack entry as long as they don't catch (e.g. label sites).
+ */
+
+ tmp_act = thr->callstack_curr;
+ for (tmp_cat = tmp_act->cat; tmp_cat != NULL; tmp_cat = tmp_cat->parent) {
+ DUK_ASSERT(DUK_CAT_GET_TYPE(tmp_cat) == DUK_CAT_TYPE_LABEL); /* a non-catching entry */
+ }
+ }
+#endif /* DUK_USE_ASSERTIONS */
+
+ /*
+ * Store entry state.
+ */
+
+#if defined(DUK_USE_ASSERTIONS)
+ entry_act = thr->callstack_curr;
+ entry_callstack_top = thr->callstack_top;
+#endif
+ entry_valstack_bottom_byteoff = (duk_size_t) ((duk_uint8_t *) thr->valstack_bottom - (duk_uint8_t *) thr->valstack);
+ entry_valstack_end_byteoff = (duk_size_t) ((duk_uint8_t *) thr->valstack_end - (duk_uint8_t *) thr->valstack);
+ entry_call_recursion_depth = thr->heap->call_recursion_depth;
+ entry_curr_thread = thr->heap->curr_thread; /* may be NULL if first call */
+ entry_thread_state = thr->state;
+ entry_ptr_curr_pc = thr->ptr_curr_pc; /* may be NULL */
+
+ /* 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);
+ DUK_ASSERT(thr->ptr_curr_pc == NULL);
+
+ DUK_DD(DUK_DDPRINT("duk__handle_call_raw: thr=%p, idx_func=%ld, "
+ "call_flags=0x%08lx (constructor=%ld), "
+ "valstack_top=%ld, idx_func=%ld, idx_args=%ld, rec_depth=%ld/%ld, "
+ "entry_valstack_bottom_byteoff=%ld, entry_valstack_end_byteoff=%ld, "
+ "entry_call_recursion_depth=%ld, "
+ "entry_curr_thread=%p, entry_thread_state=%ld",
+ (void *) thr,
+ (long) idx_func,
+ (unsigned long) call_flags,
+ (long) ((call_flags & DUK_CALL_FLAG_CONSTRUCT) != 0 ? 1 : 0),
+ (long) duk_get_top(thr),
+ (long) idx_func,
+ (long) (idx_func + 2),
+ (long) thr->heap->call_recursion_depth,
+ (long) thr->heap->call_recursion_limit,
+ (long) entry_valstack_bottom_byteoff,
+ (long) entry_valstack_end_byteoff,
+ (long) entry_call_recursion_depth,
+ (void *) entry_curr_thread,
+ (long) entry_thread_state));
+
+ /*
+ * Thread state check and book-keeping.
+ */
+
+ duk__call_thread_state_update(thr);
+
+ /*
+ * Resolve final target function; handle bound functions and special
+ * functions like .call() and .apply(). Also figure out the effective
+ * 'this' binding, which replaces the current value at idx_func + 1.
+ */
+
+ if (DUK_LIKELY(duk__resolve_target_fastpath_check(thr, idx_func, &func, call_flags) != 0U)) {
+ DUK_DDD(DUK_DDDPRINT("fast path target resolve"));
+ } else {
+ DUK_DDD(DUK_DDDPRINT("slow path target resolve"));
+ func = duk__resolve_target_func_and_this_binding(thr, idx_func, &call_flags);
+ }
+ DUK_ASSERT(duk_get_top(thr) - idx_func >= 2); /* at least func and this present */
+
+ DUK_ASSERT(func == NULL || !DUK_HOBJECT_HAS_BOUNDFUNC(func));
+ DUK_ASSERT(func == NULL || (DUK_HOBJECT_IS_COMPFUNC(func) ||
+ DUK_HOBJECT_IS_NATFUNC(func)));
/* [ ... func this arg1 ... argN ] */
/*
- * Setup value stack: clamp to 'nargs', fill up to 'nregs'
+ * Setup a preliminary activation and figure out nargs/nregs and
+ * value stack minimum size.
*
- * Value stack may either grow or shrink, depending on the
- * number of func registers and the number of actual arguments.
- * If nregs >= 0, func wants args clamped to 'nargs'; else it
- * wants all args (= 'num_stack_args').
+ * Don't touch valstack_bottom or valstack_top yet so that Duktape API
+ * calls work normally.
+ *
+ * Because 'act' is not zeroed, all fields must be filled in.
*/
- /* XXX: optimize value stack operation */
- /* XXX: don't want to shrink allocation here */
+#if defined(DUK_USE_TAILCALL)
+ use_tailcall = (call_flags & DUK_CALL_FLAG_TAILCALL);
+ if (use_tailcall) {
+ use_tailcall = duk__call_setup_act_attempt_tailcall(thr,
+ call_flags,
+ idx_func,
+ func,
+ entry_valstack_bottom_byteoff,
+ entry_valstack_end_byteoff,
+ &nargs,
+ &nregs,
+ &vs_min_bytes,
+ &act);
+ }
+#else
+ DUK_ASSERT((call_flags & DUK_CALL_FLAG_TAILCALL) == 0); /* compiler ensures this */
+ use_tailcall = 0;
+#endif
+
+ if (use_tailcall) {
+ idx_args = 0;
+ DUK_STATS_INC(thr->heap, stats_call_tailcall);
+ } else {
+ duk__call_setup_act_not_tailcall(thr,
+ call_flags,
+ idx_func,
+ func,
+ entry_valstack_bottom_byteoff,
+ entry_valstack_end_byteoff,
+ &nargs,
+ &nregs,
+ &vs_min_bytes,
+ &act);
+ idx_args = idx_func + 2;
+ }
+ /* After this point idx_func is no longer valid for tailcalls. */
- duk__adjust_valstack_and_top(thr,
- num_stack_args,
- idx_func + 2,
- nregs,
- nargs,
- func);
+ DUK_ASSERT(act != NULL);
+
+ /* [ ... func this arg1 ... argN ] */
/*
- * Determine call type, then finalize activation, shift to
- * new value stack bottom, and call the target.
+ * Environment record creation and 'arguments' object creation.
+ * Named function expression name binding is handled by the
+ * compiler; the compiled function's parent env will contain
+ * the (immutable) binding already.
+ *
+ * This handling is now identical for C and Ecmascript functions.
+ * C functions always have the 'NEWENV' flag set, so their
+ * environment record initialization is delayed (which is good).
+ *
+ * Delayed creation (on demand) is handled in duk_js_var.c.
+ */
+
+ duk__call_env_setup(thr, func, act, idx_args);
+
+ /* [ ... func this arg1 ... argN ] */
+
+ /*
+ * Setup value stack: clamp to 'nargs', fill up to 'nregs',
+ * ensure value stack size matches target requirements, and
+ * switch value stack bottom. Valstack top is kept.
+ *
+ * Value stack can only grow here.
+ */
+
+ duk_valstack_grow_check_throw(thr, vs_min_bytes);
+ act->reserve_byteoff = (duk_size_t) ((duk_uint8_t *) thr->valstack_end - (duk_uint8_t *) thr->valstack);
+
+ if (use_tailcall) {
+ DUK_ASSERT(nregs >= 0);
+ DUK_ASSERT(nregs >= nargs);
+ duk_set_top_and_wipe(thr, nregs, nargs);
+ } else {
+ if (nregs >= 0) {
+ DUK_ASSERT(nregs >= nargs);
+ duk_set_top_and_wipe(thr, idx_func + 2 + nregs, idx_func + 2 + nargs);
+ } else {
+ ;
+ }
+ thr->valstack_bottom = thr->valstack_bottom + idx_func + 2;
+ }
+ DUK_ASSERT(thr->valstack_bottom >= thr->valstack);
+ DUK_ASSERT(thr->valstack_top >= thr->valstack_bottom);
+ DUK_ASSERT(thr->valstack_end >= thr->valstack_top);
+
+ /*
+ * Make the actual call. For Ecma-to-Ecma calls detect that
+ * setup is complete, then return with a status code that allows
+ * the caller to reuse the running executor.
*/
- act = thr->callstack_curr;
if (func != NULL && DUK_HOBJECT_IS_COMPFUNC(func)) {
/*
- * Ecmascript call
+ * Ecmascript call.
*/
- duk_tval *tv_ret;
- duk_tval *tv_funret;
-
DUK_ASSERT(func != NULL);
DUK_ASSERT(DUK_HOBJECT_HAS_COMPFUNC(func));
act->curr_pc = DUK_HCOMPFUNC_GET_CODE_BASE(thr->heap, (duk_hcompfunc *) func);
- thr->valstack_bottom = thr->valstack_bottom + idx_func + 2;
- /* keep current valstack_top */
- DUK_ASSERT(thr->valstack_bottom >= thr->valstack);
- DUK_ASSERT(thr->valstack_top >= thr->valstack_bottom);
- DUK_ASSERT(thr->valstack_end >= thr->valstack_top);
+ if (call_flags & DUK_CALL_FLAG_ALLOW_ECMATOECMA) {
+ DUK_DD(DUK_DDPRINT("avoid native call, use existing executor"));
+ DUK_STATS_INC(thr->heap, stats_call_ecmatoecma);
+ DUK_ASSERT((act->flags & DUK_ACT_FLAG_PREVENT_YIELD) == 0);
+ DUK_REFZERO_CHECK_FAST(thr);
+ DUK_ASSERT(thr->ptr_curr_pc == NULL);
+ return 1; /* 1=reuse executor */
+ }
+ DUK_ASSERT(use_tailcall == 0);
+
+ /* duk_hthread_activation_unwind_norz() will decrease this on unwind */
+ DUK_ASSERT((act->flags & DUK_ACT_FLAG_PREVENT_YIELD) == 0);
+ act->flags |= DUK_ACT_FLAG_PREVENT_YIELD;
+ thr->callstack_preventcount++;
+
+ /* XXX: we could just do this on entry regardless of reuse, as long
+ * as recursion depth is decreased for e2e case.
+ */
+ duk__call_c_recursion_limit_check(thr);
+ thr->heap->call_recursion_depth++;
/* [ ... func this | arg1 ... argN ] ('this' must precede new bottom) */
@@ -61137,124 +63151,123 @@ DUK_LOCAL void duk__handle_call_inner(duk_hthread *thr,
DUK_DDD(DUK_DDDPRINT("entering bytecode execution"));
duk_js_execute_bytecode(thr);
DUK_DDD(DUK_DDDPRINT("returned from bytecode execution"));
-
- /* Unwind. */
-
- DUK_ASSERT(thr->catchstack_top >= entry_catchstack_top); /* may need unwind */
- DUK_ASSERT(thr->callstack_top == entry_callstack_top + 1);
- duk_hthread_catchstack_unwind_norz(thr, entry_catchstack_top);
- duk_hthread_catchstack_shrink_check(thr);
- duk_hthread_callstack_unwind_norz(thr, entry_callstack_top); /* XXX: may now fail */
- duk_hthread_callstack_shrink_check(thr);
-
- thr->valstack_bottom = thr->valstack + entry_valstack_bottom_index;
- /* keep current valstack_top */
- DUK_ASSERT(thr->valstack_bottom >= thr->valstack);
- DUK_ASSERT(thr->valstack_top >= thr->valstack_bottom);
- DUK_ASSERT(thr->valstack_end >= thr->valstack_top);
- DUK_ASSERT(thr->valstack_top - thr->valstack_bottom >= idx_func + 1);
-
- /* Return value handling. */
-
- /* [ ... func this (crud) retval ] */
-
- tv_ret = thr->valstack_bottom + idx_func;
- tv_funret = thr->valstack_top - 1;
-#if defined(DUK_USE_FASTINT)
- /* Explicit check for fastint downgrade. */
- DUK_TVAL_CHKFAST_INPLACE_FAST(tv_funret);
-#endif
- DUK_TVAL_SET_TVAL_UPDREF(thr, tv_ret, tv_funret); /* side effects */
} else {
/*
* Native call.
*/
- duk_tval *tv_ret;
- duk_tval *tv_funret;
-
- thr->valstack_bottom = thr->valstack_bottom + idx_func + 2;
- /* keep current valstack_top */
- DUK_ASSERT(thr->valstack_bottom >= thr->valstack);
- DUK_ASSERT(thr->valstack_top >= thr->valstack_bottom);
- DUK_ASSERT(thr->valstack_end >= thr->valstack_top);
DUK_ASSERT(func == NULL || ((duk_hnatfunc *) func)->func != NULL);
+ DUK_ASSERT(use_tailcall == 0);
/* [ ... func this | arg1 ... argN ] ('this' must precede new bottom) */
+ /* duk_hthread_activation_unwind_norz() will decrease this on unwind */
+ DUK_ASSERT((act->flags & DUK_ACT_FLAG_PREVENT_YIELD) == 0);
+ act->flags |= DUK_ACT_FLAG_PREVENT_YIELD;
+ thr->callstack_preventcount++;
+
+ /* XXX: we could just do this on entry regardless of reuse, as long
+ * as recursion depth is decreased for e2e case.
+ */
+ duk__call_c_recursion_limit_check(thr);
+ thr->heap->call_recursion_depth++;
+
/* For native calls must be NULL so we don't sync back */
DUK_ASSERT(thr->ptr_curr_pc == NULL);
+ /* XXX: native funcptr could come out of call setup. */
if (func) {
- rc = ((duk_hnatfunc *) func)->func((duk_context *) thr);
+ rc = ((duk_hnatfunc *) func)->func(thr);
} else {
- duk_c_function funcptr = DUK_TVAL_GET_LIGHTFUNC_FUNCPTR(tv_func);
- rc = funcptr((duk_context *) thr);
+ duk_tval *tv_func;
+ duk_c_function funcptr;
+
+ tv_func = &act->tv_func;
+ DUK_ASSERT(DUK_TVAL_IS_LIGHTFUNC(tv_func));
+ funcptr = DUK_TVAL_GET_LIGHTFUNC_FUNCPTR(tv_func);
+ rc = funcptr(thr);
}
/* Automatic error throwing, retval check. */
- if (rc < 0) {
+ if (rc == 0) {
+ DUK_ASSERT(thr->valstack < thr->valstack_end);
+ DUK_ASSERT(DUK_TVAL_IS_UNDEFINED(thr->valstack_top));
+ thr->valstack_top++;
+ } else if (rc == 1) {
+ ;
+ } else if (rc < 0) {
duk_error_throw_from_negative_rc(thr, rc);
DUK_UNREACHABLE();
- } else if (rc > 1) {
- DUK_ERROR_TYPE(thr, "c function returned invalid rc");
+ } else {
+ DUK_ERROR_TYPE(thr, DUK_STR_INVALID_CFUNC_RC);
}
- DUK_ASSERT(rc == 0 || rc == 1);
+ }
+ DUK_ASSERT(thr->ptr_curr_pc == NULL);
+ DUK_ASSERT(use_tailcall == 0);
- /* Unwind. */
+ /*
+ * Constructor call post processing.
+ */
- DUK_ASSERT(thr->catchstack_top == entry_catchstack_top); /* no need to unwind */
- DUK_ASSERT(thr->callstack_top == entry_callstack_top + 1);
- duk_hthread_callstack_unwind_norz(thr, entry_callstack_top);
- duk_hthread_callstack_shrink_check(thr);
+#if defined(DUK_USE_ES6_PROXY)
+ if (call_flags & (DUK_CALL_FLAG_CONSTRUCT | DUK_CALL_FLAG_CONSTRUCT_PROXY)) {
+ duk_call_construct_postprocess(thr, call_flags & DUK_CALL_FLAG_CONSTRUCT_PROXY);
+ }
+#else
+ if (call_flags & DUK_CALL_FLAG_CONSTRUCT) {
+ duk_call_construct_postprocess(thr, 0);
+ }
+#endif
+
+ /*
+ * Unwind, restore valstack bottom and other book-keeping.
+ */
+
+ DUK_ASSERT(thr->callstack_curr != NULL);
+ DUK_ASSERT(thr->callstack_curr->parent == entry_act);
+ DUK_ASSERT(thr->callstack_top == entry_callstack_top + 1);
+ duk_hthread_activation_unwind_norz(thr);
+ DUK_ASSERT(thr->callstack_curr == entry_act);
+ DUK_ASSERT(thr->callstack_top == entry_callstack_top);
- thr->valstack_bottom = thr->valstack + entry_valstack_bottom_index;
- /* keep current valstack_top */
- DUK_ASSERT(thr->valstack_bottom >= thr->valstack);
- DUK_ASSERT(thr->valstack_top >= thr->valstack_bottom);
- DUK_ASSERT(thr->valstack_end >= thr->valstack_top);
- DUK_ASSERT(thr->valstack_top - thr->valstack_bottom >= idx_func + 1);
+ thr->valstack_bottom = (duk_tval *) (void *) ((duk_uint8_t *) thr->valstack + entry_valstack_bottom_byteoff);
+ /* keep current valstack_top */
+ DUK_ASSERT(thr->valstack_bottom >= thr->valstack);
+ DUK_ASSERT(thr->valstack_top >= thr->valstack_bottom);
+ DUK_ASSERT(thr->valstack_end >= thr->valstack_top);
+ DUK_ASSERT(thr->valstack_top - thr->valstack_bottom >= idx_func + 1);
+
+ /* Return value handling. */
- /* Return value handling. */
+ /* [ ... func this (crud) retval ] */
+
+ {
+ duk_tval *tv_ret;
+ duk_tval *tv_funret;
- /* XXX: should this happen in the callee's activation or after unwinding? */
tv_ret = thr->valstack_bottom + idx_func;
- if (rc == 0) {
- DUK_TVAL_SET_UNDEFINED_UPDREF(thr, tv_ret); /* side effects */
- } else {
- /* [ ... func this (crud) retval ] */
- tv_funret = thr->valstack_top - 1;
+ tv_funret = thr->valstack_top - 1;
#if defined(DUK_USE_FASTINT)
- /* Explicit check for fastint downgrade. */
- DUK_TVAL_CHKFAST_INPLACE_FAST(tv_funret);
+ /* Explicit check for fastint downgrade. */
+ DUK_TVAL_CHKFAST_INPLACE_FAST(tv_funret);
#endif
- DUK_TVAL_SET_TVAL_UPDREF(thr, tv_ret, tv_funret); /* side effects */
- }
+ DUK_TVAL_SET_TVAL_UPDREF(thr, tv_ret, tv_funret); /* side effects */
}
- duk_set_top(ctx, idx_func + 1); /* XXX: unnecessary, handle in adjust */
+ duk_set_top_unsafe(thr, idx_func + 1);
/* [ ... retval ] */
- /* Ensure there is internal valstack spare before we exit; this may
- * throw an alloc error. The same guaranteed size must be available
- * as before the call. This is not optimal now: we store the valstack
- * allocated size during entry; this value may be higher than the
- * minimal guarantee for an application.
- */
+ /* Restore caller's value stack reserve (cannot fail). */
+ DUK_ASSERT((duk_uint8_t *) thr->valstack + entry_valstack_end_byteoff >= (duk_uint8_t *) thr->valstack_top);
+ DUK_ASSERT((duk_uint8_t *) thr->valstack + entry_valstack_end_byteoff <= (duk_uint8_t *) thr->valstack_alloc_end);
+ thr->valstack_end = (duk_tval *) (void *) ((duk_uint8_t *) thr->valstack + entry_valstack_end_byteoff);
- /* XXX: we should never shrink here; when we error out later, we'd
- * need to potentially grow the value stack in error unwind which could
- * cause another error.
+ /* XXX: Trial value stack shrink would be OK here, but we'd need
+ * to prevent side effects of the potential realloc.
*/
- (void) duk_valstack_resize_raw((duk_context *) thr,
- entry_valstack_end, /* same as during entry */
- DUK_VSRESIZE_FLAG_SHRINK | /* flags */
- DUK_VSRESIZE_FLAG_COMPACT |
- DUK_VSRESIZE_FLAG_THROW);
-
/* Restore entry thread executor curr_pc stack frame pointer. */
thr->ptr_curr_pc = entry_ptr_curr_pc;
@@ -61295,162 +63308,29 @@ DUK_LOCAL void duk__handle_call_inner(duk_hthread *thr,
/* Restored by success path. */
DUK_ASSERT(thr->heap->call_recursion_depth == entry_call_recursion_depth);
DUK_ASSERT(thr->ptr_curr_pc == entry_ptr_curr_pc);
-
DUK_ASSERT_LJSTATE_UNSET(thr->heap);
DUK_REFZERO_CHECK_FAST(thr);
- return;
-
- thread_state_error:
- DUK_ERROR_FMT1(thr, DUK_ERR_TYPE_ERROR, "invalid thread state for call (%ld)", (long) thr->state);
- DUK_UNREACHABLE();
- return; /* never executed */
+ return 0; /* 0=call handled inline */
}
-DUK_LOCAL void duk__handle_call_error(duk_hthread *thr,
- duk_size_t entry_valstack_bottom_index,
- duk_size_t entry_valstack_end,
- duk_size_t entry_catchstack_top,
- duk_size_t entry_callstack_top,
- 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_idx_t idx_func,
- duk_jmpbuf *old_jmpbuf_ptr) {
- duk_context *ctx;
- duk_tval *tv_ret;
-
- ctx = (duk_context *) thr;
-
- DUK_DDD(DUK_DDDPRINT("error caught during duk__handle_call_inner(): %!T",
- (duk_tval *) &thr->heap->lj.value1));
-
- /* Other longjmp types are handled by executor before propagating
- * the error here.
- */
- DUK_ASSERT(thr->heap->lj.type == DUK_LJ_TYPE_THROW);
- DUK_ASSERT_LJSTATE_SET(thr->heap);
- DUK_ASSERT(thr->callstack_top >= entry_callstack_top);
- DUK_ASSERT(thr->catchstack_top >= entry_catchstack_top);
-
- /* We don't need to sync back thr->ptr_curr_pc here because
- * the bytecode executor always has a setjmp catchpoint which
- * does that before errors propagate to here.
- */
- DUK_ASSERT(thr->ptr_curr_pc == NULL);
-
- /* Restore the previous setjmp catcher so that any error in
- * error handling will propagate outwards rather than re-enter
- * the same handler. However, the error handling path must be
- * designed to be error free so that sandboxing guarantees are
- * reliable, see e.g. https://github.com/svaarala/duktape/issues/476.
- */
- thr->heap->lj.jmpbuf_ptr = old_jmpbuf_ptr;
-
- /* XXX: callstack unwind may now throw an error when closing
- * scopes; this is a sandboxing issue, described in:
- * https://github.com/svaarala/duktape/issues/476
- */
- duk_hthread_catchstack_unwind_norz(thr, entry_catchstack_top);
- duk_hthread_catchstack_shrink_check(thr);
- duk_hthread_callstack_unwind_norz(thr, entry_callstack_top);
- duk_hthread_callstack_shrink_check(thr);
-
- thr->valstack_bottom = thr->valstack + entry_valstack_bottom_index;
- tv_ret = thr->valstack_bottom + idx_func; /* XXX: byte offset? */
- DUK_TVAL_SET_TVAL_UPDREF(thr, tv_ret, &thr->heap->lj.value1); /* side effects */
-#if defined(DUK_USE_FASTINT)
- /* Explicit check for fastint downgrade. */
- DUK_TVAL_CHKFAST_INPLACE_FAST(tv_ret);
-#endif
- duk_set_top(ctx, idx_func + 1); /* XXX: could be eliminated with valstack adjust */
-
- /* [ ... errobj ] */
-
- /* Ensure there is internal valstack spare before we exit; this may
- * throw an alloc error. The same guaranteed size must be available
- * as before the call. This is not optimal now: we store the valstack
- * allocated size during entry; this value may be higher than the
- * minimal guarantee for an application.
- */
-
- /* XXX: this needs to be reworked so that we never shrink the value
- * stack on function entry so that we never need to grow it here.
- * Needing to grow here is a sandboxing issue because we need to
- * allocate which may cause an error in the error handling path
- * and thus propagate an error out of a protected call.
- */
-
- (void) duk_valstack_resize_raw((duk_context *) thr,
- entry_valstack_end, /* same as during entry */
- DUK_VSRESIZE_FLAG_SHRINK | /* flags */
- DUK_VSRESIZE_FLAG_COMPACT |
- DUK_VSRESIZE_FLAG_THROW);
-
-
- /* These are just convenience "wiping" of state. Side effects should
- * not be an issue here: thr->heap and thr->heap->lj have a stable
- * pointer. Finalizer runs etc capture even out-of-memory errors so
- * nothing should throw here.
- */
- thr->heap->lj.type = DUK_LJ_TYPE_UNKNOWN;
- thr->heap->lj.iserror = 0;
- DUK_TVAL_SET_UNDEFINED_UPDREF(thr, &thr->heap->lj.value1); /* side effects */
- DUK_TVAL_SET_UNDEFINED_UPDREF(thr, &thr->heap->lj.value2); /* side effects */
-
- /* 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;
-
- /* Disabled assert: triggered with some torture tests. */
-#if 0
- DUK_ASSERT((thr->state == DUK_HTHREAD_STATE_INACTIVE && thr->heap->curr_thread == NULL) || /* first call */
- (thr->state == DUK_HTHREAD_STATE_INACTIVE && thr->heap->curr_thread != NULL) || /* other call */
- (thr->state == DUK_HTHREAD_STATE_RUNNING && thr->heap->curr_thread == thr)); /* current thread */
-#endif
-
- 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_debug_is_attached(thr->heap)) {
- DUK_DD(DUK_DDPRINT("returning 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
-
- /* Error handling complete, remove side effect protections and
- * process pending finalizers.
- */
-#if defined(DUK_USE_ASSERTIONS)
- DUK_ASSERT(thr->heap->error_not_allowed == 1);
- thr->heap->error_not_allowed = 0;
-#endif
- DUK_ASSERT(thr->heap->pf_prevent_count > 0);
- thr->heap->pf_prevent_count--;
- DUK_DD(DUK_DDPRINT("call error handled, pf_prevent_count updated to %ld", (long) thr->heap->pf_prevent_count));
-
- DUK_ASSERT_LJSTATE_UNSET(thr->heap);
+DUK_INTERNAL duk_int_t duk_handle_call_unprotected_nargs(duk_hthread *thr,
+ duk_idx_t nargs,
+ duk_small_uint_t call_flags) {
+ duk_idx_t idx_func;
+ DUK_ASSERT(duk_get_top(thr) >= nargs + 2);
+ idx_func = duk_get_top(thr) - (nargs + 2);
+ DUK_ASSERT(idx_func >= 0);
+ return duk_handle_call_unprotected(thr, idx_func, call_flags);
+}
- DUK_REFZERO_CHECK_SLOW(thr);
+DUK_INTERNAL duk_int_t duk_handle_call_unprotected(duk_hthread *thr,
+ duk_idx_t idx_func,
+ duk_small_uint_t call_flags) {
+ DUK_ASSERT(duk_is_valid_index(thr, idx_func));
+ DUK_ASSERT(idx_func >= 0);
+ return duk__handle_call_raw(thr, idx_func, call_flags);
}
/*
@@ -61458,247 +63338,52 @@ DUK_LOCAL void duk__handle_call_error(duk_hthread *thr,
* current activation.
*
* The allowed thread states for making a call are the same as for
- * duk_handle_call_xxx().
+ * duk_handle_call_protected().
+ *
+ * Even though this call is protected, errors are thrown for insane arguments
+ * and may result in a fatal error unless there's another protected call which
+ * catches such errors.
*
- * Error handling is similar to duk_handle_call_xxx(); errors may be thrown
- * (and result in a fatal error) for insane arguments.
+ * The error handling path should be error free, even for out-of-memory
+ * errors, to ensure safe sandboxing. (As of Duktape 2.2.0 this is not
+ * yet the case for environment closing which may run out of memory, see
+ * XXX notes below.)
*/
-/* XXX: bump preventcount by one for the duration of this call? */
-
-DUK_INTERNAL duk_int_t duk_handle_safe_call(duk_hthread *thr,
- duk_safe_call_function func,
- void *udata,
- duk_idx_t num_stack_args,
- duk_idx_t num_stack_rets) {
- duk_context *ctx = (duk_context *) thr;
- duk_size_t entry_valstack_bottom_index;
- duk_size_t entry_callstack_top;
- duk_size_t entry_catchstack_top;
- 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_idx_t idx_retbase;
- duk_int_t retval;
-
- DUK_ASSERT(thr != NULL);
- DUK_ASSERT(ctx != NULL);
-
- /* Note: careful with indices like '-x'; if 'x' is zero, it refers to bottom */
- entry_valstack_bottom_index = (duk_size_t) (thr->valstack_bottom - thr->valstack);
- 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_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! */
- DUK_DD(DUK_DDPRINT("duk_handle_safe_call: thr=%p, num_stack_args=%ld, num_stack_rets=%ld, "
- "valstack_top=%ld, idx_retbase=%ld, rec_depth=%ld/%ld, "
- "entry_valstack_bottom_index=%ld, entry_callstack_top=%ld, entry_catchstack_top=%ld, "
- "entry_call_recursion_depth=%ld, entry_curr_thread=%p, entry_thread_state=%ld",
- (void *) thr,
- (long) num_stack_args,
- (long) num_stack_rets,
- (long) duk_get_top(ctx),
- (long) idx_retbase,
- (long) thr->heap->call_recursion_depth,
- (long) thr->heap->call_recursion_limit,
- (long) entry_valstack_bottom_index,
- (long) entry_callstack_top,
- (long) entry_catchstack_top,
- (long) entry_call_recursion_depth,
- (void *) entry_curr_thread,
- (long) entry_thread_state));
-
- if (idx_retbase < 0) {
- /* Since stack indices are not reliable, we can't do anything useful
- * here. Invoke the existing setjmp catcher, or if it doesn't exist,
- * call the fatal error handler.
- */
-
- DUK_ERROR_TYPE_INVALID_ARGS(thr);
- }
-
- /* setjmp catchpoint setup */
-
- old_jmpbuf_ptr = thr->heap->lj.jmpbuf_ptr;
- thr->heap->lj.jmpbuf_ptr = &our_jmpbuf;
-
-#if defined(DUK_USE_CPP_EXCEPTIONS)
- try {
-#else
- DUK_ASSERT(thr->heap->lj.jmpbuf_ptr == &our_jmpbuf);
- if (DUK_SETJMP(our_jmpbuf.jb) == 0) {
- /* Success path. */
-#endif
- DUK_DDD(DUK_DDDPRINT("safe_call setjmp catchpoint setup complete"));
-
- duk__handle_safe_call_inner(thr,
- func,
- udata,
- idx_retbase,
- num_stack_rets,
- entry_valstack_bottom_index,
- entry_callstack_top,
- entry_catchstack_top);
-
- /* Note: either pointer may be NULL (at entry), so don't assert */
- thr->heap->lj.jmpbuf_ptr = old_jmpbuf_ptr;
-
- retval = DUK_EXEC_SUCCESS;
-#if defined(DUK_USE_CPP_EXCEPTIONS)
- } catch (duk_internal_exception &exc) {
- DUK_UNREF(exc);
-#else
- } else {
- /* Error path. */
-#endif
- duk__handle_safe_call_error(thr,
- idx_retbase,
- num_stack_rets,
- entry_valstack_bottom_index,
- entry_callstack_top,
- entry_catchstack_top,
- old_jmpbuf_ptr);
-
- retval = DUK_EXEC_ERROR;
- }
-#if defined(DUK_USE_CPP_EXCEPTIONS)
- catch (std::exception &exc) {
- const char *what = exc.what();
- if (!what) {
- what = "unknown";
- }
- DUK_D(DUK_DPRINT("unexpected c++ std::exception (perhaps thrown by user code)"));
- try {
- DUK_ERROR_FMT1(thr, DUK_ERR_TYPE_ERROR, "caught invalid c++ std::exception '%s' (perhaps thrown by user code)", what);
- } catch (duk_internal_exception exc) {
- DUK_D(DUK_DPRINT("caught api error thrown from unexpected c++ std::exception"));
- DUK_UNREF(exc);
- duk__handle_safe_call_error(thr,
- idx_retbase,
- num_stack_rets,
- entry_valstack_bottom_index,
- entry_callstack_top,
- entry_catchstack_top,
- old_jmpbuf_ptr);
- retval = DUK_EXEC_ERROR;
- }
- } catch (...) {
- DUK_D(DUK_DPRINT("unexpected c++ exception (perhaps thrown by user code)"));
- try {
- DUK_ERROR_TYPE(thr, "caught invalid c++ exception (perhaps thrown by user code)");
- } catch (duk_internal_exception exc) {
- DUK_D(DUK_DPRINT("caught api error thrown from unexpected c++ exception"));
- DUK_UNREF(exc);
- duk__handle_safe_call_error(thr,
- idx_retbase,
- num_stack_rets,
- entry_valstack_bottom_index,
- entry_callstack_top,
- entry_catchstack_top,
- old_jmpbuf_ptr);
- retval = DUK_EXEC_ERROR;
- }
- }
-#endif
-
- DUK_ASSERT(thr->heap->lj.jmpbuf_ptr == old_jmpbuf_ptr); /* success/error path both do this */
-
- DUK_ASSERT_LJSTATE_UNSET(thr->heap);
-
- duk__handle_safe_call_shared(thr,
- idx_retbase,
- num_stack_rets,
- entry_call_recursion_depth,
- entry_curr_thread,
- entry_thread_state,
- entry_ptr_curr_pc);
-
- return retval;
-}
-
DUK_LOCAL void duk__handle_safe_call_inner(duk_hthread *thr,
duk_safe_call_function func,
void *udata,
- duk_idx_t idx_retbase,
- duk_idx_t num_stack_rets,
- duk_size_t entry_valstack_bottom_index,
+#if defined(DUK_USE_ASSERTIONS)
+ duk_size_t entry_valstack_bottom_byteoff,
duk_size_t entry_callstack_top,
- duk_size_t entry_catchstack_top) {
- duk_context *ctx;
+#endif
+ duk_hthread *entry_curr_thread,
+ duk_uint_fast8_t entry_thread_state,
+ duk_idx_t idx_retbase,
+ duk_idx_t num_stack_rets) {
duk_ret_t rc;
DUK_ASSERT(thr != NULL);
- ctx = (duk_context *) thr;
- DUK_ASSERT_CTX_VALID(ctx);
- DUK_UNREF(entry_valstack_bottom_index);
- DUK_UNREF(entry_callstack_top);
- DUK_UNREF(entry_catchstack_top);
+ DUK_ASSERT_CTX_VALID(thr);
/*
* Thread state check and book-keeping.
*/
- if (thr == thr->heap->curr_thread) {
- /* same thread */
- if (thr->state != DUK_HTHREAD_STATE_RUNNING) {
- /* should actually never happen, but check anyway */
- goto thread_state_error;
- }
- } else {
- /* different thread */
- DUK_ASSERT(thr->heap->curr_thread == NULL ||
- thr->heap->curr_thread->state == DUK_HTHREAD_STATE_RUNNING);
- if (thr->state != DUK_HTHREAD_STATE_INACTIVE) {
- goto thread_state_error;
- }
- DUK_HEAP_SWITCH_THREAD(thr->heap, thr);
- thr->state = DUK_HTHREAD_STATE_RUNNING;
-
- /* Note: multiple threads may be simultaneously in the RUNNING
- * state, but not in the same "resume chain".
- */
- }
-
- DUK_ASSERT(thr->heap->curr_thread == thr);
- DUK_ASSERT(thr->state == DUK_HTHREAD_STATE_RUNNING);
+ duk__call_thread_state_update(thr);
/*
* Recursion limit check.
- *
- * Note: there is no need for an "ignore recursion limit" flag
- * for duk_handle_safe_call now.
*/
- DUK_ASSERT(thr->heap->call_recursion_depth >= 0);
- DUK_ASSERT(thr->heap->call_recursion_depth <= thr->heap->call_recursion_limit);
- if (thr->heap->call_recursion_depth >= thr->heap->call_recursion_limit) {
- /* XXX: error message is a bit misleading: we reached a recursion
- * limit which is also essentially the same as a C callstack limit
- * (except perhaps with some relaxed threading assumptions).
- */
- DUK_ERROR_RANGE(thr, DUK_STR_C_CALLSTACK_LIMIT);
- }
+ duk__call_c_recursion_limit_check(thr);
thr->heap->call_recursion_depth++;
/*
- * Valstack spare check
- */
-
- duk_require_stack(ctx, 0); /* internal spare */
-
- /*
- * Make the C call
+ * Make the C call.
*/
- rc = func(ctx, udata);
+ rc = func(thr, udata);
DUK_DDD(DUK_DDDPRINT("safe_call, func rc=%ld", (long) rc));
@@ -61708,48 +63393,35 @@ DUK_LOCAL void duk__handle_safe_call_inner(duk_hthread *thr,
/* we're running inside the caller's activation, so no change in call/catch stack or valstack bottom */
DUK_ASSERT(thr->callstack_top == entry_callstack_top);
- DUK_ASSERT(thr->catchstack_top == entry_catchstack_top);
DUK_ASSERT(thr->valstack_bottom >= thr->valstack);
- DUK_ASSERT((duk_size_t) (thr->valstack_bottom - thr->valstack) == entry_valstack_bottom_index);
+ DUK_ASSERT((duk_size_t) ((duk_uint8_t *) thr->valstack_bottom - (duk_uint8_t *) thr->valstack) == entry_valstack_bottom_byteoff);
DUK_ASSERT(thr->valstack_top >= thr->valstack_bottom);
DUK_ASSERT(thr->valstack_end >= thr->valstack_top);
- if (rc < 0) {
+ if (DUK_UNLIKELY(rc < 0)) {
duk_error_throw_from_negative_rc(thr, rc);
}
DUK_ASSERT(rc >= 0);
- if (duk_get_top(ctx) < rc) {
- DUK_ERROR_RANGE(thr, "not enough stack values for safe_call rc");
- }
-
- DUK_ASSERT(thr->catchstack_top == entry_catchstack_top); /* no need to unwind */
- DUK_ASSERT(thr->callstack_top == entry_callstack_top);
-
- duk__safe_call_adjust_valstack(thr, idx_retbase, num_stack_rets, rc);
-
- DUK_ASSERT_LJSTATE_UNSET(thr->heap);
-
- DUK_REFZERO_CHECK_FAST(thr);
- return;
+ duk__safe_call_adjust_valstack(thr, idx_retbase, num_stack_rets, rc); /* throws for insane rc */
- thread_state_error:
- DUK_ERROR_FMT1(thr, DUK_ERR_TYPE_ERROR, "invalid thread state for safe_call (%ld)", (long) thr->state);
- DUK_UNREACHABLE();
+ DUK_HEAP_SWITCH_THREAD(thr->heap, entry_curr_thread); /* may be NULL */
+ thr->state = (duk_uint8_t) entry_thread_state;
}
DUK_LOCAL void duk__handle_safe_call_error(duk_hthread *thr,
+ duk_activation *entry_act,
+#if defined(DUK_USE_ASSERTIONS)
+ duk_size_t entry_callstack_top,
+#endif
+ duk_hthread *entry_curr_thread,
+ duk_uint_fast8_t entry_thread_state,
duk_idx_t idx_retbase,
duk_idx_t num_stack_rets,
- duk_size_t entry_valstack_bottom_index,
- duk_size_t entry_callstack_top,
- duk_size_t entry_catchstack_top,
+ duk_size_t entry_valstack_bottom_byteoff,
duk_jmpbuf *old_jmpbuf_ptr) {
- duk_context *ctx;
-
DUK_ASSERT(thr != NULL);
- ctx = (duk_context *) thr;
- DUK_ASSERT_CTX_VALID(ctx);
+ DUK_ASSERT_CTX_VALID(thr);
/*
* Error during call. The error value is at heap->lj.value1.
@@ -61766,51 +63438,56 @@ DUK_LOCAL void duk__handle_safe_call_error(duk_hthread *thr,
*/
DUK_ASSERT(thr->heap->lj.type == DUK_LJ_TYPE_THROW);
DUK_ASSERT_LJSTATE_SET(thr->heap);
- DUK_ASSERT(thr->callstack_top >= entry_callstack_top);
- DUK_ASSERT(thr->catchstack_top >= entry_catchstack_top);
- /* Note: either pointer may be NULL (at entry), so don't assert. */
+ /* Either pointer may be NULL (at entry), so don't assert. */
thr->heap->lj.jmpbuf_ptr = old_jmpbuf_ptr;
- DUK_ASSERT(thr->catchstack_top >= entry_catchstack_top);
+ /* XXX: callstack unwind may now throw an error when closing
+ * scopes; this is a sandboxing issue, described in:
+ * https://github.com/svaarala/duktape/issues/476
+ */
+ /* XXX: "unwind to" primitive? */
+
DUK_ASSERT(thr->callstack_top >= entry_callstack_top);
- duk_hthread_catchstack_unwind_norz(thr, entry_catchstack_top);
- duk_hthread_catchstack_shrink_check(thr);
- duk_hthread_callstack_unwind_norz(thr, entry_callstack_top);
- duk_hthread_callstack_shrink_check(thr);
- thr->valstack_bottom = thr->valstack + entry_valstack_bottom_index;
+ while (thr->callstack_curr != entry_act) {
+ DUK_ASSERT(thr->callstack_curr != NULL);
+ duk_hthread_activation_unwind_norz(thr);
+ }
+ DUK_ASSERT(thr->callstack_top == entry_callstack_top);
+
+ /* Switch active thread before any side effects to avoid a
+ * dangling curr_thread pointer.
+ */
+ DUK_HEAP_SWITCH_THREAD(thr->heap, entry_curr_thread); /* may be NULL */
+ thr->state = (duk_uint8_t) entry_thread_state;
+
+ DUK_ASSERT(thr->heap->curr_thread == entry_curr_thread);
+ DUK_ASSERT(thr->state == entry_thread_state);
+
+ /* Restore valstack bottom. */
+ thr->valstack_bottom = (duk_tval *) (void *) ((duk_uint8_t *) thr->valstack + entry_valstack_bottom_byteoff);
/* [ ... | (crud) ] */
- /* XXX: space in valstack? see discussion in duk_handle_call_xxx(). */
- duk_push_tval(ctx, &thr->heap->lj.value1);
+ /* XXX: ensure space in valstack (now relies on internal reserve)? */
+ duk_push_tval(thr, &thr->heap->lj.value1);
/* [ ... | (crud) errobj ] */
- DUK_ASSERT(duk_get_top(ctx) >= 1); /* at least errobj must be on stack */
-
- /* check that the valstack has space for the final amount and any
- * intermediate space needed; this is unoptimal but should be safe
- */
- duk_require_stack_top(ctx, idx_retbase + num_stack_rets); /* final configuration */
- duk_require_stack(ctx, num_stack_rets);
+ DUK_ASSERT(duk_get_top(thr) >= 1); /* at least errobj must be on stack */
duk__safe_call_adjust_valstack(thr, idx_retbase, num_stack_rets, 1); /* 1 = num actual 'return values' */
/* [ ... | ] or [ ... | errobj (M * undefined)] where M = num_stack_rets - 1 */
- /* These are just convenience "wiping" of state. Side effects should
- * not be an issue here: thr->heap and thr->heap->lj have a stable
- * pointer. Finalizer runs etc capture even out-of-memory errors so
- * nothing should throw here.
- */
+ /* Reset longjmp state. */
thr->heap->lj.type = DUK_LJ_TYPE_UNKNOWN;
thr->heap->lj.iserror = 0;
- 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_TVAL_SET_UNDEFINED_UPDREF_NORZ(thr, &thr->heap->lj.value1);
+ DUK_TVAL_SET_UNDEFINED_UPDREF_NORZ(thr, &thr->heap->lj.value2);
- /* Error handling complete, remove side effect protections and
- * process pending finalizers.
+ /* Error handling complete, remove side effect protections. Caller
+ * will process pending finalizers.
*/
#if defined(DUK_USE_ASSERTIONS)
DUK_ASSERT(thr->heap->error_not_allowed == 1);
@@ -61820,47 +63497,39 @@ DUK_LOCAL void duk__handle_safe_call_error(duk_hthread *thr,
thr->heap->pf_prevent_count--;
DUK_DD(DUK_DDPRINT("safe call error handled, pf_prevent_count updated to %ld", (long) thr->heap->pf_prevent_count));
- DUK_ASSERT_LJSTATE_UNSET(thr->heap);
-
- DUK_REFZERO_CHECK_SLOW(thr);
+ /* thr->ptr_curr_pc is restored by
+ * duk__handle_safe_call_shared_unwind() which is also used for
+ * success path.
+ */
}
-DUK_LOCAL void duk__handle_safe_call_shared(duk_hthread *thr,
- duk_idx_t idx_retbase,
- duk_idx_t num_stack_rets,
- 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_context *ctx;
-
+DUK_LOCAL void duk__handle_safe_call_shared_unwind(duk_hthread *thr,
+ duk_idx_t idx_retbase,
+ duk_idx_t num_stack_rets,
+#if defined(DUK_USE_ASSERTIONS)
+ duk_size_t entry_callstack_top,
+#endif
+ duk_int_t entry_call_recursion_depth,
+ duk_hthread *entry_curr_thread,
+ duk_instr_t **entry_ptr_curr_pc) {
DUK_ASSERT(thr != NULL);
- ctx = (duk_context *) thr;
- DUK_ASSERT_CTX_VALID(ctx);
- DUK_UNREF(ctx);
+ DUK_ASSERT_CTX_VALID(thr);
DUK_UNREF(idx_retbase);
DUK_UNREF(num_stack_rets);
+ DUK_UNREF(entry_curr_thread);
- /* Restore entry thread executor curr_pc stack frame pointer. */
- thr->ptr_curr_pc = entry_ptr_curr_pc;
+ DUK_ASSERT(thr->callstack_top == entry_callstack_top);
- /* 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()
- * was fixed to restore thr->heap->curr_thread before rethrowing an
- * uncaught error.
+ /* Restore entry thread executor curr_pc stack frame pointer.
+ * XXX: would be enough to do in error path only, should nest
+ * cleanly in success path.
*/
- DUK_HEAP_SWITCH_THREAD(thr->heap, entry_curr_thread); /* may be NULL */
- thr->state = (duk_uint8_t) entry_thread_state;
-
- DUK_ASSERT((thr->state == DUK_HTHREAD_STATE_INACTIVE && thr->heap->curr_thread == NULL) || /* first call */
- (thr->state == DUK_HTHREAD_STATE_INACTIVE && thr->heap->curr_thread != NULL) || /* other call */
- (thr->state == DUK_HTHREAD_STATE_RUNNING && thr->heap->curr_thread == thr)); /* current thread */
+ thr->ptr_curr_pc = entry_ptr_curr_pc;
thr->heap->call_recursion_depth = entry_call_recursion_depth;
/* stack discipline consistency check */
- DUK_ASSERT(duk_get_top(ctx) == idx_retbase + num_stack_rets);
+ DUK_ASSERT(duk_get_top(thr) == idx_retbase + num_stack_rets);
/* A debugger forced interrupt check is not needed here, as
* problematic safe calls are not caused by side effects.
@@ -61869,479 +63538,293 @@ DUK_LOCAL void duk__handle_safe_call_shared(duk_hthread *thr,
#if defined(DUK_USE_INTERRUPT_COUNTER) && defined(DUK_USE_DEBUG)
duk__interrupt_fixup(thr, entry_curr_thread);
#endif
-
- DUK_ASSERT_LJSTATE_UNSET(thr->heap);
}
-/*
- * Helper for handling an Ecmascript-to-Ecmascript call or an Ecmascript
- * function (initial) Duktape.Thread.resume().
- *
- * Compared to normal calls handled by duk_handle_call(), there are a
- * bunch of differences:
- *
- * - the call is never protected
- * - there is no C recursion depth increase (hence an "ignore recursion
- * limit" flag is not applicable)
- * - instead of making the call, this helper just performs the thread
- * setup and returns; the bytecode executor then restarts execution
- * internally
- * - ecmascript functions are never 'vararg' functions (they access
- * varargs through the 'arguments' object)
- *
- * The callstack of the target contains an earlier Ecmascript call in case
- * of an Ecmascript-to-Ecmascript call (whose idx_retval is updated), or
- * is empty in case of an initial Duktape.Thread.resume().
- *
- * The first thing to do here is to figure out whether an ecma-to-ecma
- * call is actually possible. It's not always the case if the target is
- * a bound function; the final function may be native. In that case,
- * return an error so caller can fall back to a normal call path.
- */
-
-DUK_INTERNAL duk_bool_t duk_handle_ecma_call_setup(duk_hthread *thr,
- duk_idx_t num_stack_args,
- duk_small_uint_t call_flags) {
- duk_context *ctx = (duk_context *) thr;
- duk_size_t entry_valstack_bottom_index;
- 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 => never for ecma calls) */
- duk_idx_t nregs; /* # total registers target function wants on entry (< 0 => never for ecma calls) */
- duk_hobject *func; /* 'func' on stack (borrowed reference) */
- duk_tval *tv_func; /* duk_tval ptr for 'func' on stack (borrowed reference) */
- duk_activation *act;
- duk_hobject *env;
- duk_bool_t use_tailcall;
+DUK_INTERNAL duk_int_t duk_handle_safe_call(duk_hthread *thr,
+ duk_safe_call_function func,
+ void *udata,
+ duk_idx_t num_stack_args,
+ duk_idx_t num_stack_rets) {
+ duk_activation *entry_act;
+ duk_size_t entry_valstack_bottom_byteoff;
+#if defined(DUK_USE_ASSERTIONS)
+ duk_size_t entry_valstack_end_byteoff;
+ duk_size_t entry_callstack_top;
+ duk_size_t entry_callstack_preventcount;
+#endif
+ 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_idx_t idx_retbase;
+ duk_int_t retval;
DUK_ASSERT(thr != NULL);
- DUK_ASSERT(ctx != NULL);
- DUK_ASSERT(!((call_flags & DUK_CALL_FLAG_IS_RESUME) != 0 && (call_flags & DUK_CALL_FLAG_IS_TAILCALL) != 0));
-
- /* XXX: assume these? */
- DUK_ASSERT(thr->valstack != NULL);
- DUK_ASSERT(thr->callstack != NULL);
- DUK_ASSERT(thr->catchstack != NULL);
+ DUK_ASSERT(duk_get_top(thr) >= num_stack_args); /* Caller ensures. */
- /* no need to handle thread state book-keeping here */
- DUK_ASSERT((call_flags & DUK_CALL_FLAG_IS_RESUME) != 0 ||
- (thr->state == DUK_HTHREAD_STATE_RUNNING &&
- thr->heap->curr_thread == thr));
+ DUK_STATS_INC(thr->heap, stats_safecall_all);
- /* 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.
+ /* Value stack reserve handling: safe call assumes caller has reserved
+ * space for nrets (assuming optimal unwind processing). Value stack
+ * reserve is not stored/restored as for normal calls because a safe
+ * call conceptually happens in the same activation.
*/
- 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
- */
+ /* Careful with indices like '-x'; if 'x' is zero, it refers to bottom */
+ entry_act = thr->callstack_curr;
+ entry_valstack_bottom_byteoff = (duk_size_t) ((duk_uint8_t *) thr->valstack_bottom - (duk_uint8_t *) thr->valstack);
#if defined(DUK_USE_ASSERTIONS)
- if (call_flags & DUK_CALL_FLAG_IS_TAILCALL) {
- duk_size_t our_callstack_index;
- duk_size_t i;
-
- DUK_ASSERT(thr->callstack_top >= 1);
- our_callstack_index = thr->callstack_top - 1;
- DUK_ASSERT_DISABLE(our_callstack_index >= 0);
- DUK_ASSERT(our_callstack_index < thr->callstack_size);
- DUK_ASSERT(DUK_ACT_GET_FUNC(thr->callstack + our_callstack_index) != NULL);
- DUK_ASSERT(DUK_HOBJECT_IS_COMPFUNC(DUK_ACT_GET_FUNC(thr->callstack + our_callstack_index)));
-
- /* No entry in the catchstack which would actually catch a
- * throw can refer to the callstack entry being reused.
- * There *can* be catchstack entries referring to the current
- * callstack entry as long as they don't catch (e.g. label sites).
- */
-
- for (i = 0; i < thr->catchstack_top; i++) {
- DUK_ASSERT(thr->catchstack[i].callstack_index < our_callstack_index || /* refer to callstack entries below current */
- DUK_CAT_GET_TYPE(thr->catchstack + i) == DUK_CAT_TYPE_LABEL); /* or a non-catching entry */
- }
- }
-#endif /* DUK_USE_ASSERTIONS */
+ entry_valstack_end_byteoff = (duk_size_t) ((duk_uint8_t *) thr->valstack_end - (duk_uint8_t *) thr->valstack);
+ entry_callstack_top = thr->callstack_top;
+ entry_callstack_preventcount = thr->callstack_preventcount;
+#endif
+ entry_call_recursion_depth = thr->heap->call_recursion_depth;
+ entry_curr_thread = thr->heap->curr_thread; /* 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(thr) - num_stack_args; /* not a valid stack index if num_stack_args == 0 */
+ DUK_ASSERT(idx_retbase >= 0);
- entry_valstack_bottom_index = (duk_size_t) (thr->valstack_bottom - thr->valstack);
- /* XXX: rework */
- idx_func = duk_normalize_index(thr, -num_stack_args - 2);
- idx_args = idx_func + 2;
+ DUK_ASSERT((duk_idx_t) (thr->valstack_top - thr->valstack_bottom) >= num_stack_args); /* Caller ensures. */
+ DUK_ASSERT((duk_idx_t) (thr->valstack_end - (thr->valstack_bottom + idx_retbase)) >= num_stack_rets); /* Caller ensures. */
- DUK_DD(DUK_DDPRINT("handle_ecma_call_setup: thr=%p, "
- "num_stack_args=%ld, call_flags=0x%08lx (resume=%ld, tailcall=%ld), "
- "idx_func=%ld, idx_args=%ld, entry_valstack_bottom_index=%ld",
+ /* Cannot portably debug print a function pointer, hence 'func' not printed! */
+ DUK_DD(DUK_DDPRINT("duk_handle_safe_call: thr=%p, num_stack_args=%ld, num_stack_rets=%ld, "
+ "valstack_top=%ld, idx_retbase=%ld, rec_depth=%ld/%ld, "
+ "entry_act=%p, entry_valstack_bottom_byteoff=%ld, entry_call_recursion_depth=%ld, "
+ "entry_curr_thread=%p, entry_thread_state=%ld",
(void *) thr,
(long) num_stack_args,
- (unsigned long) call_flags,
- (long) ((call_flags & DUK_CALL_FLAG_IS_RESUME) != 0 ? 1 : 0),
- (long) ((call_flags & DUK_CALL_FLAG_IS_TAILCALL) != 0 ? 1 : 0),
- (long) idx_func,
- (long) idx_args,
- (long) entry_valstack_bottom_index));
+ (long) num_stack_rets,
+ (long) duk_get_top(thr),
+ (long) idx_retbase,
+ (long) thr->heap->call_recursion_depth,
+ (long) thr->heap->call_recursion_limit,
+ (void *) entry_act,
+ (long) entry_valstack_bottom_byteoff,
+ (long) entry_call_recursion_depth,
+ (void *) entry_curr_thread,
+ (long) entry_thread_state));
- if (DUK_UNLIKELY(idx_func < 0 || idx_args < 0)) {
- /* XXX: assert? compiler is responsible for this never happening */
- DUK_ERROR_TYPE_INVALID_ARGS(thr);
- }
+ /* Setjmp catchpoint setup. */
+ old_jmpbuf_ptr = thr->heap->lj.jmpbuf_ptr;
+ thr->heap->lj.jmpbuf_ptr = &our_jmpbuf;
- /*
- * Check the function type, handle bound function chains, and prepare
- * parameters for the rest of the call handling. Also figure out the
- * effective 'this' binding, which replaces the current value at
- * idx_func + 1.
- *
- * If the target function is a 'bound' one, follow the chain of 'bound'
- * functions until a non-bound function is found. During this process,
- * bound arguments are 'prepended' to existing ones, and the "this"
- * binding is overridden. See E5 Section 15.3.4.5.1.
- *
- * If the final target function cannot be handled by an ecma-to-ecma
- * call, return to the caller with a return value indicating this case.
- * The bound chain is resolved and the caller can resume with a plain
- * function call.
+ /* Prevent yields for the duration of the safe call. This only
+ * matters if the executor makes safe calls to functions that
+ * yield, this doesn't currently happen.
*/
+ thr->callstack_preventcount++;
- func = duk__nonbound_func_lookup(ctx, idx_func, &num_stack_args, &tv_func, call_flags);
- if (func == NULL || !DUK_HOBJECT_IS_COMPFUNC(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 */
-
- DUK_ASSERT(func != NULL);
- DUK_ASSERT(!DUK_HOBJECT_HAS_BOUNDFUNC(func));
- DUK_ASSERT(DUK_HOBJECT_IS_COMPFUNC(func));
-
- duk__coerce_effective_this_binding(thr, func, idx_func + 1);
- DUK_DDD(DUK_DDDPRINT("effective 'this' binding is: %!T",
- duk_get_tval(ctx, idx_func + 1)));
-
- nargs = ((duk_hcompfunc *) func)->nargs;
- nregs = ((duk_hcompfunc *) func)->nregs;
- DUK_ASSERT(nregs >= nargs);
-
- /* [ ... func this arg1 ... argN ] */
-
- /*
- * Preliminary activation record and valstack manipulation.
- * The concrete actions depend on whether the we're dealing
- * with a tail call (reuse an existing activation), a resume,
- * or a normal call.
- *
- * The basic actions, in varying order, are:
- *
- * - Check stack size for call handling
- * - Grow call stack if necessary (non-tail-calls)
- * - Update current activation (idx_retval) if necessary
- * (non-tail, non-resume calls)
- * - Move start of args (idx_args) to valstack bottom
- * (tail calls)
- *
- * Don't touch valstack_bottom or valstack_top yet so that Duktape API
- * calls work normally.
- */
+#if defined(DUK_USE_CPP_EXCEPTIONS)
+ try {
+#else
+ DUK_ASSERT(thr->heap->lj.jmpbuf_ptr == &our_jmpbuf);
+ if (DUK_SETJMP(our_jmpbuf.jb) == 0) {
+ /* Success path. */
+#endif
+ DUK_DDD(DUK_DDDPRINT("safe_call setjmp catchpoint setup complete"));
- /* XXX: some overlapping code; cleanup */
- use_tailcall = call_flags & DUK_CALL_FLAG_IS_TAILCALL;
-#if !defined(DUK_USE_TAILCALL)
- DUK_ASSERT(use_tailcall == 0); /* compiler ensures this */
+ duk__handle_safe_call_inner(thr,
+ func,
+ udata,
+#if defined(DUK_USE_ASSERTIONS)
+ entry_valstack_bottom_byteoff,
+ entry_callstack_top,
#endif
- if (use_tailcall) {
- /* tailcall cannot be flagged to resume calls, and a
- * previous frame must exist
- */
- DUK_ASSERT(thr->callstack_top >= 1);
- DUK_ASSERT((call_flags & DUK_CALL_FLAG_IS_RESUME) == 0);
+ entry_curr_thread,
+ entry_thread_state,
+ idx_retbase,
+ num_stack_rets);
- act = thr->callstack_curr;
- DUK_ASSERT(act != NULL);
- if (act->flags & DUK_ACT_FLAG_PREVENT_YIELD) {
- /* See: test-bug-tailcall-preventyield-assert.c. */
- 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("tail call prevented by function having a notail flag"));
- use_tailcall = 0;
- }
- }
+ DUK_STATS_INC(thr->heap, stats_safecall_nothrow);
- if (use_tailcall) {
- duk_tval *tv1, *tv2;
- duk_size_t cs_index;
- duk_int_t i_stk; /* must be signed for loop structure */
- duk_idx_t i_arg;
+ /* Either pointer may be NULL (at entry), so don't assert */
+ thr->heap->lj.jmpbuf_ptr = old_jmpbuf_ptr;
- /*
- * Tailcall handling
- *
- * Although the callstack entry is reused, we need to explicitly unwind
- * 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 tail calls.
+ /* If calls happen inside the safe call, these are restored by
+ * whatever calls are made. Reserve cannot decrease.
*/
+ DUK_ASSERT(thr->callstack_curr == entry_act);
+ DUK_ASSERT((duk_size_t) ((duk_uint8_t *) thr->valstack_end - (duk_uint8_t *) thr->valstack) >= entry_valstack_end_byteoff);
- DUK_DDD(DUK_DDDPRINT("is tail call, reusing activation at callstack top, at index %ld",
- (long) (thr->callstack_top - 1)));
-
- /* 'act' already set above */
-
- DUK_ASSERT(!DUK_HOBJECT_HAS_BOUNDFUNC(func));
- DUK_ASSERT(!DUK_HOBJECT_HAS_NATFUNC(func));
- DUK_ASSERT(DUK_HOBJECT_HAS_COMPFUNC(func));
- DUK_ASSERT((act->flags & DUK_ACT_FLAG_PREVENT_YIELD) == 0);
-
- /* Unwind catchstack entries referring to the callstack entry we're reusing */
- cs_index = thr->callstack_top - 1;
- DUK_ASSERT(thr->catchstack_top <= DUK_INT_MAX); /* catchstack limits */
- for (i_stk = (duk_int_t) (thr->catchstack_top - 1); i_stk >= 0; i_stk--) {
- duk_catcher *cat = thr->catchstack + i_stk;
- if (cat->callstack_index != cs_index) {
- /* 'i' is the first entry we'll keep */
- break;
- }
- }
- duk_hthread_catchstack_unwind_norz(thr, i_stk + 1);
-
- /* Unwind the topmost callstack entry before reusing it */
- DUK_ASSERT(thr->callstack_top > 0);
- duk_hthread_callstack_unwind_norz(thr, thr->callstack_top - 1);
-
- /* Then reuse the unwound activation; callstack was not shrunk so there is always space */
- DUK_ASSERT(thr->callstack_top < thr->callstack_size);
- act = thr->callstack + thr->callstack_top;
- thr->callstack_top++;
- thr->callstack_curr = act;
-
- /* Start filling in the activation */
- act->func = func; /* don't want an intermediate exposed state with func == NULL */
-#if defined(DUK_USE_NONSTD_FUNC_CALLER_PROPERTY)
- act->prev_caller = NULL;
-#endif
- DUK_ASSERT(func != NULL);
- DUK_ASSERT(DUK_HOBJECT_HAS_COMPFUNC(func));
- /* don't want an intermediate exposed state with invalid pc */
- act->curr_pc = DUK_HCOMPFUNC_GET_CODE_BASE(thr->heap, (duk_hcompfunc *) func);
-#if defined(DUK_USE_DEBUGGER_SUPPORT)
- act->prev_line = 0;
-#endif
- DUK_TVAL_SET_OBJECT(&act->tv_func, func); /* borrowed, no refcount */
-#if defined(DUK_USE_REFERENCE_COUNTING)
- DUK_HOBJECT_INCREF(thr, func);
- act = thr->callstack_curr; /* side effects (currently none though) */
-#endif
-
-#if defined(DUK_USE_NONSTD_FUNC_CALLER_PROPERTY)
-#if defined(DUK_USE_TAILCALL)
-#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
- * is in use.
- */
- duk__update_func_caller_prop(thr, func);
- act = thr->callstack_curr;
+ retval = DUK_EXEC_SUCCESS;
+#if defined(DUK_USE_CPP_EXCEPTIONS)
+ } catch (duk_internal_exception &exc) {
+ DUK_UNREF(exc);
+#else
+ } else {
+ /* Error path. */
#endif
+ DUK_ASSERT((duk_size_t) ((duk_uint8_t *) thr->valstack_end - (duk_uint8_t *) thr->valstack) >= entry_valstack_end_byteoff);
- act->flags = (DUK_HOBJECT_HAS_STRICT(func) ?
- DUK_ACT_FLAG_STRICT | DUK_ACT_FLAG_TAILCALLED :
- DUK_ACT_FLAG_TAILCALLED);
+ DUK_STATS_INC(thr->heap, stats_safecall_throw);
- 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) */
- 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 */
- act->idx_retval = 0;
+ duk__handle_safe_call_error(thr,
+ entry_act,
+#if defined(DUK_USE_ASSERTIONS)
+ entry_callstack_top,
#endif
+ entry_curr_thread,
+ entry_thread_state,
+ idx_retbase,
+ num_stack_rets,
+ entry_valstack_bottom_byteoff,
+ old_jmpbuf_ptr);
- /*
- * Manipulate valstack so that args are on the current bottom and the
- * previous caller's 'this' binding (which is the value preceding the
- * current bottom) is replaced with the new 'this' binding:
- *
- * [ ... this_old | (crud) func this_new arg1 ... argN ]
- * --> [ ... this_new | arg1 ... argN ]
- *
- * For tail calling to work properly, the valstack bottom must not grow
- * here; otherwise crud would accumulate on the valstack.
- */
-
- tv1 = thr->valstack_bottom - 1;
- 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_UPDREF(thr, tv1, tv2); /* side effects */
-
- for (i_arg = 0; i_arg < idx_args; i_arg++) {
- /* XXX: block removal API primitive */
- /* Note: 'func' is popped from valstack here, but it is
- * already reachable from the activation.
- */
- duk_remove(ctx, 0);
- }
- idx_func = 0; DUK_UNREF(idx_func); /* really 'not applicable' anymore, should not be referenced after this */
- idx_args = 0;
-
- /* [ ... this_new | arg1 ... argN ] */
- } else {
- 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);
-
- if (call_flags & DUK_CALL_FLAG_IS_RESUME) {
- DUK_DDD(DUK_DDDPRINT("is resume -> no update to current activation (may not even exist)"));
- } else {
- DUK_DDD(DUK_DDDPRINT("update to current activation idx_retval"));
- DUK_ASSERT(thr->callstack_top < thr->callstack_size);
- DUK_ASSERT(thr->callstack_top >= 1);
- act = thr->callstack_curr;
- DUK_ASSERT(DUK_ACT_GET_FUNC(act) != NULL);
- DUK_ASSERT(DUK_HOBJECT_IS_COMPFUNC(DUK_ACT_GET_FUNC(act)));
- act->idx_retval = entry_valstack_bottom_index + idx_func;
+ retval = DUK_EXEC_ERROR;
+ }
+#if defined(DUK_USE_CPP_EXCEPTIONS)
+ catch (std::exception &exc) {
+ const char *what = exc.what();
+ DUK_ASSERT((duk_size_t) ((duk_uint8_t *) thr->valstack_end - (duk_uint8_t *) thr->valstack) >= entry_valstack_end_byteoff);
+ DUK_STATS_INC(thr->heap, stats_safecall_throw);
+ if (!what) {
+ what = "unknown";
}
-
- DUK_ASSERT(thr->callstack_top < thr->callstack_size);
- act = thr->callstack + thr->callstack_top;
- thr->callstack_top++;
- thr->callstack_curr = act;
- DUK_ASSERT(thr->callstack_top <= thr->callstack_size);
-
- DUK_ASSERT(!DUK_HOBJECT_HAS_BOUNDFUNC(func));
- DUK_ASSERT(!DUK_HOBJECT_HAS_NATFUNC(func));
- DUK_ASSERT(DUK_HOBJECT_HAS_COMPFUNC(func));
-
- act->flags = (DUK_HOBJECT_HAS_STRICT(func) ?
- DUK_ACT_FLAG_STRICT :
- 0);
- act->func = func;
- act->var_env = NULL;
- act->lex_env = NULL;
-#if defined(DUK_USE_NONSTD_FUNC_CALLER_PROPERTY)
- act->prev_caller = NULL;
-#endif
- DUK_ASSERT(func != NULL);
- DUK_ASSERT(DUK_HOBJECT_HAS_COMPFUNC(func));
- act->curr_pc = DUK_HCOMPFUNC_GET_CODE_BASE(thr->heap, (duk_hcompfunc *) func);
-#if defined(DUK_USE_DEBUGGER_SUPPORT)
- act->prev_line = 0;
-#endif
- act->idx_bottom = entry_valstack_bottom_index + idx_args;
- DUK_ASSERT(nregs >= 0);
-#if 0 /* topmost activation idx_retval is considered garbage, no need to init */
- act->idx_retval = 0;
+ DUK_D(DUK_DPRINT("unexpected c++ std::exception (perhaps thrown by user code)"));
+ try {
+ DUK_ERROR_FMT1(thr, DUK_ERR_TYPE_ERROR, "caught invalid c++ std::exception '%s' (perhaps thrown by user code)", what);
+ } catch (duk_internal_exception exc) {
+ DUK_D(DUK_DPRINT("caught api error thrown from unexpected c++ std::exception"));
+ DUK_UNREF(exc);
+ duk__handle_safe_call_error(thr,
+ entry_act,
+#if defined(DUK_USE_ASSERTIONS)
+ entry_callstack_top,
#endif
- DUK_TVAL_SET_OBJECT(&act->tv_func, func); /* borrowed, no refcount */
-
- DUK_HOBJECT_INCREF(thr, func); /* act->func */
-
-#if defined(DUK_USE_NONSTD_FUNC_CALLER_PROPERTY)
- duk__update_func_caller_prop(thr, func);
- act = thr->callstack_curr;
+ entry_curr_thread,
+ entry_thread_state,
+ idx_retbase,
+ num_stack_rets,
+ entry_valstack_bottom_byteoff,
+ old_jmpbuf_ptr);
+ retval = DUK_EXEC_ERROR;
+ }
+ } catch (...) {
+ DUK_D(DUK_DPRINT("unexpected c++ exception (perhaps thrown by user code)"));
+ DUK_ASSERT((duk_size_t) ((duk_uint8_t *) thr->valstack_end - (duk_uint8_t *) thr->valstack) >= entry_valstack_end_byteoff);
+ DUK_STATS_INC(thr->heap, stats_safecall_throw);
+ try {
+ DUK_ERROR_TYPE(thr, "caught invalid c++ exception (perhaps thrown by user code)");
+ } catch (duk_internal_exception exc) {
+ DUK_D(DUK_DPRINT("caught api error thrown from unexpected c++ exception"));
+ DUK_UNREF(exc);
+ duk__handle_safe_call_error(thr,
+ entry_act,
+#if defined(DUK_USE_ASSERTIONS)
+ entry_callstack_top,
#endif
+ entry_curr_thread,
+ entry_thread_state,
+ idx_retbase,
+ num_stack_rets,
+ entry_valstack_bottom_byteoff,
+ old_jmpbuf_ptr);
+ retval = DUK_EXEC_ERROR;
+ }
}
+#endif
- /* [ ... func this arg1 ... argN ] (not tail call)
- * [ this | arg1 ... argN ] (tail call)
- *
- * idx_args updated to match
- */
-
- /*
- * Environment record creation and 'arguments' object creation.
- * Named function expression name binding is handled by the
- * compiler; the compiled function's parent env will contain
- * the (immutable) binding already.
- *
- * Delayed creation (on demand) is handled in duk_js_var.c.
- */
+ DUK_ASSERT(thr->heap->lj.jmpbuf_ptr == old_jmpbuf_ptr); /* success/error path both do this */
- /* XXX: unify handling with native call. */
+ DUK_ASSERT_LJSTATE_UNSET(thr->heap);
- DUK_ASSERT(!DUK_HOBJECT_HAS_BOUNDFUNC(func)); /* bound function chain has already been resolved */
+ DUK_ASSERT((duk_size_t) ((duk_uint8_t *) thr->valstack_end - (duk_uint8_t *) thr->valstack) >= entry_valstack_end_byteoff);
+ duk__handle_safe_call_shared_unwind(thr,
+ idx_retbase,
+ num_stack_rets,
+#if defined(DUK_USE_ASSERTIONS)
+ entry_callstack_top,
+#endif
+ entry_call_recursion_depth,
+ entry_curr_thread,
+ entry_ptr_curr_pc);
- if (!DUK_HOBJECT_HAS_NEWENV(func)) {
- /* use existing env (e.g. for non-strict eval); cannot have
- * an own 'arguments' object (but can refer to the existing one)
- */
+ /* Restore preventcount. */
+ thr->callstack_preventcount--;
+ DUK_ASSERT(thr->callstack_preventcount == entry_callstack_preventcount);
- duk__handle_oldenv_for_call(thr, func, act);
- /* No need to re-lookup 'act' at present: no side effects. */
+ /* Final asserts. */
+ DUK_ASSERT(thr->callstack_curr == entry_act);
+ DUK_ASSERT((duk_size_t) ((duk_uint8_t *) thr->valstack_bottom - (duk_uint8_t *) thr->valstack) == entry_valstack_bottom_byteoff);
+ DUK_ASSERT((duk_size_t) ((duk_uint8_t *) thr->valstack_end - (duk_uint8_t *) thr->valstack) >= entry_valstack_end_byteoff);
+ DUK_ASSERT(thr->callstack_top == entry_callstack_top);
+ DUK_ASSERT(thr->heap->call_recursion_depth == entry_call_recursion_depth);
+ DUK_ASSERT(thr->heap->curr_thread == entry_curr_thread);
+ DUK_ASSERT(thr->state == entry_thread_state);
+ DUK_ASSERT(thr->ptr_curr_pc == entry_ptr_curr_pc);
+ DUK_ASSERT(duk_get_top(thr) == idx_retbase + num_stack_rets);
+ DUK_ASSERT_LJSTATE_UNSET(thr->heap);
- DUK_ASSERT(act->lex_env != NULL);
- DUK_ASSERT(act->var_env != NULL);
- goto env_done;
- }
+ /* Pending side effects. */
+ DUK_REFZERO_CHECK_FAST(thr);
- DUK_ASSERT(DUK_HOBJECT_HAS_NEWENV(func));
+ return retval;
+}
- if (!DUK_HOBJECT_HAS_CREATEARGS(func)) {
- /* no need to create environment record now; leave as NULL */
- DUK_ASSERT(act->lex_env == NULL);
- DUK_ASSERT(act->var_env == NULL);
- goto env_done;
- }
+/*
+ * Property-based call (foo.noSuch()) error setup: replace target function
+ * on stack top with a specially tagged (hidden Symbol) error which gets
+ * thrown in call handling at the proper spot to follow Ecmascript semantics.
+ */
- /* third arg: absolute index (to entire valstack) of idx_bottom of new activation */
- env = duk_create_activation_environment_record(thr, func, act->idx_bottom);
- DUK_ASSERT(env != NULL);
+#if defined(DUK_USE_VERBOSE_ERRORS)
+DUK_INTERNAL DUK_NOINLINE DUK_COLD void duk_call_setup_propcall_error(duk_hthread *thr, duk_tval *tv_targ, duk_tval *tv_base, duk_tval *tv_key) {
+ const char *str1, *str2, *str3;
+ duk_idx_t entry_top;
- /* [ ... arg1 ... argN envobj ] */
+ entry_top = duk_get_top(thr);
- /* original input stack before nargs/nregs handling must be
- * intact for 'arguments' object
+ /* Must stabilize pointers first. Argument convention is a bit awkward,
+ * it comes from the executor call site where some arguments may not be
+ * on the value stack (consts).
*/
- DUK_ASSERT(DUK_HOBJECT_HAS_CREATEARGS(func));
- duk__handle_createargs_for_call(thr, func, env, num_stack_args);
-
- /* [ ... arg1 ... argN envobj ] */
+ duk_push_tval(thr, tv_base);
+ duk_push_tval(thr, tv_key);
+ duk_push_tval(thr, tv_targ);
- act = thr->callstack_curr;
- act->lex_env = env;
- act->var_env = env;
- DUK_HOBJECT_INCREF(thr, act->lex_env);
- DUK_HOBJECT_INCREF(thr, act->var_env);
- duk_pop(ctx);
-
- env_done:
- /* [ ... arg1 ... argN ] */
+ DUK_GC_TORTURE(thr->heap);
- /*
- * Setup value stack: clamp to 'nargs', fill up to 'nregs'
+ /* We only push an error, replacing the call target (at idx_func)
+ * with the error to ensure side effects come out correctly:
+ * - Property read
+ * - Call argument evaluation
+ * - Callability check and error thrown.
+ *
+ * A hidden Symbol on the error object pushed here is used by
+ * call handling to figure out the error is to be thrown as is.
+ * It is CRITICAL that the hidden Symbol can never occur on a
+ * user visible object that may get thrown.
*/
- duk__adjust_valstack_and_top(thr,
- num_stack_args,
- idx_args,
- nregs,
- nargs,
- func);
-
- /*
- * Shift to new valstack_bottom.
- */
+#if defined(DUK_USE_PARANOID_ERRORS)
+ str1 = duk_get_type_name(thr, -1);
+ str2 = duk_get_type_name(thr, -2);
+ str3 = duk_get_type_name(thr, -3);
+ duk_push_error_object(thr, DUK_ERR_TYPE_ERROR | DUK_ERRCODE_FLAG_NOBLAME_FILELINE, "%s not callable (property %s of %s)", str1, str2, str3);
+#else
+ str1 = duk_push_string_readable(thr, -1);
+ str2 = duk_push_string_readable(thr, -3);
+ str3 = duk_push_string_readable(thr, -5);
+ duk_push_error_object(thr, DUK_ERR_TYPE_ERROR | DUK_ERRCODE_FLAG_NOBLAME_FILELINE, "%s not callable (property %s of %s)", str1, str2, str3);
+#endif
- thr->valstack_bottom = thr->valstack_bottom + idx_args;
- /* keep current valstack_top */
- DUK_ASSERT(thr->valstack_bottom >= thr->valstack);
- DUK_ASSERT(thr->valstack_top >= thr->valstack_bottom);
- DUK_ASSERT(thr->valstack_end >= thr->valstack_top);
+ duk_push_true(thr);
+ duk_put_prop_stridx(thr, -2, DUK_STRIDX_INT_TARGET); /* Marker property, reuse _Target. */
- /*
- * Return to bytecode executor, which will resume execution from
- * the topmost activation.
- */
+ /* [ <nregs> propValue <variable> error ] */
+ duk_replace(thr, entry_top - 1);
+ duk_set_top(thr, entry_top);
- DUK_REFZERO_CHECK_FAST(thr);
- return 1;
+ DUK_ASSERT(!duk_is_callable(thr, -1)); /* Critical so that call handling will throw the error. */
}
+#endif /* DUK_USE_VERBOSE_ERRORS */
+
+/* automatic undefs */
+#undef DUK__AUGMENT_CALL_RELAX_COUNT
/*
* Ecmascript compiler.
*
@@ -62365,8 +63848,8 @@ DUK_INTERNAL duk_bool_t duk_handle_ecma_call_setup(duk_hthread *thr,
*
* A few typing notes:
*
- * - duk_regconst_t: unsigned, no marker value for "none"
- * - duk_reg_t: signed, < 0 = none
+ * - duk_regconst_t: signed, highest bit set (< 0) means constant,
+ * some call sites use -1 for "none" (equivalent to constant 0x7fffffff)
* - PC values: duk_int_t, negative values used as markers
*/
@@ -62374,15 +63857,16 @@ DUK_INTERNAL duk_bool_t duk_handle_ecma_call_setup(duk_hthread *thr,
/* If highest bit of a register number is set, it refers to a constant instead.
* When interpreted as a signed value, this means const values are always
- * negative (when interpreted as two's complement). For example DUK__ISTEMP()
+ * negative (when interpreted as two's complement). For example DUK__ISREG_TEMP()
* uses this approach to avoid an explicit DUK__ISREG() check (the condition is
* logically "'x' is a register AND 'x' >= temp_first").
*/
#define DUK__CONST_MARKER DUK_REGCONST_CONST_MARKER
-#define DUK__ISREG(x) (((x) & DUK__CONST_MARKER) == 0)
-#define DUK__ISCONST(x) (((x) & DUK__CONST_MARKER) != 0)
#define DUK__REMOVECONST(x) ((x) & ~DUK__CONST_MARKER)
-#define DUK__ISTEMP(comp_ctx,x) ((duk_int32_t) (x) >= (duk_int32_t) ((comp_ctx)->curr_func.temp_first)) /* Avoid DUK__ISREG() check by interpreting as negative value. */
+#define DUK__ISREG(x) ((x) >= 0)
+#define DUK__ISCONST(x) ((x) < 0)
+#define DUK__ISREG_TEMP(comp_ctx,x) ((duk_int32_t) (x) >= (duk_int32_t) ((comp_ctx)->curr_func.temp_first)) /* Check for x >= temp_first && x >= 0 by comparing as signed. */
+#define DUK__ISREG_NOTTEMP(comp_ctx,x) ((duk_uint32_t) (x) < (duk_uint32_t) ((comp_ctx)->curr_func.temp_first)) /* Check for x >= 0 && x < temp_first by interpreting as unsigned. */
#define DUK__GETTEMP(comp_ctx) ((comp_ctx)->curr_func.temp_next)
#define DUK__SETTEMP(comp_ctx,x) ((comp_ctx)->curr_func.temp_next = (x)) /* dangerous: must only lower (temp_max not updated) */
#define DUK__SETTEMP_CHECKMAX(comp_ctx,x) duk__settemp_checkmax((comp_ctx),(x))
@@ -62412,12 +63896,12 @@ DUK_INTERNAL duk_bool_t duk_handle_ecma_call_setup(duk_hthread *thr,
#define DUK__RECURSION_INCREASE(comp_ctx,thr) do { \
DUK_DDD(DUK_DDDPRINT("RECURSION INCREASE: %s:%ld", (const char *) DUK_FILE_MACRO, (long) DUK_LINE_MACRO)); \
- duk__recursion_increase((comp_ctx)); \
+ duk__comp_recursion_increase((comp_ctx)); \
} while (0)
#define DUK__RECURSION_DECREASE(comp_ctx,thr) do { \
DUK_DDD(DUK_DDDPRINT("RECURSION DECREASE: %s:%ld", (const char *) DUK_FILE_MACRO, (long) DUK_LINE_MACRO)); \
- duk__recursion_decrease((comp_ctx)); \
+ duk__comp_recursion_decrease((comp_ctx)); \
} while (0)
/* Value stack slot limits: these are quite approximate right now, and
@@ -62450,7 +63934,7 @@ DUK_LOCAL_DECL void duk__advance(duk_compiler_ctx *ctx);
/* function helpers */
DUK_LOCAL_DECL void duk__init_func_valstack_slots(duk_compiler_ctx *comp_ctx);
DUK_LOCAL_DECL void duk__reset_func_for_pass2(duk_compiler_ctx *comp_ctx);
-DUK_LOCAL_DECL void duk__init_varmap_and_prologue_for_pass2(duk_compiler_ctx *comp_ctx, duk_reg_t *out_stmt_value_reg);
+DUK_LOCAL_DECL void duk__init_varmap_and_prologue_for_pass2(duk_compiler_ctx *comp_ctx, duk_regconst_t *out_stmt_value_reg);
DUK_LOCAL_DECL void duk__convert_to_func_template(duk_compiler_ctx *comp_ctx);
DUK_LOCAL_DECL duk_int_t duk__cleanup_varmap(duk_compiler_ctx *comp_ctx);
@@ -62464,13 +63948,13 @@ DUK_LOCAL_DECL void duk__emit_a_b(duk_compiler_ctx *comp_ctx, duk_small_uint_t o
DUK_LOCAL_DECL void duk__emit_b_c(duk_compiler_ctx *comp_ctx, duk_small_uint_t op_flags, duk_regconst_t b, duk_regconst_t c);
#if 0 /* unused */
DUK_LOCAL_DECL void duk__emit_a(duk_compiler_ctx *comp_ctx, duk_small_uint_t op_flags, duk_regconst_t a);
-#endif
DUK_LOCAL_DECL void duk__emit_b(duk_compiler_ctx *comp_ctx, duk_small_uint_t op_flags, duk_regconst_t b);
+#endif
DUK_LOCAL_DECL void duk__emit_a_bc(duk_compiler_ctx *comp_ctx, duk_small_uint_t op_flags, duk_regconst_t a, duk_regconst_t bc);
DUK_LOCAL_DECL void duk__emit_bc(duk_compiler_ctx *comp_ctx, duk_small_uint_t op, duk_regconst_t bc);
DUK_LOCAL_DECL void duk__emit_abc(duk_compiler_ctx *comp_ctx, duk_small_uint_t op, duk_regconst_t abc);
-DUK_LOCAL_DECL void duk__emit_load_int32(duk_compiler_ctx *comp_ctx, duk_reg_t reg, duk_int32_t val);
-DUK_LOCAL_DECL void duk__emit_load_int32_noshuffle(duk_compiler_ctx *comp_ctx, duk_reg_t reg, duk_int32_t val);
+DUK_LOCAL_DECL void duk__emit_load_int32(duk_compiler_ctx *comp_ctx, duk_regconst_t reg, duk_int32_t val);
+DUK_LOCAL_DECL void duk__emit_load_int32_noshuffle(duk_compiler_ctx *comp_ctx, duk_regconst_t reg, duk_int32_t val);
DUK_LOCAL_DECL void duk__emit_jump(duk_compiler_ctx *comp_ctx, duk_int_t target_pc);
DUK_LOCAL_DECL duk_int_t duk__emit_jump_empty(duk_compiler_ctx *comp_ctx);
DUK_LOCAL_DECL void duk__insert_jump_entry(duk_compiler_ctx *comp_ctx, duk_int_t jump_pc);
@@ -62488,41 +63972,41 @@ DUK_LOCAL_DECL void duk__ivalue_var_fromstack(duk_compiler_ctx *comp_ctx, duk_iv
DUK_LOCAL_DECL void duk__ivalue_var_hstring(duk_compiler_ctx *comp_ctx, duk_ivalue *x, duk_hstring *h);
DUK_LOCAL_DECL void duk__copy_ispec(duk_compiler_ctx *comp_ctx, duk_ispec *src, duk_ispec *dst);
DUK_LOCAL_DECL void duk__copy_ivalue(duk_compiler_ctx *comp_ctx, duk_ivalue *src, duk_ivalue *dst);
-DUK_LOCAL_DECL duk_reg_t duk__alloctemps(duk_compiler_ctx *comp_ctx, duk_small_int_t num);
-DUK_LOCAL_DECL duk_reg_t duk__alloctemp(duk_compiler_ctx *comp_ctx);
-DUK_LOCAL_DECL void duk__settemp_checkmax(duk_compiler_ctx *comp_ctx, duk_reg_t temp_next);
+DUK_LOCAL_DECL duk_regconst_t duk__alloctemps(duk_compiler_ctx *comp_ctx, duk_small_int_t num);
+DUK_LOCAL_DECL duk_regconst_t duk__alloctemp(duk_compiler_ctx *comp_ctx);
+DUK_LOCAL_DECL void duk__settemp_checkmax(duk_compiler_ctx *comp_ctx, duk_regconst_t temp_next);
DUK_LOCAL_DECL duk_regconst_t duk__getconst(duk_compiler_ctx *comp_ctx);
DUK_LOCAL_DECL
duk_regconst_t duk__ispec_toregconst_raw(duk_compiler_ctx *comp_ctx,
duk_ispec *x,
- duk_reg_t forced_reg,
+ duk_regconst_t forced_reg,
duk_small_uint_t flags);
-DUK_LOCAL_DECL void duk__ispec_toforcedreg(duk_compiler_ctx *comp_ctx, duk_ispec *x, duk_reg_t forced_reg);
-DUK_LOCAL_DECL void duk__ivalue_toplain_raw(duk_compiler_ctx *comp_ctx, duk_ivalue *x, duk_reg_t forced_reg);
+DUK_LOCAL_DECL void duk__ispec_toforcedreg(duk_compiler_ctx *comp_ctx, duk_ispec *x, duk_regconst_t forced_reg);
+DUK_LOCAL_DECL void duk__ivalue_toplain_raw(duk_compiler_ctx *comp_ctx, duk_ivalue *x, duk_regconst_t forced_reg);
DUK_LOCAL_DECL void duk__ivalue_toplain(duk_compiler_ctx *comp_ctx, duk_ivalue *x);
DUK_LOCAL_DECL void duk__ivalue_toplain_ignore(duk_compiler_ctx *comp_ctx, duk_ivalue *x);
DUK_LOCAL_DECL
duk_regconst_t duk__ivalue_toregconst_raw(duk_compiler_ctx *comp_ctx,
duk_ivalue *x,
- duk_reg_t forced_reg,
+ duk_regconst_t forced_reg,
duk_small_uint_t flags);
-DUK_LOCAL_DECL duk_reg_t duk__ivalue_toreg(duk_compiler_ctx *comp_ctx, duk_ivalue *x);
+DUK_LOCAL_DECL duk_regconst_t duk__ivalue_toreg(duk_compiler_ctx *comp_ctx, duk_ivalue *x);
#if 0 /* unused */
-DUK_LOCAL_DECL duk_reg_t duk__ivalue_totemp(duk_compiler_ctx *comp_ctx, duk_ivalue *x);
+DUK_LOCAL_DECL duk_regconst_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);
-DUK_LOCAL_DECL duk_bool_t duk__lookup_lhs(duk_compiler_ctx *ctx, duk_reg_t *out_reg_varbind, duk_regconst_t *out_rc_varname);
+DUK_LOCAL_DECL duk_regconst_t duk__lookup_active_register_binding(duk_compiler_ctx *comp_ctx);
+DUK_LOCAL_DECL duk_bool_t duk__lookup_lhs(duk_compiler_ctx *ctx, duk_regconst_t *out_reg_varbind, duk_regconst_t *out_rc_varname);
/* label handling */
DUK_LOCAL_DECL void duk__add_label(duk_compiler_ctx *comp_ctx, duk_hstring *h_label, duk_int_t pc_label, duk_int_t label_id);
DUK_LOCAL_DECL void duk__update_label_flags(duk_compiler_ctx *comp_ctx, duk_int_t label_id, duk_small_uint_t flags);
DUK_LOCAL_DECL void duk__lookup_active_label(duk_compiler_ctx *comp_ctx, duk_hstring *h_label, duk_bool_t is_break, duk_int_t *out_label_id, duk_int_t *out_label_catch_depth, duk_int_t *out_label_pc, duk_bool_t *out_is_closest);
-DUK_LOCAL_DECL void duk__reset_labels_to_length(duk_compiler_ctx *comp_ctx, duk_int_t len);
+DUK_LOCAL_DECL void duk__reset_labels_to_length(duk_compiler_ctx *comp_ctx, duk_size_t len);
/* top-down expression parser */
DUK_LOCAL_DECL void duk__expr_nud(duk_compiler_ctx *comp_ctx, duk_ivalue *res);
@@ -62536,23 +64020,23 @@ DUK_LOCAL_DECL void duk__exprtop(duk_compiler_ctx *ctx, duk_ivalue *res, duk_sma
/* 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);
+DUK_LOCAL_DECL duk_regconst_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_totemp(duk_compiler_ctx *comp_ctx, duk_ivalue *res, duk_small_uint_t rbp_flags);
+DUK_LOCAL_DECL duk_regconst_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 void duk__expr_toforcedreg(duk_compiler_ctx *comp_ctx, duk_ivalue *res, duk_small_uint_t rbp_flags, duk_regconst_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);
+DUK_LOCAL_DECL duk_regconst_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_totemp(duk_compiler_ctx *comp_ctx, duk_ivalue *res, duk_small_uint_t rbp_flags);
+DUK_LOCAL_DECL duk_regconst_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 void duk__exprtop_toforcedreg(duk_compiler_ctx *comp_ctx, duk_ivalue *res, duk_small_uint_t rbp_flags, duk_regconst_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);
#if 0 /* unused */
DUK_LOCAL_DECL void duk__exprtop_toplain_ignore(duk_compiler_ctx *comp_ctx, duk_ivalue *res, duk_small_uint_t rbp_flags);
@@ -62564,7 +64048,7 @@ DUK_LOCAL_DECL void duk__nud_array_literal(duk_compiler_ctx *comp_ctx, duk_ivalu
DUK_LOCAL_DECL void duk__nud_object_literal(duk_compiler_ctx *comp_ctx, duk_ivalue *res);
/* statement parsing */
-DUK_LOCAL_DECL void duk__parse_var_decl(duk_compiler_ctx *comp_ctx, duk_ivalue *res, duk_small_uint_t expr_flags, duk_reg_t *out_reg_varbind, duk_regconst_t *out_rc_varname);
+DUK_LOCAL_DECL void duk__parse_var_decl(duk_compiler_ctx *comp_ctx, duk_ivalue *res, duk_small_uint_t expr_flags, duk_regconst_t *out_reg_varbind, duk_regconst_t *out_rc_varname);
DUK_LOCAL_DECL void duk__parse_var_stmt(duk_compiler_ctx *comp_ctx, duk_ivalue *res, duk_small_uint_t expr_flags);
DUK_LOCAL_DECL void duk__parse_for_stmt(duk_compiler_ctx *comp_ctx, duk_ivalue *res, duk_int_t pc_label_site);
DUK_LOCAL_DECL void duk__parse_switch_stmt(duk_compiler_ctx *comp_ctx, duk_ivalue *res, duk_int_t pc_label_site);
@@ -62631,7 +64115,7 @@ DUK_LOCAL_DECL duk_int_t duk__parse_func_like_fnum(duk_compiler_ctx *comp_ctx, d
#define DUK__TOKEN_LBP_BP_MASK 0x1f
#define DUK__TOKEN_LBP_FLAG_NO_REGEXP (1 << 5) /* regexp literal must not follow this token */
#define DUK__TOKEN_LBP_FLAG_TERMINATES (1 << 6) /* terminates expression; e.g. post-increment/-decrement */
-#define DUK__TOKEN_LBP_FLAG_UNUSED (1 << 7) /* spare */
+#define DUK__TOKEN_LBP_FLAG_UNUSED (1 << 7) /* unused */
#define DUK__TOKEN_LBP_GET_BP(x) ((duk_small_uint_t) (((x) & DUK__TOKEN_LBP_BP_MASK) * 2))
@@ -62747,7 +64231,7 @@ DUK_LOCAL const duk_uint8_t duk__token_lbp[] = {
* Misc helpers
*/
-DUK_LOCAL void duk__recursion_increase(duk_compiler_ctx *comp_ctx) {
+DUK_LOCAL void duk__comp_recursion_increase(duk_compiler_ctx *comp_ctx) {
DUK_ASSERT(comp_ctx != NULL);
DUK_ASSERT(comp_ctx->recursion_depth >= 0);
if (comp_ctx->recursion_depth >= comp_ctx->recursion_limit) {
@@ -62756,7 +64240,7 @@ DUK_LOCAL void duk__recursion_increase(duk_compiler_ctx *comp_ctx) {
comp_ctx->recursion_depth++;
}
-DUK_LOCAL void duk__recursion_decrease(duk_compiler_ctx *comp_ctx) {
+DUK_LOCAL void duk__comp_recursion_decrease(duk_compiler_ctx *comp_ctx) {
DUK_ASSERT(comp_ctx != NULL);
DUK_ASSERT(comp_ctx->recursion_depth > 0);
comp_ctx->recursion_depth--;
@@ -62784,10 +64268,10 @@ DUK_LOCAL duk_bool_t duk__hstring_is_eval_or_arguments_in_strict_mode(duk_compil
DUK_LOCAL void duk__advance_helper(duk_compiler_ctx *comp_ctx, duk_small_int_t expect) {
duk_hthread *thr = comp_ctx->thr;
- duk_context *ctx = (duk_context *) thr;
duk_bool_t regexp;
- DUK_ASSERT(comp_ctx->curr_token.t >= 0 && comp_ctx->curr_token.t <= DUK_TOK_MAXVAL); /* MAXVAL is inclusive */
+ DUK_ASSERT_DISABLE(comp_ctx->curr_token.t >= 0); /* unsigned */
+ DUK_ASSERT(comp_ctx->curr_token.t <= DUK_TOK_MAXVAL); /* MAXVAL is inclusive */
/*
* Use current token to decide whether a RegExp can follow.
@@ -62807,7 +64291,7 @@ DUK_LOCAL void duk__advance_helper(duk_compiler_ctx *comp_ctx, duk_small_int_t e
regexp = 0;
}
- if (expect >= 0 && comp_ctx->curr_token.t != expect) {
+ if (expect >= 0 && comp_ctx->curr_token.t != (duk_small_uint_t) expect) {
DUK_D(DUK_DPRINT("parse error: expect=%ld, got=%ld",
(long) expect, (long) comp_ctx->curr_token.t));
DUK_ERROR_SYNTAX(thr, DUK_STR_PARSE_ERROR);
@@ -62815,8 +64299,8 @@ DUK_LOCAL void duk__advance_helper(duk_compiler_ctx *comp_ctx, duk_small_int_t e
/* make current token the previous; need to fiddle with valstack "backing store" */
DUK_MEMCPY(&comp_ctx->prev_token, &comp_ctx->curr_token, sizeof(duk_token));
- duk_copy(ctx, comp_ctx->tok11_idx, comp_ctx->tok21_idx);
- duk_copy(ctx, comp_ctx->tok12_idx, comp_ctx->tok22_idx);
+ duk_copy(thr, comp_ctx->tok11_idx, comp_ctx->tok21_idx);
+ duk_copy(thr, comp_ctx->tok12_idx, comp_ctx->tok22_idx);
/* parse new token */
duk_lexer_parse_js_input_element(&comp_ctx->lex,
@@ -62830,14 +64314,14 @@ DUK_LOCAL void duk__advance_helper(duk_compiler_ctx *comp_ctx, duk_small_int_t e
(long) comp_ctx->curr_token.t_nores,
(long) comp_ctx->curr_token.start_line,
(long) comp_ctx->curr_token.lineterm,
- (duk_tval *) duk_get_tval(ctx, comp_ctx->tok11_idx),
- (duk_tval *) duk_get_tval(ctx, comp_ctx->tok12_idx),
+ (duk_tval *) duk_get_tval(thr, comp_ctx->tok11_idx),
+ (duk_tval *) duk_get_tval(thr, comp_ctx->tok12_idx),
(long) comp_ctx->prev_token.t,
(long) comp_ctx->prev_token.t_nores,
(long) comp_ctx->prev_token.start_line,
(long) comp_ctx->prev_token.lineterm,
- (duk_tval *) duk_get_tval(ctx, comp_ctx->tok21_idx),
- (duk_tval *) duk_get_tval(ctx, comp_ctx->tok22_idx)));
+ (duk_tval *) duk_get_tval(thr, comp_ctx->tok21_idx),
+ (duk_tval *) duk_get_tval(thr, comp_ctx->tok22_idx)));
}
/* advance, expecting current token to be a specific token; parse next token in regexp context */
@@ -62858,10 +64342,9 @@ DUK_LOCAL void duk__advance(duk_compiler_ctx *comp_ctx) {
DUK_LOCAL void duk__init_func_valstack_slots(duk_compiler_ctx *comp_ctx) {
duk_compiler_func *func = &comp_ctx->curr_func;
duk_hthread *thr = comp_ctx->thr;
- duk_context *ctx = (duk_context *) thr;
duk_idx_t entry_top;
- entry_top = duk_get_top(ctx);
+ entry_top = duk_get_top(thr);
DUK_MEMZERO(func, sizeof(*func)); /* intentional overlap with earlier memzero */
#if defined(DUK_USE_EXPLICIT_NULL_INIT)
@@ -62875,46 +64358,46 @@ DUK_LOCAL void duk__init_func_valstack_slots(duk_compiler_ctx *comp_ctx) {
func->h_varmap = NULL;
#endif
- duk_require_stack(ctx, DUK__FUNCTION_INIT_REQUIRE_SLOTS);
+ duk_require_stack(thr, DUK__FUNCTION_INIT_REQUIRE_SLOTS);
DUK_BW_INIT_PUSHBUF(thr, &func->bw_code, DUK__BC_INITIAL_INSTS * sizeof(duk_compiler_instr));
/* code_idx = entry_top + 0 */
- duk_push_array(ctx);
+ duk_push_array(thr);
func->consts_idx = entry_top + 1;
- func->h_consts = DUK_GET_HOBJECT_POSIDX(ctx, entry_top + 1);
+ func->h_consts = DUK_GET_HOBJECT_POSIDX(thr, entry_top + 1);
DUK_ASSERT(func->h_consts != NULL);
- duk_push_array(ctx);
+ duk_push_array(thr);
func->funcs_idx = entry_top + 2;
- func->h_funcs = DUK_GET_HOBJECT_POSIDX(ctx, entry_top + 2);
+ func->h_funcs = DUK_GET_HOBJECT_POSIDX(thr, entry_top + 2);
DUK_ASSERT(func->h_funcs != NULL);
DUK_ASSERT(func->fnum_next == 0);
- duk_push_array(ctx);
+ duk_push_array(thr);
func->decls_idx = entry_top + 3;
- func->h_decls = DUK_GET_HOBJECT_POSIDX(ctx, entry_top + 3);
+ func->h_decls = DUK_GET_HOBJECT_POSIDX(thr, entry_top + 3);
DUK_ASSERT(func->h_decls != NULL);
- duk_push_array(ctx);
+ duk_push_array(thr);
func->labelnames_idx = entry_top + 4;
- func->h_labelnames = DUK_GET_HOBJECT_POSIDX(ctx, entry_top + 4);
+ func->h_labelnames = DUK_GET_HOBJECT_POSIDX(thr, entry_top + 4);
DUK_ASSERT(func->h_labelnames != NULL);
- duk_push_dynamic_buffer(ctx, 0);
+ duk_push_dynamic_buffer(thr, 0);
func->labelinfos_idx = entry_top + 5;
- func->h_labelinfos = (duk_hbuffer_dynamic *) duk_known_hbuffer(ctx, entry_top + 5);
+ func->h_labelinfos = (duk_hbuffer_dynamic *) duk_known_hbuffer(thr, entry_top + 5);
DUK_ASSERT(func->h_labelinfos != NULL);
DUK_ASSERT(DUK_HBUFFER_HAS_DYNAMIC(func->h_labelinfos) && !DUK_HBUFFER_HAS_EXTERNAL(func->h_labelinfos));
- duk_push_array(ctx);
+ duk_push_array(thr);
func->argnames_idx = entry_top + 6;
- func->h_argnames = DUK_GET_HOBJECT_POSIDX(ctx, entry_top + 6);
+ func->h_argnames = DUK_GET_HOBJECT_POSIDX(thr, entry_top + 6);
DUK_ASSERT(func->h_argnames != NULL);
- duk_push_bare_object(ctx);
+ duk_push_bare_object(thr);
func->varmap_idx = entry_top + 7;
- func->h_varmap = DUK_GET_HOBJECT_POSIDX(ctx, entry_top + 7);
+ func->h_varmap = DUK_GET_HOBJECT_POSIDX(thr, entry_top + 7);
DUK_ASSERT(func->h_varmap != NULL);
}
@@ -62922,25 +64405,24 @@ DUK_LOCAL void duk__init_func_valstack_slots(duk_compiler_ctx *comp_ctx) {
DUK_LOCAL void duk__reset_func_for_pass2(duk_compiler_ctx *comp_ctx) {
duk_compiler_func *func = &comp_ctx->curr_func;
duk_hthread *thr = comp_ctx->thr;
- duk_context *ctx = (duk_context *) thr;
/* reset bytecode buffer but keep current size; pass 2 will
* require same amount or more.
*/
DUK_BW_RESET_SIZE(thr, &func->bw_code);
- duk_set_length(ctx, func->consts_idx, 0);
+ duk_set_length(thr, func->consts_idx, 0);
/* keep func->h_funcs; inner functions are not reparsed to avoid O(depth^2) parsing */
func->fnum_next = 0;
- /* duk_set_length(ctx, func->funcs_idx, 0); */
- duk_set_length(ctx, func->labelnames_idx, 0);
+ /* duk_set_length(thr, func->funcs_idx, 0); */
+ duk_set_length(thr, func->labelnames_idx, 0);
duk_hbuffer_reset(thr, func->h_labelinfos);
/* keep func->h_argnames; it is fixed for all passes */
/* truncated in case pass 3 needed */
- duk_push_bare_object(ctx);
- duk_replace(ctx, func->varmap_idx);
- func->h_varmap = DUK_GET_HOBJECT_POSIDX(ctx, func->varmap_idx);
+ duk_push_bare_object(thr);
+ duk_replace(thr, func->varmap_idx);
+ func->h_varmap = DUK_GET_HOBJECT_POSIDX(thr, func->varmap_idx);
DUK_ASSERT(func->h_varmap != NULL);
}
@@ -62949,7 +64431,6 @@ DUK_LOCAL void duk__reset_func_for_pass2(duk_compiler_ctx *comp_ctx) {
*/
DUK_LOCAL duk_int_t duk__cleanup_varmap(duk_compiler_ctx *comp_ctx) {
duk_hthread *thr = comp_ctx->thr;
- duk_context *ctx = (duk_context *) thr;
duk_hobject *h_varmap;
duk_hstring *h_key;
duk_tval *tv;
@@ -62958,7 +64439,7 @@ DUK_LOCAL duk_int_t duk__cleanup_varmap(duk_compiler_ctx *comp_ctx) {
/* [ ... varmap ] */
- h_varmap = DUK_GET_HOBJECT_NEGIDX(ctx, -1);
+ h_varmap = DUK_GET_HOBJECT_NEGIDX(thr, -1);
DUK_ASSERT(h_varmap != NULL);
ret = 0;
@@ -62989,7 +64470,7 @@ DUK_LOCAL duk_int_t duk__cleanup_varmap(duk_compiler_ctx *comp_ctx) {
}
}
- duk_compact_m1(ctx);
+ duk_compact_m1(thr);
return ret;
}
@@ -63001,7 +64482,6 @@ DUK_LOCAL duk_int_t duk__cleanup_varmap(duk_compiler_ctx *comp_ctx) {
DUK_LOCAL void duk__convert_to_func_template(duk_compiler_ctx *comp_ctx) {
duk_compiler_func *func = &comp_ctx->curr_func;
duk_hthread *thr = comp_ctx->thr;
- duk_context *ctx = (duk_context *) thr;
duk_hcompfunc *h_res;
duk_hbuffer_fixed *h_data;
duk_size_t consts_count;
@@ -63029,7 +64509,7 @@ DUK_LOCAL void duk__convert_to_func_template(duk_compiler_ctx *comp_ctx) {
/* Valstack should suffice here, required on function valstack init */
- h_res = duk_push_hcompfunc(ctx);
+ h_res = duk_push_hcompfunc(thr);
DUK_ASSERT(h_res != NULL);
DUK_ASSERT(DUK_HOBJECT_GET_PROTOTYPE(thr->heap, (duk_hobject *) h_res) == thr->builtins[DUK_BIDX_FUNCTION_PROTOTYPE]);
DUK_HOBJECT_SET_PROTOTYPE_UPDREF(thr, (duk_hobject *) h_res, NULL); /* Function templates are "bare objects". */
@@ -63112,8 +64592,8 @@ DUK_LOCAL void duk__convert_to_func_template(duk_compiler_ctx *comp_ctx) {
(long) funcs_count, (long) sizeof(duk_hobject *),
(long) code_size, (long) data_size));
- duk_push_fixed_buffer_nozero(ctx, data_size);
- h_data = (duk_hbuffer_fixed *) duk_known_hbuffer(ctx, -1);
+ duk_push_fixed_buffer_nozero(thr, data_size);
+ h_data = (duk_hbuffer_fixed *) duk_known_hbuffer(thr, -1);
DUK_HCOMPFUNC_SET_DATA(thr->heap, h_res, (duk_hbuffer *) h_data);
DUK_HEAPHDR_INCREF(thr, h_data);
@@ -63160,7 +64640,7 @@ DUK_LOCAL void duk__convert_to_func_template(duk_compiler_ctx *comp_ctx) {
DUK_ASSERT((duk_uint8_t *) (p_instr + code_count) == DUK_HBUFFER_FIXED_GET_DATA_PTR(thr->heap, h_data) + data_size);
- duk_pop(ctx); /* 'data' (and everything in it) is reachable through h_res now */
+ duk_pop(thr); /* 'data' (and everything in it) is reachable through h_res now */
/*
* Init non-property result fields
@@ -63217,16 +64697,16 @@ DUK_LOCAL void duk__convert_to_func_template(duk_compiler_ctx *comp_ctx) {
if (keep_varmap) {
duk_int_t num_used;
- duk_dup(ctx, func->varmap_idx);
+ duk_dup(thr, func->varmap_idx);
num_used = duk__cleanup_varmap(comp_ctx);
DUK_DDD(DUK_DDDPRINT("cleaned up varmap: %!T (num_used=%ld)",
- (duk_tval *) duk_get_tval(ctx, -1), (long) num_used));
+ (duk_tval *) duk_get_tval(thr, -1), (long) num_used));
if (num_used > 0) {
- duk_xdef_prop_stridx_short(ctx, -2, DUK_STRIDX_INT_VARMAP, DUK_PROPDESC_FLAGS_NONE);
+ duk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_INT_VARMAP, DUK_PROPDESC_FLAGS_NONE);
} else {
DUK_DD(DUK_DDPRINT("varmap is empty after cleanup -> no need to add"));
- duk_pop(ctx);
+ duk_pop(thr);
}
}
@@ -63242,7 +64722,7 @@ DUK_LOCAL void duk__convert_to_func_template(duk_compiler_ctx *comp_ctx) {
DUK_DD(DUK_DDPRINT("keeping _Formals because debugger support is enabled"));
keep_formals = 1;
#else
- formals_length = duk_get_length(ctx, func->argnames_idx);
+ formals_length = duk_get_length(thr, func->argnames_idx);
if (formals_length != (duk_size_t) h_res->nargs) {
/* Nargs not enough for closure .length: keep _Formals regardless
* of its length. Shouldn't happen in practice at the moment.
@@ -63263,16 +64743,16 @@ DUK_LOCAL void duk__convert_to_func_template(duk_compiler_ctx *comp_ctx) {
#endif
if (keep_formals) {
- duk_dup(ctx, func->argnames_idx);
- duk_xdef_prop_stridx_short(ctx, -2, DUK_STRIDX_INT_FORMALS, DUK_PROPDESC_FLAGS_NONE);
+ duk_dup(thr, func->argnames_idx);
+ duk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_INT_FORMALS, DUK_PROPDESC_FLAGS_NONE);
}
/* name */
#if defined(DUK_USE_FUNC_NAME_PROPERTY)
if (func->h_name) {
- duk_push_hstring(ctx, func->h_name);
- DUK_DD(DUK_DDPRINT("setting function template .name to %!T", duk_get_tval(ctx, -1)));
- duk_xdef_prop_stridx_short(ctx, -2, DUK_STRIDX_NAME, DUK_PROPDESC_FLAGS_NONE);
+ duk_push_hstring(thr, func->h_name);
+ DUK_DD(DUK_DDPRINT("setting function template .name to %!T", duk_get_tval(thr, -1)));
+ duk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_NAME, DUK_PROPDESC_FLAGS_NONE);
}
#endif /* DUK_USE_FUNC_NAME_PROPERTY */
@@ -63318,8 +64798,8 @@ DUK_LOCAL void duk__convert_to_func_template(duk_compiler_ctx *comp_ctx) {
*/
#if 0
- duk_push_string(ctx, "XXX");
- duk_xdef_prop_stridx_short(ctx, -2, DUK_STRIDX_INT_SOURCE, DUK_PROPDESC_FLAGS_NONE);
+ duk_push_string(thr, "XXX");
+ duk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_INT_SOURCE, DUK_PROPDESC_FLAGS_NONE);
#endif
}
#endif /* DUK_USE_NONSTD_FUNC_SOURCE_PROPERTY */
@@ -63333,7 +64813,7 @@ DUK_LOCAL void duk__convert_to_func_template(duk_compiler_ctx *comp_ctx) {
DUK_ASSERT(code_count <= DUK_COMPILER_MAX_BYTECODE_LENGTH);
duk_hobject_pc2line_pack(thr, q_instr, (duk_uint_fast32_t) code_count); /* -> pushes fixed buffer */
- duk_xdef_prop_stridx_short(ctx, -2, DUK_STRIDX_INT_PC2LINE, DUK_PROPDESC_FLAGS_NONE);
+ duk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_INT_PC2LINE, DUK_PROPDESC_FLAGS_NONE);
/* XXX: if assertions enabled, walk through all valid PCs
* and check line mapping.
@@ -63348,19 +64828,19 @@ DUK_LOCAL void duk__convert_to_func_template(duk_compiler_ctx *comp_ctx) {
* Source filename (or equivalent), for identifying thrown errors.
*/
- duk_push_hstring(ctx, comp_ctx->h_filename);
- duk_xdef_prop_stridx_short(ctx, -2, DUK_STRIDX_FILE_NAME, DUK_PROPDESC_FLAGS_NONE);
+ duk_push_hstring(thr, comp_ctx->h_filename);
+ duk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_FILE_NAME, DUK_PROPDESC_FLAGS_NONE);
}
#endif
DUK_DD(DUK_DDPRINT("converted function: %!ixT",
- (duk_tval *) duk_get_tval(ctx, -1)));
+ (duk_tval *) duk_get_tval(thr, -1)));
/*
* Compact the function template.
*/
- duk_compact_m1(ctx);
+ duk_compact_m1(thr);
/*
* Debug dumping
@@ -63371,7 +64851,7 @@ DUK_LOCAL void duk__convert_to_func_template(duk_compiler_ctx *comp_ctx) {
duk_hcompfunc *h;
duk_instr_t *p, *p_start, *p_end;
- h = (duk_hcompfunc *) duk_get_hobject(ctx, -1);
+ h = (duk_hcompfunc *) duk_get_hobject(thr, -1);
p_start = (duk_instr_t *) DUK_HCOMPFUNC_GET_CODE_BASE(thr->heap, h);
p_end = (duk_instr_t *) DUK_HCOMPFUNC_GET_CODE_END(thr->heap, h);
@@ -63485,7 +64965,7 @@ DUK_LOCAL void duk__emit(duk_compiler_ctx *comp_ctx, duk_instr_t ins) {
instr->ins = ins;
#if defined(DUK_USE_PC2LINE)
- instr->line = line;
+ instr->line = (duk_uint32_t) line;
#endif
#if defined(DUK_USE_DEBUGGER_SUPPORT)
if (line < comp_ctx->curr_func.min_line) {
@@ -63554,7 +65034,7 @@ DUK_LOCAL void duk__emit_a_b_c(duk_compiler_ctx *comp_ctx, duk_small_uint_t op_f
duk_int_t b_out = -1;
duk_int_t c_out = -1;
duk_int_t tmp;
- duk_small_int_t op = op_flags & 0xff;
+ duk_small_uint_t op = op_flags & 0xffU;
DUK_DDD(DUK_DDDPRINT("emit: op_flags=%04lx, a=%ld, b=%ld, c=%ld",
(unsigned long) op_flags, (long) a, (long) b, (long) c));
@@ -63568,6 +65048,9 @@ DUK_LOCAL void duk__emit_a_b_c(duk_compiler_ctx *comp_ctx, duk_small_uint_t op_f
DUK_ASSERT_DISABLE((op_flags & 0xff) >= DUK_BC_OP_MIN); /* unsigned */
DUK_ASSERT((op_flags & 0xff) <= DUK_BC_OP_MAX);
+ DUK_ASSERT(DUK__ISREG(a));
+ DUK_ASSERT(b != -1); /* Not 'none'. */
+ DUK_ASSERT(c != -1); /* Not 'none'. */
/* Input shuffling happens before the actual operation, while output
* shuffling happens afterwards. Output shuffling decisions are still
@@ -63599,7 +65082,7 @@ DUK_LOCAL void duk__emit_a_b_c(duk_compiler_ctx *comp_ctx, duk_small_uint_t op_f
* consecutive.
*/
DUK_ASSERT((comp_ctx->curr_func.shuffle1 == 0 && comp_ctx->curr_func.shuffle2 == 0) ||
- comp_ctx->curr_func.shuffle2 == comp_ctx->curr_func.shuffle1 + 1);
+ (comp_ctx->curr_func.shuffle2 == comp_ctx->curr_func.shuffle1 + 1));
if (op == DUK_OP_CSVAR) {
/* For CSVAR the limit is one smaller because output shuffle
* must be able to express 'a + 1' in BC.
@@ -63617,7 +65100,7 @@ DUK_LOCAL void duk__emit_a_b_c(duk_compiler_ctx *comp_ctx, duk_small_uint_t op_f
/* Slot B: reg/const support, mapped to bit 0 of opcode. */
- if (b & DUK__CONST_MARKER) {
+ if ((b & DUK__CONST_MARKER) != 0) {
DUK_ASSERT((op_flags & DUK__EMIT_FLAG_NO_SHUFFLE_B) == 0);
DUK_ASSERT((op_flags & DUK__EMIT_FLAG_B_IS_TARGET) == 0);
b = b & ~DUK__CONST_MARKER;
@@ -63687,7 +65170,7 @@ DUK_LOCAL void duk__emit_a_b_c(duk_compiler_ctx *comp_ctx, duk_small_uint_t op_f
/* Slot C: reg/const support, mapped to bit 1 of opcode. */
- if (c & DUK__CONST_MARKER) {
+ if ((c & DUK__CONST_MARKER) != 0) {
DUK_ASSERT((op_flags & DUK__EMIT_FLAG_NO_SHUFFLE_C) == 0);
DUK_ASSERT((op_flags & DUK__EMIT_FLAG_C_IS_TARGET) == 0);
c = c & ~DUK__CONST_MARKER;
@@ -63743,11 +65226,11 @@ DUK_LOCAL void duk__emit_a_b_c(duk_compiler_ctx *comp_ctx, duk_small_uint_t op_f
/* Main operation */
- DUK_ASSERT_DISABLE(a >= DUK_BC_A_MIN); /* unsigned */
+ DUK_ASSERT(a >= DUK_BC_A_MIN);
DUK_ASSERT(a <= DUK_BC_A_MAX);
- DUK_ASSERT_DISABLE(b >= DUK_BC_B_MIN); /* unsigned */
+ DUK_ASSERT(b >= DUK_BC_B_MIN);
DUK_ASSERT(b <= DUK_BC_B_MAX);
- DUK_ASSERT_DISABLE(c >= DUK_BC_C_MIN); /* unsigned */
+ DUK_ASSERT(c >= DUK_BC_C_MIN);
DUK_ASSERT(c <= DUK_BC_C_MAX);
ins |= DUK_ENC_OP_A_B_C(op_flags & 0xff, a, b, c);
@@ -63832,23 +65315,26 @@ DUK_LOCAL void duk__emit_a(duk_compiler_ctx *comp_ctx, int op_flags, int a) {
}
#endif
+#if 0 /* unused */
DUK_LOCAL void duk__emit_b(duk_compiler_ctx *comp_ctx, duk_small_uint_t op_flags, duk_regconst_t b) {
#if defined(DUK_USE_SHUFFLE_TORTURE)
op_flags |= DUK__EMIT_FLAG_NO_SHUFFLE_A | DUK__EMIT_FLAG_NO_SHUFFLE_C;
#endif
duk__emit_a_b_c(comp_ctx, op_flags, 0, b, 0);
}
+#endif
DUK_LOCAL void duk__emit_a_bc(duk_compiler_ctx *comp_ctx, duk_small_uint_t op_flags, duk_regconst_t a, duk_regconst_t bc) {
duk_instr_t ins;
duk_int_t tmp;
/* allow caller to give a const number with the DUK__CONST_MARKER */
+ DUK_ASSERT(bc != -1); /* Not 'none'. */
bc = bc & (~DUK__CONST_MARKER);
DUK_ASSERT_DISABLE((op_flags & 0xff) >= DUK_BC_OP_MIN); /* unsigned */
DUK_ASSERT((op_flags & 0xff) <= DUK_BC_OP_MAX);
- DUK_ASSERT_DISABLE(bc >= DUK_BC_BC_MIN); /* unsigned */
+ DUK_ASSERT(bc >= DUK_BC_BC_MIN);
DUK_ASSERT(bc <= DUK_BC_BC_MAX);
DUK_ASSERT((bc & DUK__CONST_MARKER) == 0);
@@ -63868,6 +65354,13 @@ DUK_LOCAL void duk__emit_a_bc(duk_compiler_ctx *comp_ctx, duk_small_uint_t op_fl
duk__emit(comp_ctx, ins);
} else if (op_flags & DUK__EMIT_FLAG_NO_SHUFFLE_A) {
goto error_outofregs;
+ } else if ((op_flags & 0xf0U) == DUK_OP_CALL0) {
+ comp_ctx->curr_func.needs_shuffle = 1;
+ tmp = comp_ctx->curr_func.shuffle1;
+ duk__emit_load_int32_noshuffle(comp_ctx, tmp, a);
+ op_flags |= DUK_BC_CALL_FLAG_INDIRECT;
+ ins = DUK_ENC_OP_A_BC(op_flags & 0xff, tmp, bc);
+ duk__emit(comp_ctx, ins);
} else if (a <= DUK_BC_BC_MAX) {
comp_ctx->curr_func.needs_shuffle = 1;
tmp = comp_ctx->curr_func.shuffle1;
@@ -63903,6 +65396,7 @@ DUK_LOCAL void duk__emit_abc(duk_compiler_ctx *comp_ctx, duk_small_uint_t op, du
DUK_ASSERT_DISABLE(abc >= DUK_BC_ABC_MIN); /* unsigned */
DUK_ASSERT(abc <= DUK_BC_ABC_MAX);
DUK_ASSERT((abc & DUK__CONST_MARKER) == 0);
+ DUK_ASSERT(abc != -1); /* Not 'none'. */
if (abc <= DUK_BC_ABC_MAX) {
;
@@ -63921,7 +65415,7 @@ DUK_LOCAL void duk__emit_abc(duk_compiler_ctx *comp_ctx, duk_small_uint_t op, du
DUK_ERROR_RANGE(comp_ctx->thr, DUK_STR_REG_LIMIT);
}
-DUK_LOCAL void duk__emit_load_int32_raw(duk_compiler_ctx *comp_ctx, duk_reg_t reg, duk_int32_t val, duk_small_uint_t op_flags) {
+DUK_LOCAL void duk__emit_load_int32_raw(duk_compiler_ctx *comp_ctx, duk_regconst_t reg, duk_int32_t val, duk_small_uint_t op_flags) {
/* XXX: Shuffling support could be implemented here so that LDINT+LDINTX
* would only shuffle once (instead of twice). The current code works
* though, and has a smaller compiler footprint.
@@ -63942,7 +65436,7 @@ DUK_LOCAL void duk__emit_load_int32_raw(duk_compiler_ctx *comp_ctx, duk_reg_t re
}
}
-DUK_LOCAL void duk__emit_load_int32(duk_compiler_ctx *comp_ctx, duk_reg_t reg, duk_int32_t val) {
+DUK_LOCAL void duk__emit_load_int32(duk_compiler_ctx *comp_ctx, duk_regconst_t reg, duk_int32_t val) {
duk__emit_load_int32_raw(comp_ctx, reg, val, 0 /*op_flags*/);
}
@@ -63950,11 +65444,11 @@ DUK_LOCAL void duk__emit_load_int32(duk_compiler_ctx *comp_ctx, duk_reg_t reg, d
/* Used by duk__emit*() calls so that we don't shuffle the loadints that
* are needed to handle indirect opcodes.
*/
-DUK_LOCAL void duk__emit_load_int32_noshuffle(duk_compiler_ctx *comp_ctx, duk_reg_t reg, duk_int32_t val) {
+DUK_LOCAL void duk__emit_load_int32_noshuffle(duk_compiler_ctx *comp_ctx, duk_regconst_t reg, duk_int32_t val) {
duk__emit_load_int32_raw(comp_ctx, reg, val, DUK__EMIT_FLAG_NO_SHUFFLE_A /*op_flags*/);
}
#else
-DUK_LOCAL void duk__emit_load_int32_noshuffle(duk_compiler_ctx *comp_ctx, duk_reg_t reg, duk_int32_t val) {
+DUK_LOCAL void duk__emit_load_int32_noshuffle(duk_compiler_ctx *comp_ctx, duk_regconst_t reg, duk_int32_t val) {
/* When torture not enabled, can just use the same helper because
* 'reg' won't get spilled.
*/
@@ -63992,7 +65486,8 @@ DUK_LOCAL void duk__insert_jump_entry(duk_compiler_ctx *comp_ctx, duk_int_t jump
duk_compiler_instr *instr;
duk_size_t offset;
- offset = jump_pc * sizeof(duk_compiler_instr),
+ DUK_ASSERT(jump_pc >= 0);
+ offset = (duk_size_t) jump_pc * sizeof(duk_compiler_instr);
instr = (duk_compiler_instr *) (void *)
DUK_BW_INSERT_ENSURE_AREA(comp_ctx->thr,
&comp_ctx->curr_func.bw_code,
@@ -64004,7 +65499,7 @@ DUK_LOCAL void duk__insert_jump_entry(duk_compiler_ctx *comp_ctx, duk_int_t jump
#endif
instr->ins = DUK_ENC_OP_ABC(DUK_OP_JUMP, 0);
#if defined(DUK_USE_PC2LINE)
- instr->line = line;
+ instr->line = (duk_uint32_t) line;
#endif
DUK_BW_ADD_PTR(comp_ctx->thr, &comp_ctx->curr_func.bw_code, sizeof(duk_compiler_instr));
@@ -64051,7 +65546,7 @@ DUK_LOCAL void duk__patch_jump_here(duk_compiler_ctx *comp_ctx, duk_int_t jump_p
DUK_LOCAL void duk__patch_trycatch(duk_compiler_ctx *comp_ctx, duk_int_t ldconst_pc, duk_int_t trycatch_pc, duk_regconst_t reg_catch, duk_regconst_t const_varname, duk_small_uint_t flags) {
duk_compiler_instr *instr;
- DUK_ASSERT((reg_catch & DUK__CONST_MARKER) == 0);
+ DUK_ASSERT(DUK__ISREG(reg_catch));
instr = duk__get_instr_ptr(comp_ctx, ldconst_pc);
DUK_ASSERT(DUK_DEC_OP(instr->ins) == DUK_OP_LDCONST);
@@ -64138,7 +65633,7 @@ DUK_LOCAL void duk__peephole_optimize_bytecode(duk_compiler_ctx *comp_ctx) {
continue;
}
- target_pc1 = i + 1 + DUK_DEC_ABC(ins) - DUK_BC_JUMP_BIAS;
+ target_pc1 = i + 1 + (duk_int_t) DUK_DEC_ABC(ins) - (duk_int_t) DUK_BC_JUMP_BIAS;
DUK_DDD(DUK_DDDPRINT("consider jump at pc %ld; target_pc=%ld", (long) i, (long) target_pc1));
DUK_ASSERT(target_pc1 >= 0);
DUK_ASSERT(target_pc1 < n);
@@ -64153,7 +65648,7 @@ DUK_LOCAL void duk__peephole_optimize_bytecode(duk_compiler_ctx *comp_ctx) {
continue;
}
- target_pc2 = target_pc1 + 1 + DUK_DEC_ABC(ins) - DUK_BC_JUMP_BIAS;
+ target_pc2 = target_pc1 + 1 + (duk_int_t) DUK_DEC_ABC(ins) - (duk_int_t) DUK_BC_JUMP_BIAS;
DUK_DDD(DUK_DDDPRINT("optimizing jump at pc %ld; old target is %ld -> new target is %ld",
(long) i, (long) target_pc1, (long) target_pc2));
@@ -64179,11 +65674,14 @@ DUK_LOCAL void duk__peephole_optimize_bytecode(duk_compiler_ctx *comp_ctx) {
* is not needed, the forced_reg argument suffices and generates better
* code (it is checked as it is used).
*/
+/* XXX: DUK__IVAL_FLAG_REQUIRE_SHORT is passed but not currently implemented
+ * by ispec/ivalue operations.
+ */
#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 (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) */
+/* XXX: some code might benefit from DUK__SETTEMP_IFTEMP(thr,x) */
#if 0 /* enable manually for dumping */
#define DUK__DUMP_ISPEC(compctx,ispec) do { duk__dump_ispec((compctx), (ispec)); } while (0)
@@ -64192,7 +65690,7 @@ DUK_LOCAL void duk__peephole_optimize_bytecode(duk_compiler_ctx *comp_ctx) {
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_get_tval(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 "
@@ -64200,9 +65698,9 @@ DUK_LOCAL void duk__dump_ivalue(duk_compiler_ctx *comp_ctx, duk_ivalue *x) {
"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),
+ duk_get_tval(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)));
+ duk_get_tval(comp_ctx->thr, x->x2.valstack_idx)));
}
#else
#define DUK__DUMP_ISPEC(comp_ctx,x) do {} while (0)
@@ -64212,50 +65710,46 @@ DUK_LOCAL void duk__dump_ivalue(duk_compiler_ctx *comp_ctx, duk_ivalue *x) {
DUK_LOCAL void duk__ivalue_regconst(duk_ivalue *x, duk_regconst_t regconst) {
x->t = DUK_IVAL_PLAIN;
x->x1.t = DUK_ISPEC_REGCONST;
- x->x1.regconst = (duk_regconst_t) regconst;
+ x->x1.regconst = regconst;
}
DUK_LOCAL void duk__ivalue_plain_fromstack(duk_compiler_ctx *comp_ctx, duk_ivalue *x) {
x->t = DUK_IVAL_PLAIN;
x->x1.t = DUK_ISPEC_VALUE;
- duk_replace((duk_context *) comp_ctx->thr, x->x1.valstack_idx);
+ duk_replace(comp_ctx->thr, x->x1.valstack_idx);
}
DUK_LOCAL void duk__ivalue_var_fromstack(duk_compiler_ctx *comp_ctx, duk_ivalue *x) {
x->t = DUK_IVAL_VAR;
x->x1.t = DUK_ISPEC_VALUE;
- duk_replace((duk_context *) comp_ctx->thr, x->x1.valstack_idx);
+ duk_replace(comp_ctx->thr, x->x1.valstack_idx);
}
DUK_LOCAL_DECL void duk__ivalue_var_hstring(duk_compiler_ctx *comp_ctx, duk_ivalue *x, duk_hstring *h) {
DUK_ASSERT(h != NULL);
- duk_push_hstring((duk_context *) comp_ctx->thr, h);
+ duk_push_hstring(comp_ctx->thr, h);
duk__ivalue_var_fromstack(comp_ctx, x);
}
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;
-
dst->t = src->t;
dst->regconst = src->regconst;
- duk_copy(ctx, src->valstack_idx, dst->valstack_idx);
+ duk_copy(comp_ctx->thr, src->valstack_idx, dst->valstack_idx);
}
DUK_LOCAL void duk__copy_ivalue(duk_compiler_ctx *comp_ctx, duk_ivalue *src, duk_ivalue *dst) {
- duk_context *ctx = (duk_context *) comp_ctx->thr;
-
dst->t = src->t;
dst->op = src->op;
dst->x1.t = src->x1.t;
dst->x1.regconst = src->x1.regconst;
dst->x2.t = src->x2.t;
dst->x2.regconst = src->x2.regconst;
- duk_copy(ctx, src->x1.valstack_idx, dst->x1.valstack_idx);
- duk_copy(ctx, src->x2.valstack_idx, dst->x2.valstack_idx);
+ duk_copy(comp_ctx->thr, src->x1.valstack_idx, dst->x1.valstack_idx);
+ duk_copy(comp_ctx->thr, src->x2.valstack_idx, dst->x2.valstack_idx);
}
-DUK_LOCAL duk_reg_t duk__alloctemps(duk_compiler_ctx *comp_ctx, duk_small_int_t num) {
- duk_reg_t res;
+DUK_LOCAL duk_regconst_t duk__alloctemps(duk_compiler_ctx *comp_ctx, duk_small_int_t num) {
+ duk_regconst_t res;
res = comp_ctx->curr_func.temp_next;
comp_ctx->curr_func.temp_next += num;
@@ -64272,11 +65766,11 @@ DUK_LOCAL duk_reg_t duk__alloctemps(duk_compiler_ctx *comp_ctx, duk_small_int_t
return res;
}
-DUK_LOCAL duk_reg_t duk__alloctemp(duk_compiler_ctx *comp_ctx) {
+DUK_LOCAL duk_regconst_t duk__alloctemp(duk_compiler_ctx *comp_ctx) {
return duk__alloctemps(comp_ctx, 1);
}
-DUK_LOCAL void duk__settemp_checkmax(duk_compiler_ctx *comp_ctx, duk_reg_t temp_next) {
+DUK_LOCAL void duk__settemp_checkmax(duk_compiler_ctx *comp_ctx, duk_regconst_t temp_next) {
comp_ctx->curr_func.temp_next = temp_next;
if (temp_next > comp_ctx->curr_func.temp_max) {
comp_ctx->curr_func.temp_max = temp_next;
@@ -64286,14 +65780,13 @@ DUK_LOCAL void duk__settemp_checkmax(duk_compiler_ctx *comp_ctx, duk_reg_t temp_
/* get const for value at valstack top */
DUK_LOCAL duk_regconst_t duk__getconst(duk_compiler_ctx *comp_ctx) {
duk_hthread *thr = comp_ctx->thr;
- duk_context *ctx = (duk_context *) thr;
duk_compiler_func *f = &comp_ctx->curr_func;
duk_tval *tv1;
duk_int_t i, n, n_check;
- n = (duk_int_t) duk_get_length(ctx, f->consts_idx);
+ n = (duk_int_t) duk_get_length(thr, f->consts_idx);
- tv1 = DUK_GET_TVAL_NEGIDX(ctx, -1);
+ tv1 = DUK_GET_TVAL_NEGIDX(thr, -1);
DUK_ASSERT(tv1 != NULL);
#if defined(DUK_USE_FASTINT)
@@ -64315,8 +65808,8 @@ DUK_LOCAL duk_regconst_t duk__getconst(duk_compiler_ctx *comp_ctx) {
if (duk_js_samevalue(tv1, tv2)) {
DUK_DDD(DUK_DDDPRINT("reused existing constant for %!T -> const index %ld",
(duk_tval *) tv1, (long) i));
- duk_pop(ctx);
- return (duk_regconst_t) (i | DUK__CONST_MARKER);
+ duk_pop(thr);
+ return (duk_regconst_t) i | (duk_regconst_t) DUK__CONST_MARKER;
}
}
@@ -64326,20 +65819,19 @@ DUK_LOCAL duk_regconst_t duk__getconst(duk_compiler_ctx *comp_ctx) {
DUK_DDD(DUK_DDDPRINT("allocating new constant for %!T -> const index %ld",
(duk_tval *) tv1, (long) n));
- (void) duk_put_prop_index(ctx, f->consts_idx, n); /* invalidates tv1, tv2 */
- return (duk_regconst_t) (n | DUK__CONST_MARKER);
+ (void) duk_put_prop_index(thr, f->consts_idx, (duk_uarridx_t) n); /* invalidates tv1, tv2 */
+ return (duk_regconst_t) n | (duk_regconst_t) DUK__CONST_MARKER;
}
DUK_LOCAL duk_bool_t duk__const_needs_refcount(duk_compiler_ctx *comp_ctx, duk_regconst_t rc) {
#if defined(DUK_USE_REFERENCE_COUNTING)
- duk_context *ctx = (duk_context *) comp_ctx->thr;
duk_compiler_func *f = &comp_ctx->curr_func;
duk_bool_t ret;
DUK_ASSERT((rc & DUK__CONST_MARKER) == 0); /* caller removes const marker */
- (void) duk_get_prop_index(ctx, f->consts_idx, (duk_uarridx_t) rc);
- ret = !duk_is_number(ctx, -1); /* now only number/string, so conservative check */
- duk_pop(ctx);
+ (void) duk_get_prop_index(comp_ctx->thr, f->consts_idx, (duk_uarridx_t) rc);
+ ret = !duk_is_number(comp_ctx->thr, -1); /* now only number/string, so conservative check */
+ duk_pop(comp_ctx->thr);
return ret;
#else
DUK_UNREF(comp_ctx);
@@ -64368,16 +65860,15 @@ DUK_LOCAL duk_bool_t duk__const_needs_refcount(duk_compiler_ctx *comp_ctx, duk_r
DUK_LOCAL
duk_regconst_t duk__ispec_toregconst_raw(duk_compiler_ctx *comp_ctx,
duk_ispec *x,
- duk_reg_t forced_reg,
+ duk_regconst_t forced_reg,
duk_small_uint_t flags) {
duk_hthread *thr = comp_ctx->thr;
- duk_context *ctx = (duk_context *) thr;
DUK_DDD(DUK_DDDPRINT("duk__ispec_toregconst_raw(): x={%ld:%ld:%!T}, "
"forced_reg=%ld, flags 0x%08lx: allow_const=%ld require_temp=%ld require_short=%ld",
(long) x->t,
(long) x->regconst,
- (duk_tval *) duk_get_tval(ctx, x->valstack_idx),
+ (duk_tval *) duk_get_tval(thr, x->valstack_idx),
(long) forced_reg,
(unsigned long) flags,
(long) ((flags & DUK__IVAL_FLAG_ALLOW_CONST) ? 1 : 0),
@@ -64388,7 +65879,7 @@ duk_regconst_t duk__ispec_toregconst_raw(duk_compiler_ctx *comp_ctx,
case DUK_ISPEC_VALUE: {
duk_tval *tv;
- tv = DUK_GET_TVAL_POSIDX(ctx, x->valstack_idx);
+ tv = DUK_GET_TVAL_POSIDX(thr, x->valstack_idx);
DUK_ASSERT(tv != NULL);
switch (DUK_TVAL_GET_TAG(tv)) {
@@ -64397,21 +65888,21 @@ duk_regconst_t duk__ispec_toregconst_raw(duk_compiler_ctx *comp_ctx,
* values can occur during compilation as a result of e.g.
* the 'void' operator.
*/
- duk_reg_t dest = (forced_reg >= 0 ? forced_reg : DUK__ALLOCTEMP(comp_ctx));
- duk__emit_bc(comp_ctx, DUK_OP_LDUNDEF, (duk_regconst_t) dest);
- return (duk_regconst_t) dest;
+ duk_regconst_t dest = (forced_reg >= 0 ? forced_reg : DUK__ALLOCTEMP(comp_ctx));
+ duk__emit_bc(comp_ctx, DUK_OP_LDUNDEF, dest);
+ return dest;
}
case DUK_TAG_NULL: {
- duk_reg_t dest = (forced_reg >= 0 ? forced_reg : DUK__ALLOCTEMP(comp_ctx));
- duk__emit_bc(comp_ctx, DUK_OP_LDNULL, (duk_regconst_t) dest);
- return (duk_regconst_t) dest;
+ duk_regconst_t dest = (forced_reg >= 0 ? forced_reg : DUK__ALLOCTEMP(comp_ctx));
+ duk__emit_bc(comp_ctx, DUK_OP_LDNULL, dest);
+ return dest;
}
case DUK_TAG_BOOLEAN: {
- duk_reg_t dest = (forced_reg >= 0 ? forced_reg : DUK__ALLOCTEMP(comp_ctx));
+ duk_regconst_t dest = (forced_reg >= 0 ? forced_reg : DUK__ALLOCTEMP(comp_ctx));
duk__emit_bc(comp_ctx,
(DUK_TVAL_GET_BOOLEAN(tv) ? DUK_OP_LDTRUE : DUK_OP_LDFALSE),
- (duk_regconst_t) dest);
- return (duk_regconst_t) dest;
+ dest);
+ return dest;
}
case DUK_TAG_POINTER: {
DUK_UNREACHABLE();
@@ -64419,7 +65910,7 @@ duk_regconst_t duk__ispec_toregconst_raw(duk_compiler_ctx *comp_ctx,
}
case DUK_TAG_STRING: {
duk_hstring *h;
- duk_reg_t dest;
+ duk_regconst_t dest;
duk_regconst_t constidx;
h = DUK_TVAL_GET_STRING(tv);
@@ -64434,7 +65925,7 @@ duk_regconst_t duk__ispec_toregconst_raw(duk_compiler_ctx *comp_ctx,
/* Encode into a double constant (53 bits can encode 6*8 = 48 bits + 3-bit length */
}
#endif
- duk_dup(ctx, x->valstack_idx);
+ duk_dup(thr, x->valstack_idx);
constidx = duk__getconst(comp_ctx);
if (flags & DUK__IVAL_FLAG_ALLOW_CONST) {
@@ -64442,8 +65933,8 @@ duk_regconst_t duk__ispec_toregconst_raw(duk_compiler_ctx *comp_ctx,
}
dest = (forced_reg >= 0 ? forced_reg : DUK__ALLOCTEMP(comp_ctx));
- duk__emit_a_bc(comp_ctx, DUK_OP_LDCONST, (duk_regconst_t) dest, constidx);
- return (duk_regconst_t) dest;
+ duk__emit_a_bc(comp_ctx, DUK_OP_LDCONST, dest, constidx);
+ return dest;
}
case DUK_TAG_OBJECT: {
DUK_UNREACHABLE();
@@ -64462,7 +65953,7 @@ duk_regconst_t duk__ispec_toregconst_raw(duk_compiler_ctx *comp_ctx,
#endif
default: {
/* number */
- duk_reg_t dest;
+ duk_regconst_t dest;
duk_regconst_t constidx;
duk_double_t dval;
duk_int32_t ival;
@@ -64481,50 +65972,50 @@ duk_regconst_t duk__ispec_toregconst_raw(duk_compiler_ctx *comp_ctx,
if (duk_is_whole_get_int32_nonegzero(dval, &ival)) {
dest = (forced_reg >= 0 ? forced_reg : DUK__ALLOCTEMP(comp_ctx));
duk__emit_load_int32(comp_ctx, dest, ival);
- return (duk_regconst_t) dest;
+ return dest;
}
}
- duk_dup(ctx, x->valstack_idx);
+ duk_dup(thr, x->valstack_idx);
constidx = duk__getconst(comp_ctx);
if (flags & DUK__IVAL_FLAG_ALLOW_CONST) {
return constidx;
} else {
dest = (forced_reg >= 0 ? forced_reg : DUK__ALLOCTEMP(comp_ctx));
- duk__emit_a_bc(comp_ctx, DUK_OP_LDCONST, (duk_regconst_t) dest, constidx);
- return (duk_regconst_t) dest;
+ duk__emit_a_bc(comp_ctx, DUK_OP_LDCONST, dest, constidx);
+ return dest;
}
}
} /* end switch */
}
case DUK_ISPEC_REGCONST: {
if (forced_reg >= 0) {
- if (x->regconst & DUK__CONST_MARKER) {
+ if (DUK__ISCONST(x->regconst)) {
duk__emit_a_bc(comp_ctx, DUK_OP_LDCONST, forced_reg, x->regconst);
- } else if (x->regconst != (duk_regconst_t) forced_reg) {
+ } else if (x->regconst != forced_reg) {
duk__emit_a_bc(comp_ctx, DUK_OP_LDREG, forced_reg, x->regconst);
} else {
; /* already in correct reg */
}
- return (duk_regconst_t) forced_reg;
+ return forced_reg;
}
DUK_ASSERT(forced_reg < 0);
- if (x->regconst & DUK__CONST_MARKER) {
+ if (DUK__ISCONST(x->regconst)) {
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;
+ duk_regconst_t dest = DUK__ALLOCTEMP(comp_ctx);
+ duk__emit_a_bc(comp_ctx, DUK_OP_LDCONST, dest, x->regconst);
+ return 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;
+ DUK_ASSERT(forced_reg < 0 && !DUK__ISCONST(x->regconst));
+ if ((flags & DUK__IVAL_FLAG_REQUIRE_TEMP) && !DUK__ISREG_TEMP(comp_ctx, x->regconst)) {
+ duk_regconst_t dest = DUK__ALLOCTEMP(comp_ctx);
+ duk__emit_a_bc(comp_ctx, DUK_OP_LDREG, dest, x->regconst);
+ return dest;
}
return x->regconst;
}
@@ -64537,7 +66028,7 @@ duk_regconst_t duk__ispec_toregconst_raw(duk_compiler_ctx *comp_ctx,
return 0;
}
-DUK_LOCAL void duk__ispec_toforcedreg(duk_compiler_ctx *comp_ctx, duk_ispec *x, duk_reg_t forced_reg) {
+DUK_LOCAL void duk__ispec_toforcedreg(duk_compiler_ctx *comp_ctx, duk_ispec *x, duk_regconst_t forced_reg) {
DUK_ASSERT(forced_reg >= 0);
(void) duk__ispec_toregconst_raw(comp_ctx, x, forced_reg, 0 /*flags*/);
}
@@ -64547,17 +66038,16 @@ DUK_LOCAL void duk__ispec_toforcedreg(duk_compiler_ctx *comp_ctx, duk_ispec *x,
* The duk_ivalue argument ('x') is converted into a plain value as a
* side effect.
*/
-DUK_LOCAL void duk__ivalue_toplain_raw(duk_compiler_ctx *comp_ctx, duk_ivalue *x, duk_reg_t forced_reg) {
+DUK_LOCAL void duk__ivalue_toplain_raw(duk_compiler_ctx *comp_ctx, duk_ivalue *x, duk_regconst_t forced_reg) {
duk_hthread *thr = comp_ctx->thr;
- duk_context *ctx = (duk_context *) thr;
DUK_DDD(DUK_DDDPRINT("duk__ivalue_toplain_raw(): x={t=%ld,op=%ld,x1={%ld:%ld:%!T},x2={%ld:%ld:%!T}}, "
"forced_reg=%ld",
(long) x->t, (long) x->op,
(long) x->x1.t, (long) x->x1.regconst,
- (duk_tval *) duk_get_tval(ctx, x->x1.valstack_idx),
+ (duk_tval *) duk_get_tval(thr, x->x1.valstack_idx),
(long) x->x2.t, (long) x->x2.regconst,
- (duk_tval *) duk_get_tval(ctx, x->x2.valstack_idx),
+ (duk_tval *) duk_get_tval(thr, x->x2.valstack_idx),
(long) forced_reg));
switch (x->t) {
@@ -64568,7 +66058,7 @@ DUK_LOCAL void duk__ivalue_toplain_raw(duk_compiler_ctx *comp_ctx, duk_ivalue *x
case DUK_IVAL_ARITH: {
duk_regconst_t arg1;
duk_regconst_t arg2;
- duk_reg_t dest;
+ duk_regconst_t dest;
duk_tval *tv1;
duk_tval *tv2;
@@ -64577,8 +66067,8 @@ DUK_LOCAL void duk__ivalue_toplain_raw(duk_compiler_ctx *comp_ctx, duk_ivalue *x
/* inline arithmetic check for constant values */
/* XXX: use the exactly same arithmetic function here as in executor */
if (x->x1.t == DUK_ISPEC_VALUE && x->x2.t == DUK_ISPEC_VALUE && x->t == DUK_IVAL_ARITH) {
- tv1 = DUK_GET_TVAL_POSIDX(ctx, x->x1.valstack_idx);
- tv2 = DUK_GET_TVAL_POSIDX(ctx, x->x2.valstack_idx);
+ tv1 = DUK_GET_TVAL_POSIDX(thr, x->x1.valstack_idx);
+ tv2 = DUK_GET_TVAL_POSIDX(thr, x->x2.valstack_idx);
DUK_ASSERT(tv1 != NULL);
DUK_ASSERT(tv2 != NULL);
@@ -64637,10 +66127,10 @@ DUK_LOCAL void duk__ivalue_toplain_raw(duk_compiler_ctx *comp_ctx, duk_ivalue *x
/* Inline string concatenation. No need to check for
* symbols, as all inputs are valid Ecmascript strings.
*/
- duk_dup(ctx, x->x1.valstack_idx);
- duk_dup(ctx, x->x2.valstack_idx);
- duk_concat(ctx, 2);
- duk_replace(ctx, x->x1.valstack_idx);
+ duk_dup(thr, x->x1.valstack_idx);
+ duk_dup(thr, x->x2.valstack_idx);
+ duk_concat(thr, 2);
+ duk_replace(thr, x->x1.valstack_idx);
x->t = DUK_IVAL_PLAIN;
DUK_ASSERT(x->x1.t == DUK_ISPEC_VALUE);
return;
@@ -64655,25 +66145,25 @@ DUK_LOCAL void duk__ivalue_toplain_raw(duk_compiler_ctx *comp_ctx, duk_ivalue *x
*/
if (forced_reg >= 0) {
dest = forced_reg;
- } else if (DUK__ISTEMP(comp_ctx, arg1)) {
- dest = (duk_reg_t) arg1;
- } else if (DUK__ISTEMP(comp_ctx, arg2)) {
- dest = (duk_reg_t) arg2;
+ } else if (DUK__ISREG_TEMP(comp_ctx, arg1)) {
+ dest = arg1;
+ } else if (DUK__ISREG_TEMP(comp_ctx, arg2)) {
+ dest = arg2;
} else {
dest = DUK__ALLOCTEMP(comp_ctx);
}
DUK_ASSERT(DUK__ISREG(dest));
- duk__emit_a_b_c(comp_ctx, x->op | DUK__EMIT_FLAG_BC_REGCONST, (duk_regconst_t) dest, arg1, arg2);
+ duk__emit_a_b_c(comp_ctx, x->op | DUK__EMIT_FLAG_BC_REGCONST, dest, arg1, arg2);
- duk__ivalue_regconst(x, (duk_regconst_t) dest);
+ duk__ivalue_regconst(x, dest);
return;
}
case DUK_IVAL_PROP: {
/* XXX: very similar to DUK_IVAL_ARITH - merge? */
duk_regconst_t arg1;
duk_regconst_t arg2;
- duk_reg_t dest;
+ duk_regconst_t dest;
/* Need a short reg/const, does not have to be a mutable temp. */
arg1 = duk__ispec_toregconst_raw(comp_ctx, &x->x1, -1, DUK__IVAL_FLAG_ALLOW_CONST | DUK__IVAL_FLAG_REQUIRE_SHORT /*flags*/);
@@ -64690,38 +66180,38 @@ DUK_LOCAL void duk__ivalue_toplain_raw(duk_compiler_ctx *comp_ctx, duk_ivalue *x
if (forced_reg >= 0) {
dest = forced_reg;
- } else if (DUK__ISTEMP(comp_ctx, arg1)) {
- dest = (duk_reg_t) arg1;
- } else if (DUK__ISTEMP(comp_ctx, arg2)) {
- dest = (duk_reg_t) arg2;
+ } else if (DUK__ISREG_TEMP(comp_ctx, arg1)) {
+ dest = arg1;
+ } else if (DUK__ISREG_TEMP(comp_ctx, arg2)) {
+ dest = arg2;
} else {
dest = DUK__ALLOCTEMP(comp_ctx);
}
duk__emit_a_b_c(comp_ctx,
DUK_OP_GETPROP | DUK__EMIT_FLAG_BC_REGCONST,
- (duk_regconst_t) dest,
+ dest,
arg1,
arg2);
- duk__ivalue_regconst(x, (duk_regconst_t) dest);
+ duk__ivalue_regconst(x, dest);
return;
}
case DUK_IVAL_VAR: {
/* x1 must be a string */
- duk_reg_t dest;
- duk_reg_t reg_varbind;
+ duk_regconst_t dest;
+ duk_regconst_t reg_varbind;
duk_regconst_t rc_varname;
DUK_ASSERT(x->x1.t == DUK_ISPEC_VALUE);
- duk_dup(ctx, x->x1.valstack_idx);
+ duk_dup(thr, x->x1.valstack_idx);
if (duk__lookup_lhs(comp_ctx, &reg_varbind, &rc_varname)) {
- duk__ivalue_regconst(x, (duk_regconst_t) reg_varbind);
+ duk__ivalue_regconst(x, reg_varbind);
} else {
dest = (forced_reg >= 0 ? forced_reg : DUK__ALLOCTEMP(comp_ctx));
- duk__emit_a_bc(comp_ctx, DUK_OP_GETVAR, (duk_regconst_t) dest, rc_varname);
- duk__ivalue_regconst(x, (duk_regconst_t) dest);
+ duk__emit_a_bc(comp_ctx, DUK_OP_GETVAR, dest, rc_varname);
+ duk__ivalue_regconst(x, dest);
}
return;
}
@@ -64743,7 +66233,7 @@ DUK_LOCAL void duk__ivalue_toplain(duk_compiler_ctx *comp_ctx, duk_ivalue *x) {
/* evaluate to final form (e.g. coerce GETPROP to code), throw away temp */
DUK_LOCAL void duk__ivalue_toplain_ignore(duk_compiler_ctx *comp_ctx, duk_ivalue *x) {
- duk_reg_t temp;
+ duk_regconst_t temp;
/* If duk__ivalue_toplain_raw() allocates a temp, forget it and
* restore next temp state.
@@ -64762,21 +66252,19 @@ DUK_LOCAL void duk__ivalue_toplain_ignore(duk_compiler_ctx *comp_ctx, duk_ivalue
DUK_LOCAL
duk_regconst_t duk__ivalue_toregconst_raw(duk_compiler_ctx *comp_ctx,
duk_ivalue *x,
- duk_reg_t forced_reg,
+ duk_regconst_t forced_reg,
duk_small_uint_t flags) {
duk_hthread *thr = comp_ctx->thr;
- duk_context *ctx = (duk_context *) thr;
duk_regconst_t reg;
DUK_UNREF(thr);
- DUK_UNREF(ctx);
DUK_DDD(DUK_DDDPRINT("duk__ivalue_toregconst_raw(): x={t=%ld,op=%ld,x1={%ld:%ld:%!T},x2={%ld:%ld:%!T}}, "
"forced_reg=%ld, flags 0x%08lx: allow_const=%ld require_temp=%ld require_short=%ld",
(long) x->t, (long) x->op,
(long) x->x1.t, (long) x->x1.regconst,
- (duk_tval *) duk_get_tval(ctx, x->x1.valstack_idx),
+ (duk_tval *) duk_get_tval(thr, x->x1.valstack_idx),
(long) x->x2.t, (long) x->x2.regconst,
- (duk_tval *) duk_get_tval(ctx, x->x2.valstack_idx),
+ (duk_tval *) duk_get_tval(thr, x->x2.valstack_idx),
(long) forced_reg,
(unsigned long) flags,
(long) ((flags & DUK__IVAL_FLAG_ALLOW_CONST) ? 1 : 0),
@@ -64789,17 +66277,17 @@ duk_regconst_t duk__ivalue_toregconst_raw(duk_compiler_ctx *comp_ctx,
/* then to a register */
reg = duk__ispec_toregconst_raw(comp_ctx, &x->x1, forced_reg, flags);
- duk__ivalue_regconst(x, (duk_regconst_t) reg);
+ duk__ivalue_regconst(x, reg);
return reg;
}
-DUK_LOCAL duk_reg_t duk__ivalue_toreg(duk_compiler_ctx *comp_ctx, duk_ivalue *x) {
+DUK_LOCAL duk_regconst_t duk__ivalue_toreg(duk_compiler_ctx *comp_ctx, duk_ivalue *x) {
return duk__ivalue_toregconst_raw(comp_ctx, x, -1, 0 /*flags*/);
}
#if 0 /* unused */
-DUK_LOCAL duk_reg_t duk__ivalue_totemp(duk_compiler_ctx *comp_ctx, duk_ivalue *x) {
+DUK_LOCAL duk_regconst_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
@@ -64829,20 +66317,19 @@ DUK_LOCAL duk_regconst_t duk__ivalue_totempconst(duk_compiler_ctx *comp_ctx, duk
* Identifier handling
*/
-DUK_LOCAL duk_reg_t duk__lookup_active_register_binding(duk_compiler_ctx *comp_ctx) {
+DUK_LOCAL duk_regconst_t duk__lookup_active_register_binding(duk_compiler_ctx *comp_ctx) {
duk_hthread *thr = comp_ctx->thr;
- duk_context *ctx = (duk_context *) thr;
duk_hstring *h_varname;
- duk_reg_t ret;
+ duk_regconst_t ret;
DUK_DDD(DUK_DDDPRINT("resolving identifier reference to '%!T'",
- (duk_tval *) duk_get_tval(ctx, -1)));
+ (duk_tval *) duk_get_tval(thr, -1)));
/*
* Special name handling
*/
- h_varname = duk_known_hstring(ctx, -1);
+ h_varname = duk_known_hstring(thr, -1);
if (h_varname == DUK_HTHREAD_STRING_LC_ARGUMENTS(thr)) {
DUK_DDD(DUK_DDDPRINT("flagging function as accessing 'arguments'"));
@@ -64867,12 +66354,12 @@ DUK_LOCAL duk_reg_t duk__lookup_active_register_binding(duk_compiler_ctx *comp_c
* name will use slow path.
*/
- duk_get_prop(ctx, comp_ctx->curr_func.varmap_idx);
- if (duk_is_number(ctx, -1)) {
- ret = duk_to_int(ctx, -1);
- duk_pop(ctx);
+ duk_get_prop(thr, comp_ctx->curr_func.varmap_idx);
+ if (duk_is_number(thr, -1)) {
+ ret = duk_to_int(thr, -1);
+ duk_pop(thr);
} else {
- duk_pop(ctx);
+ duk_pop(thr);
if (comp_ctx->curr_func.catch_depth > 0 || comp_ctx->curr_func.with_depth > 0) {
DUK_DDD(DUK_DDDPRINT("slow path access from inside a try-catch or with needs _Varmap"));
goto slow_path_own;
@@ -64893,14 +66380,14 @@ DUK_LOCAL duk_reg_t duk__lookup_active_register_binding(duk_compiler_ctx *comp_c
DUK_DDD(DUK_DDDPRINT("identifier lookup -> slow path, not own variable"));
comp_ctx->curr_func.id_access_slow = 1;
- return (duk_reg_t) -1;
+ return (duk_regconst_t) -1;
slow_path_own:
DUK_DDD(DUK_DDDPRINT("identifier lookup -> slow path, may be own variable"));
comp_ctx->curr_func.id_access_slow = 1;
comp_ctx->curr_func.id_access_slow_own = 1;
- return (duk_reg_t) -1;
+ return (duk_regconst_t) -1;
}
/* Lookup an identifier name in the current varmap, indicating whether the
@@ -64911,21 +66398,20 @@ DUK_LOCAL duk_reg_t duk__lookup_active_register_binding(duk_compiler_ctx *comp_c
* return code is 0 or out_reg_varbind is < 0; this is becuase out_rc_varname
* is unsigned and doesn't have a "unused" / none value.
*/
-DUK_LOCAL duk_bool_t duk__lookup_lhs(duk_compiler_ctx *comp_ctx, duk_reg_t *out_reg_varbind, duk_regconst_t *out_rc_varname) {
+DUK_LOCAL duk_bool_t duk__lookup_lhs(duk_compiler_ctx *comp_ctx, duk_regconst_t *out_reg_varbind, duk_regconst_t *out_rc_varname) {
duk_hthread *thr = comp_ctx->thr;
- duk_context *ctx = (duk_context *) thr;
- duk_reg_t reg_varbind;
+ duk_regconst_t reg_varbind;
duk_regconst_t rc_varname;
/* [ ... varname ] */
- duk_dup_top(ctx);
+ duk_dup_top(thr);
reg_varbind = duk__lookup_active_register_binding(comp_ctx);
if (reg_varbind >= 0) {
*out_reg_varbind = reg_varbind;
*out_rc_varname = 0; /* duk_regconst_t is unsigned, so use 0 as dummy value (ignored by caller) */
- duk_pop(ctx);
+ duk_pop(thr);
return 1;
} else {
rc_varname = duk__getconst(comp_ctx);
@@ -64945,7 +66431,6 @@ DUK_LOCAL duk_bool_t duk__lookup_lhs(duk_compiler_ctx *comp_ctx, duk_reg_t *out_
DUK_LOCAL void duk__add_label(duk_compiler_ctx *comp_ctx, duk_hstring *h_label, duk_int_t pc_label, duk_int_t label_id) {
duk_hthread *thr = comp_ctx->thr;
- duk_context *ctx = (duk_context *) thr;
duk_size_t n;
duk_size_t new_size;
duk_uint8_t *p;
@@ -64973,13 +66458,13 @@ DUK_LOCAL void duk__add_label(duk_compiler_ctx *comp_ctx, duk_hstring *h_label,
}
}
- duk_push_hstring(ctx, h_label);
+ duk_push_hstring(thr, h_label);
DUK_ASSERT(n <= DUK_UARRIDX_MAX); /* label limits */
- (void) duk_put_prop_index(ctx, comp_ctx->curr_func.labelnames_idx, (duk_uarridx_t) n);
+ (void) duk_put_prop_index(thr, comp_ctx->curr_func.labelnames_idx, (duk_uarridx_t) n);
new_size = (n + 1) * sizeof(duk_labelinfo);
duk_hbuffer_resize(thr, comp_ctx->curr_func.h_labelinfos, new_size);
- /* XXX: spare handling, slow now */
+ /* XXX: slack handling, slow now */
/* relookup after possible realloc */
p = (duk_uint8_t *) DUK_HBUFFER_DYNAMIC_GET_DATA_PTR(thr->heap, comp_ctx->curr_func.h_labelinfos);
@@ -65050,7 +66535,6 @@ DUK_LOCAL void duk__update_label_flags(duk_compiler_ctx *comp_ctx, duk_int_t lab
/* XXX: awkward, especially the bunch of separate output values -> output struct? */
DUK_LOCAL void duk__lookup_active_label(duk_compiler_ctx *comp_ctx, duk_hstring *h_label, duk_bool_t is_break, duk_int_t *out_label_id, duk_int_t *out_label_catch_depth, duk_int_t *out_label_pc, duk_bool_t *out_is_closest) {
duk_hthread *thr = comp_ctx->thr;
- duk_context *ctx = (duk_context *) thr;
duk_uint8_t *p;
duk_labelinfo *li_start, *li_end, *li;
duk_bool_t match = 0;
@@ -65058,7 +66542,7 @@ DUK_LOCAL void duk__lookup_active_label(duk_compiler_ctx *comp_ctx, duk_hstring
DUK_DDD(DUK_DDDPRINT("looking up active label: label='%!O', is_break=%ld",
(duk_heaphdr *) h_label, (long) is_break));
- DUK_UNREF(ctx);
+ DUK_UNREF(thr);
p = (duk_uint8_t *) DUK_HBUFFER_DYNAMIC_GET_DATA_PTR(thr->heap, comp_ctx->curr_func.h_labelinfos);
li_start = (duk_labelinfo *) (void *) p;
@@ -65121,12 +66605,11 @@ DUK_LOCAL void duk__lookup_active_label(duk_compiler_ctx *comp_ctx, duk_hstring
*out_is_closest = (li == li_end - 1);
}
-DUK_LOCAL void duk__reset_labels_to_length(duk_compiler_ctx *comp_ctx, duk_int_t len) {
+DUK_LOCAL void duk__reset_labels_to_length(duk_compiler_ctx *comp_ctx, duk_size_t len) {
duk_hthread *thr = comp_ctx->thr;
- duk_context *ctx = (duk_context *) thr;
- duk_set_length(ctx, comp_ctx->curr_func.labelnames_idx, (duk_size_t) len);
- duk_hbuffer_resize(thr, comp_ctx->curr_func.h_labelinfos, sizeof(duk_labelinfo) * (duk_size_t) len);
+ duk_set_length(thr, comp_ctx->curr_func.labelnames_idx, len);
+ duk_hbuffer_resize(thr, comp_ctx->curr_func.h_labelinfos, sizeof(duk_labelinfo) * len);
}
/*
@@ -65144,15 +66627,19 @@ DUK_LOCAL void duk__reset_labels_to_length(duk_compiler_ctx *comp_ctx, duk_int_t
DUK_LOCAL void duk__nud_array_literal(duk_compiler_ctx *comp_ctx, duk_ivalue *res) {
duk_hthread *thr = comp_ctx->thr;
- duk_reg_t reg_obj; /* result reg */
- duk_reg_t reg_temp; /* temp reg */
- duk_reg_t temp_start; /* temp reg value for start of loop */
+ duk_regconst_t reg_obj; /* result reg */
+ duk_regconst_t reg_temp; /* temp reg */
+ duk_regconst_t temp_start; /* temp reg value for start of loop */
duk_small_uint_t max_init_values; /* max # of values initialized in one MPUTARR set */
duk_small_uint_t num_values; /* number of values in current MPUTARR set */
duk_uarridx_t curr_idx; /* current (next) array index */
duk_uarridx_t start_idx; /* start array index of current MPUTARR set */
duk_uarridx_t init_idx; /* last array index explicitly initialized, +1 */
duk_bool_t require_comma; /* next loop requires a comma */
+#if !defined(DUK_USE_PREFER_SIZE)
+ duk_int_t pc_newarr;
+ duk_compiler_instr *instr;
+#endif
/* DUK_TOK_LBRACKET already eaten, current token is right after that */
DUK_ASSERT(comp_ctx->prev_token.t == DUK_TOK_LBRACKET);
@@ -65160,6 +66647,9 @@ DUK_LOCAL void duk__nud_array_literal(duk_compiler_ctx *comp_ctx, duk_ivalue *re
max_init_values = DUK__MAX_ARRAY_INIT_VALUES; /* XXX: depend on available temps? */
reg_obj = DUK__ALLOCTEMP(comp_ctx);
+#if !defined(DUK_USE_PREFER_SIZE)
+ pc_newarr = duk__get_current_pc(comp_ctx);
+#endif
duk__emit_bc(comp_ctx, DUK_OP_NEWARR, reg_obj); /* XXX: patch initial size hint afterwards? */
temp_start = DUK__GETTEMP(comp_ctx);
@@ -65250,8 +66740,8 @@ DUK_LOCAL void duk__nud_array_literal(duk_compiler_ctx *comp_ctx, duk_ivalue *re
DUK_OP_MPUTARR |
DUK__EMIT_FLAG_NO_SHUFFLE_C |
DUK__EMIT_FLAG_A_IS_SOURCE,
- (duk_regconst_t) reg_obj,
- (duk_regconst_t) temp_start,
+ reg_obj,
+ temp_start,
(duk_regconst_t) (num_values + 1));
init_idx = start_idx + num_values;
@@ -65259,6 +66749,14 @@ DUK_LOCAL void duk__nud_array_literal(duk_compiler_ctx *comp_ctx, duk_ivalue *re
}
}
+ /* Update initil size for NEWARR, doesn't need to be exact and is
+ * capped at A field limit.
+ */
+#if !defined(DUK_USE_PREFER_SIZE)
+ instr = duk__get_instr_ptr(comp_ctx, pc_newarr);
+ instr->ins |= DUK_ENC_OP_A(0, curr_idx > DUK_BC_A_MAX ? DUK_BC_A_MAX : curr_idx);
+#endif
+
DUK_ASSERT(comp_ctx->curr_token.t == DUK_TOK_RBRACKET);
duk__advance(comp_ctx);
@@ -65273,13 +66771,13 @@ DUK_LOCAL void duk__nud_array_literal(duk_compiler_ctx *comp_ctx, duk_ivalue *re
duk__emit_load_int32(comp_ctx, reg_temp, (duk_int_t) curr_idx);
duk__emit_a_bc(comp_ctx,
DUK_OP_SETALEN | DUK__EMIT_FLAG_A_IS_SOURCE,
- (duk_regconst_t) reg_obj,
- (duk_regconst_t) reg_temp);
+ reg_obj,
+ reg_temp);
}
DUK__SETTEMP(comp_ctx, temp_start);
- duk__ivalue_regconst(res, (duk_regconst_t) reg_obj);
+ duk__ivalue_regconst(res, reg_obj);
return;
syntax_error:
@@ -65287,9 +66785,10 @@ DUK_LOCAL void duk__nud_array_literal(duk_compiler_ctx *comp_ctx, duk_ivalue *re
}
typedef struct {
- duk_reg_t reg_obj;
- duk_reg_t temp_start;
+ duk_regconst_t reg_obj;
+ duk_regconst_t temp_start;
duk_small_uint_t num_pairs;
+ duk_small_uint_t num_total_pairs;
} duk__objlit_state;
DUK_LOCAL void duk__objlit_flush_keys(duk_compiler_ctx *comp_ctx, duk__objlit_state *st) {
@@ -65309,20 +66808,21 @@ DUK_LOCAL void duk__objlit_flush_keys(duk_compiler_ctx *comp_ctx, duk__objlit_st
DUK__EMIT_FLAG_A_IS_SOURCE,
st->reg_obj,
st->temp_start,
- st->num_pairs * 2);
+ (duk_regconst_t) (st->num_pairs * 2));
+ st->num_total_pairs += st->num_pairs;
st->num_pairs = 0;
}
DUK__SETTEMP(comp_ctx, st->temp_start);
}
-DUK_LOCAL duk_bool_t duk__objlit_load_key(duk_compiler_ctx *comp_ctx, duk_ivalue *res, duk_token *tok, duk_reg_t reg_temp) {
+DUK_LOCAL duk_bool_t duk__objlit_load_key(duk_compiler_ctx *comp_ctx, duk_ivalue *res, duk_token *tok, duk_regconst_t reg_temp) {
if (tok->t_nores == DUK_TOK_IDENTIFIER || tok->t_nores == DUK_TOK_STRING) {
/* same handling for identifiers and strings */
DUK_ASSERT(tok->str1 != NULL);
- duk_push_hstring((duk_context *) comp_ctx->thr, tok->str1);
+ duk_push_hstring(comp_ctx->thr, tok->str1);
} else if (tok->t == DUK_TOK_NUMBER) {
/* numbers can be loaded as numbers and coerced on the fly */
- duk_push_number((duk_context *) comp_ctx->thr, tok->num);
+ duk_push_number(comp_ctx->thr, tok->num);
} else {
return 1; /* error */
}
@@ -65337,10 +66837,14 @@ DUK_LOCAL duk_bool_t duk__objlit_load_key(duk_compiler_ctx *comp_ctx, duk_ivalue
DUK_LOCAL void duk__nud_object_literal(duk_compiler_ctx *comp_ctx, duk_ivalue *res) {
duk_hthread *thr = comp_ctx->thr;
duk__objlit_state st;
- duk_reg_t reg_temp; /* temp reg */
+ duk_regconst_t reg_temp; /* temp reg */
duk_small_uint_t max_init_pairs; /* max # of key-value pairs initialized in one MPUTOBJ set */
duk_bool_t first; /* first value: comma must not precede the value */
duk_bool_t is_set, is_get; /* temps */
+#if !defined(DUK_USE_PREFER_SIZE)
+ duk_int_t pc_newobj;
+ duk_compiler_instr *instr;
+#endif
DUK_ASSERT(comp_ctx->prev_token.t == DUK_TOK_LCURLY);
@@ -65349,8 +66853,12 @@ DUK_LOCAL void duk__nud_object_literal(duk_compiler_ctx *comp_ctx, duk_ivalue *r
st.reg_obj = DUK__ALLOCTEMP(comp_ctx); /* target object */
st.temp_start = DUK__GETTEMP(comp_ctx); /* start of MPUTOBJ argument list */
st.num_pairs = 0; /* number of key/value pairs emitted for current MPUTOBJ set */
+ st.num_total_pairs = 0; /* number of key/value pairs emitted overall */
- duk__emit_bc(comp_ctx, DUK_OP_NEWOBJ, st.reg_obj); /* XXX: patch initial size hint afterwards? */
+#if !defined(DUK_USE_PREFER_SIZE)
+ pc_newobj = duk__get_current_pc(comp_ctx);
+#endif
+ duk__emit_bc(comp_ctx, DUK_OP_NEWOBJ, st.reg_obj);
/*
* Emit initializers in sets of maximum max_init_pairs keys.
@@ -65416,7 +66924,7 @@ DUK_LOCAL void duk__nud_object_literal(duk_compiler_ctx *comp_ctx, duk_ivalue *r
/* Reset temp register state and reserve reg_temp and
* reg_temp + 1 for handling the current property.
*/
- DUK__SETTEMP(comp_ctx, st.temp_start + 2 * st.num_pairs);
+ DUK__SETTEMP(comp_ctx, st.temp_start + 2 * (duk_regconst_t) st.num_pairs);
reg_temp = DUK__ALLOCTEMPS(comp_ctx, 2);
/* NOTE: "get" and "set" are not officially ReservedWords and the lexer
@@ -65446,7 +66954,7 @@ DUK_LOCAL void duk__nud_object_literal(duk_compiler_ctx *comp_ctx, duk_ivalue *r
duk__emit_a_bc(comp_ctx,
DUK_OP_CLOSURE,
- (duk_regconst_t) (st.temp_start + 1),
+ st.temp_start + 1,
(duk_regconst_t) fnum);
/* Slot C is used in a non-standard fashion (range of regs),
@@ -65494,7 +67002,7 @@ DUK_LOCAL void duk__nud_object_literal(duk_compiler_ctx *comp_ctx, duk_ivalue *r
duk__emit_a_bc(comp_ctx,
DUK_OP_CLOSURE,
- (duk_regconst_t) (reg_temp + 1),
+ reg_temp + 1,
(duk_regconst_t) fnum);
st.num_pairs++;
@@ -65538,10 +67046,21 @@ DUK_LOCAL void duk__nud_object_literal(duk_compiler_ctx *comp_ctx, duk_ivalue *r
DUK_ASSERT(st.num_pairs == 0);
DUK_ASSERT(DUK__GETTEMP(comp_ctx) == st.temp_start);
+ /* Update initial size for NEWOBJ. The init size doesn't need to be
+ * exact as the purpose is just to avoid object resizes in common
+ * cases. The size is capped to field A limit, and will be too high
+ * if the object literal contains duplicate keys (this is harmless but
+ * increases memory traffic if the object is compacted later on).
+ */
+#if !defined(DUK_USE_PREFER_SIZE)
+ instr = duk__get_instr_ptr(comp_ctx, pc_newobj);
+ instr->ins |= DUK_ENC_OP_A(0, st.num_total_pairs > DUK_BC_A_MAX ? DUK_BC_A_MAX : st.num_total_pairs);
+#endif
+
DUK_ASSERT(comp_ctx->curr_token.t == DUK_TOK_RCURLY);
duk__advance(comp_ctx);
- duk__ivalue_regconst(res, (duk_regconst_t) st.reg_obj);
+ duk__ivalue_regconst(res, st.reg_obj);
return;
syntax_error:
@@ -65554,7 +67073,7 @@ DUK_LOCAL void duk__nud_object_literal(duk_compiler_ctx *comp_ctx, duk_ivalue *r
*/
DUK_LOCAL duk_int_t duk__parse_arguments(duk_compiler_ctx *comp_ctx, duk_ivalue *res) {
duk_int_t nargs = 0;
- duk_reg_t reg_temp;
+ duk_regconst_t reg_temp;
/* Note: expect that caller has already eaten the left paren */
@@ -65604,10 +67123,9 @@ DUK_LOCAL duk_bool_t duk__expr_is_empty(duk_compiler_ctx *comp_ctx) {
DUK_LOCAL void duk__expr_nud(duk_compiler_ctx *comp_ctx, duk_ivalue *res) {
duk_hthread *thr = comp_ctx->thr;
- duk_context *ctx = (duk_context *) thr;
duk_token *tk;
- duk_reg_t temp_at_entry;
- duk_small_int_t tok;
+ duk_regconst_t temp_at_entry;
+ duk_small_uint_t tok;
duk_uint32_t args; /* temp variable to pass constants and flags to shared code */
/*
@@ -65633,12 +67151,12 @@ DUK_LOCAL void duk__expr_nud(duk_compiler_ctx *comp_ctx, duk_ivalue *res) {
/* PRIMARY EXPRESSIONS */
case DUK_TOK_THIS: {
- duk_reg_t reg_temp;
+ duk_regconst_t reg_temp;
reg_temp = DUK__ALLOCTEMP(comp_ctx);
duk__emit_bc(comp_ctx,
DUK_OP_LDTHIS,
- (duk_regconst_t) reg_temp);
- duk__ivalue_regconst(res, (duk_regconst_t) reg_temp);
+ reg_temp);
+ duk__ivalue_regconst(res, reg_temp);
return;
}
case DUK_TOK_IDENTIFIER: {
@@ -65646,29 +67164,29 @@ DUK_LOCAL void duk__expr_nud(duk_compiler_ctx *comp_ctx, duk_ivalue *res) {
return;
}
case DUK_TOK_NULL: {
- duk_push_null(ctx);
+ duk_push_null(thr);
goto plain_value;
}
case DUK_TOK_TRUE: {
- duk_push_true(ctx);
+ duk_push_true(thr);
goto plain_value;
}
case DUK_TOK_FALSE: {
- duk_push_false(ctx);
+ duk_push_false(thr);
goto plain_value;
}
case DUK_TOK_NUMBER: {
- duk_push_number(ctx, tk->num);
+ duk_push_number(thr, tk->num);
goto plain_value;
}
case DUK_TOK_STRING: {
DUK_ASSERT(tk->str1 != NULL);
- duk_push_hstring(ctx, tk->str1);
+ duk_push_hstring(thr, tk->str1);
goto plain_value;
}
case DUK_TOK_REGEXP: {
#if defined(DUK_USE_REGEXP_SUPPORT)
- duk_reg_t reg_temp;
+ duk_regconst_t reg_temp;
duk_regconst_t rc_re_bytecode; /* const */
duk_regconst_t rc_re_source; /* const */
@@ -65680,8 +67198,8 @@ DUK_LOCAL void duk__expr_nud(duk_compiler_ctx *comp_ctx, duk_ivalue *res) {
(duk_heaphdr *) tk->str2));
reg_temp = DUK__ALLOCTEMP(comp_ctx);
- duk_push_hstring(ctx, tk->str1);
- duk_push_hstring(ctx, tk->str2);
+ duk_push_hstring(thr, tk->str1);
+ duk_push_hstring(thr, tk->str2);
/* [ ... pattern flags ] */
@@ -65694,11 +67212,11 @@ DUK_LOCAL void duk__expr_nud(duk_compiler_ctx *comp_ctx, duk_ivalue *res) {
duk__emit_a_b_c(comp_ctx,
DUK_OP_REGEXP | DUK__EMIT_FLAG_BC_REGCONST,
- (duk_regconst_t) reg_temp /*a*/,
+ reg_temp /*a*/,
rc_re_bytecode /*b*/,
rc_re_source /*c*/);
- duk__ivalue_regconst(res, (duk_regconst_t) reg_temp);
+ duk__ivalue_regconst(res, reg_temp);
return;
#else /* DUK_USE_REGEXP_SUPPORT */
goto syntax_error;
@@ -65746,14 +67264,41 @@ DUK_LOCAL void duk__expr_nud(duk_compiler_ctx *comp_ctx, duk_ivalue *res) {
* and testcases/test-dev-new.js for a bunch of documented tests.
*/
- duk_reg_t reg_target;
+ duk_regconst_t reg_target;
duk_int_t nargs;
DUK_DDD(DUK_DDDPRINT("begin parsing new expression"));
- reg_target = DUK__ALLOCTEMP(comp_ctx);
+ reg_target = DUK__ALLOCTEMPS(comp_ctx, 2);
+
+#if defined(DUK_USE_ES6)
+ if (comp_ctx->curr_token.t == DUK_TOK_PERIOD) {
+ /* new.target */
+ DUK_DDD(DUK_DDDPRINT("new.target"));
+ duk__advance(comp_ctx);
+ if (comp_ctx->curr_token.t_nores != DUK_TOK_IDENTIFIER ||
+ !duk_hstring_equals_ascii_cstring(comp_ctx->curr_token.str1, "target")) {
+ goto syntax_error_newtarget;
+ }
+ if (comp_ctx->curr_func.is_global) {
+ goto syntax_error_newtarget;
+ }
+ duk__advance(comp_ctx);
+ duk__emit_bc(comp_ctx,
+ DUK_OP_NEWTARGET,
+ reg_target);
+ duk__ivalue_regconst(res, reg_target);
+ return;
+ }
+#endif /* DUK_USE_ES6 */
+
duk__expr_toforcedreg(comp_ctx, res, DUK__BP_CALL /*rbp_flags*/, reg_target /*forced_reg*/);
- DUK__SETTEMP(comp_ctx, reg_target + 1);
+ duk__emit_bc(comp_ctx, DUK_OP_NEWOBJ, reg_target + 1); /* default instance */
+ DUK__SETTEMP(comp_ctx, reg_target + 2);
+
+ /* XXX: 'new obj.noSuch()' doesn't use GETPROPC now which
+ * makes the error message worse than for obj.noSuch().
+ */
if (comp_ctx->curr_token.t == DUK_TOK_LPAREN) {
/* 'new' MemberExpression Arguments */
@@ -65767,17 +67312,14 @@ DUK_LOCAL void duk__expr_nud(duk_compiler_ctx *comp_ctx, duk_ivalue *res) {
nargs = 0;
}
- /* Opcode slot C is used in a non-standard way, so shuffling
- * is not allowed.
- */
duk__emit_a_bc(comp_ctx,
- DUK_OP_NEW | DUK__EMIT_FLAG_NO_SHUFFLE_A,
+ DUK_OP_CALL0 | DUK_BC_CALL_FLAG_CONSTRUCT,
nargs /*num_args*/,
reg_target /*target*/);
DUK_DDD(DUK_DDDPRINT("end parsing new expression"));
- duk__ivalue_regconst(res, (duk_regconst_t) reg_target);
+ duk__ivalue_regconst(res, reg_target);
return;
}
@@ -65795,7 +67337,7 @@ DUK_LOCAL void duk__expr_nud(duk_compiler_ctx *comp_ctx, duk_ivalue *res) {
* duk__parse_func_like_fnum().
*/
- duk_reg_t reg_temp;
+ duk_regconst_t reg_temp;
duk_int_t fnum;
reg_temp = DUK__ALLOCTEMP(comp_ctx);
@@ -65806,10 +67348,10 @@ DUK_LOCAL void duk__expr_nud(duk_compiler_ctx *comp_ctx, duk_ivalue *res) {
duk__emit_a_bc(comp_ctx,
DUK_OP_CLOSURE,
- (duk_regconst_t) reg_temp /*a*/,
+ reg_temp /*a*/,
(duk_regconst_t) fnum /*bc*/);
- duk__ivalue_regconst(res, (duk_regconst_t) reg_temp);
+ duk__ivalue_regconst(res, reg_temp);
return;
}
@@ -65828,8 +67370,8 @@ DUK_LOCAL void duk__expr_nud(duk_compiler_ctx *comp_ctx, duk_ivalue *res) {
* resolving cases (the specification description is a bit confusing).
*/
- duk_reg_t reg_temp;
- duk_reg_t reg_varbind;
+ duk_regconst_t reg_temp;
+ duk_regconst_t reg_varbind;
duk_regconst_t rc_varname;
if (comp_ctx->curr_func.is_strict) {
@@ -65839,24 +67381,24 @@ DUK_LOCAL void duk__expr_nud(duk_compiler_ctx *comp_ctx, duk_ivalue *res) {
DUK__SETTEMP(comp_ctx, temp_at_entry);
reg_temp = DUK__ALLOCTEMP(comp_ctx);
- duk_dup(ctx, res->x1.valstack_idx);
+ duk_dup(thr, res->x1.valstack_idx);
if (duk__lookup_lhs(comp_ctx, &reg_varbind, &rc_varname)) {
/* register bound variables are non-configurable -> always false */
duk__emit_bc(comp_ctx,
DUK_OP_LDFALSE,
- (duk_regconst_t) reg_temp);
+ reg_temp);
} else {
- duk_dup(ctx, res->x1.valstack_idx);
+ duk_dup(thr, res->x1.valstack_idx);
rc_varname = duk__getconst(comp_ctx);
duk__emit_a_bc(comp_ctx,
DUK_OP_DELVAR,
- (duk_regconst_t) reg_temp,
- (duk_regconst_t) rc_varname);
+ reg_temp,
+ rc_varname);
}
- duk__ivalue_regconst(res, (duk_regconst_t) reg_temp);
+ duk__ivalue_regconst(res, reg_temp);
} else if (res->t == DUK_IVAL_PROP) {
- duk_reg_t reg_temp;
- duk_reg_t reg_obj;
+ duk_regconst_t reg_temp;
+ duk_regconst_t reg_obj;
duk_regconst_t rc_key;
DUK__SETTEMP(comp_ctx, temp_at_entry);
@@ -65865,21 +67407,21 @@ DUK_LOCAL void duk__expr_nud(duk_compiler_ctx *comp_ctx, duk_ivalue *res) {
rc_key = duk__ispec_toregconst_raw(comp_ctx, &res->x2, -1 /*forced_reg*/, DUK__IVAL_FLAG_ALLOW_CONST /*flags*/);
duk__emit_a_b_c(comp_ctx,
DUK_OP_DELPROP | DUK__EMIT_FLAG_BC_REGCONST,
- (duk_regconst_t) reg_temp,
- (duk_regconst_t) reg_obj,
+ reg_temp,
+ reg_obj,
rc_key);
- duk__ivalue_regconst(res, (duk_regconst_t) reg_temp);
+ duk__ivalue_regconst(res, reg_temp);
} else {
/* non-Reference deletion is always 'true', even in strict mode */
- duk_push_true(ctx);
+ duk_push_true(thr);
goto plain_value;
}
return;
}
case DUK_TOK_VOID: {
duk__expr_toplain_ignore(comp_ctx, res, DUK__BP_MULTIPLICATIVE /*rbp_flags*/); /* UnaryExpression */
- duk_push_undefined(ctx);
+ duk_push_undefined(thr);
goto plain_value;
}
case DUK_TOK_TYPEOF: {
@@ -65891,11 +67433,11 @@ DUK_LOCAL void duk__expr_nud(duk_compiler_ctx *comp_ctx, duk_ivalue *res) {
duk__expr(comp_ctx, res, DUK__BP_MULTIPLICATIVE /*rbp_flags*/); /* UnaryExpression */
if (res->t == DUK_IVAL_VAR) {
- duk_reg_t reg_varbind;
+ duk_regconst_t reg_varbind;
duk_regconst_t rc_varname;
- duk_reg_t reg_temp;
+ duk_regconst_t reg_temp;
- duk_dup(ctx, res->x1.valstack_idx);
+ duk_dup(thr, res->x1.valstack_idx);
if (!duk__lookup_lhs(comp_ctx, &reg_varbind, &rc_varname)) {
DUK_DDD(DUK_DDDPRINT("typeof for an identifier name which could not be resolved "
"at compile time, need to use special run-time handling"));
@@ -65904,7 +67446,7 @@ DUK_LOCAL void duk__expr_nud(duk_compiler_ctx *comp_ctx, duk_ivalue *res) {
DUK_OP_TYPEOFID,
reg_temp,
rc_varname);
- duk__ivalue_regconst(res, (duk_regconst_t) reg_temp);
+ duk__ivalue_regconst(res, reg_temp);
return;
}
}
@@ -65924,7 +67466,7 @@ DUK_LOCAL void duk__expr_nud(duk_compiler_ctx *comp_ctx, duk_ivalue *res) {
/* unary plus */
duk__expr(comp_ctx, res, DUK__BP_MULTIPLICATIVE /*rbp_flags*/); /* UnaryExpression */
if (res->t == DUK_IVAL_PLAIN && res->x1.t == DUK_ISPEC_VALUE &&
- duk_is_number(ctx, res->x1.valstack_idx)) {
+ duk_is_number(thr, res->x1.valstack_idx)) {
/* unary plus of a number is identity */
return;
}
@@ -65935,14 +67477,14 @@ DUK_LOCAL void duk__expr_nud(duk_compiler_ctx *comp_ctx, duk_ivalue *res) {
/* unary minus */
duk__expr(comp_ctx, res, DUK__BP_MULTIPLICATIVE /*rbp_flags*/); /* UnaryExpression */
if (res->t == DUK_IVAL_PLAIN && res->x1.t == DUK_ISPEC_VALUE &&
- duk_is_number(ctx, res->x1.valstack_idx)) {
+ duk_is_number(thr, res->x1.valstack_idx)) {
/* this optimization is important to handle negative literals
* (which are not directly provided by the lexical grammar)
*/
duk_tval *tv_num;
duk_double_union du;
- tv_num = DUK_GET_TVAL_POSIDX(ctx, res->x1.valstack_idx);
+ tv_num = DUK_GET_TVAL_POSIDX(thr, res->x1.valstack_idx);
DUK_ASSERT(tv_num != NULL);
DUK_ASSERT(DUK_TVAL_IS_NUMBER(tv_num));
du.d = DUK_TVAL_GET_NUMBER(tv_num);
@@ -65967,7 +67509,7 @@ DUK_LOCAL void duk__expr_nud(duk_compiler_ctx *comp_ctx, duk_ivalue *res) {
*/
duk_tval *tv_val;
- tv_val = DUK_GET_TVAL_POSIDX(ctx, res->x1.valstack_idx);
+ tv_val = DUK_GET_TVAL_POSIDX(thr, res->x1.valstack_idx);
DUK_ASSERT(tv_val != NULL);
if (DUK_TVAL_IS_NUMBER(tv_val)) {
duk_double_t d;
@@ -65983,7 +67525,7 @@ DUK_LOCAL void duk__expr_nud(duk_compiler_ctx *comp_ctx, duk_ivalue *res) {
return;
}
} else if (DUK_TVAL_IS_BOOLEAN(tv_val)) {
- duk_small_int_t v;
+ duk_small_uint_t v;
v = DUK_TVAL_GET_BOOLEAN(tv_val);
DUK_DDD(DUK_DDDPRINT("inlined lnot boolean: %ld", (long) v));
DUK_ASSERT(v == 0 || v == 1);
@@ -66007,10 +67549,10 @@ DUK_LOCAL void duk__expr_nud(duk_compiler_ctx *comp_ctx, duk_ivalue *res) {
* bits of the opcode.
*/
- duk_reg_t reg_src, reg_res;
+ duk_regconst_t reg_src, reg_res;
reg_src = duk__ivalue_toregconst_raw(comp_ctx, res, -1 /*forced_reg*/, 0 /*flags*/);
- if (DUK__ISTEMP(comp_ctx, reg_src)) {
+ if (DUK__ISREG_TEMP(comp_ctx, reg_src)) {
reg_res = reg_src;
} else {
reg_res = DUK__ALLOCTEMP(comp_ctx);
@@ -66018,15 +67560,15 @@ DUK_LOCAL void duk__expr_nud(duk_compiler_ctx *comp_ctx, duk_ivalue *res) {
duk__emit_a_bc(comp_ctx,
args,
reg_res,
- (duk_regconst_t) reg_src);
- duk__ivalue_regconst(res, (duk_regconst_t) reg_res);
+ reg_src);
+ duk__ivalue_regconst(res, reg_res);
return;
}
preincdec:
{
/* preincrement and predecrement */
- duk_reg_t reg_res;
+ duk_regconst_t reg_res;
duk_small_uint_t args_op1 = args & 0xff; /* DUK_OP_PREINCR/DUK_OP_PREDECR */
duk_small_uint_t args_op2 = args >> 8; /* DUK_OP_PREINCP_RR/DUK_OP_PREDECP_RR */
@@ -66039,39 +67581,39 @@ DUK_LOCAL void duk__expr_nud(duk_compiler_ctx *comp_ctx, duk_ivalue *res) {
duk__expr(comp_ctx, res, DUK__BP_MULTIPLICATIVE /*rbp_flags*/); /* UnaryExpression */
if (res->t == DUK_IVAL_VAR) {
duk_hstring *h_varname;
- duk_reg_t reg_varbind;
+ duk_regconst_t reg_varbind;
duk_regconst_t rc_varname;
- h_varname = duk_known_hstring(ctx, res->x1.valstack_idx);
+ h_varname = duk_known_hstring(thr, res->x1.valstack_idx);
if (duk__hstring_is_eval_or_arguments_in_strict_mode(comp_ctx, h_varname)) {
goto syntax_error;
}
- duk_dup(ctx, res->x1.valstack_idx);
+ duk_dup(thr, res->x1.valstack_idx);
if (duk__lookup_lhs(comp_ctx, &reg_varbind, &rc_varname)) {
duk__emit_a_bc(comp_ctx,
args_op1, /* e.g. DUK_OP_PREINCR */
- (duk_regconst_t) reg_res,
- (duk_regconst_t) reg_varbind);
+ reg_res,
+ reg_varbind);
} else {
duk__emit_a_bc(comp_ctx,
args_op1 + 4, /* e.g. DUK_OP_PREINCV */
- (duk_regconst_t) reg_res,
+ reg_res,
rc_varname);
}
DUK_DDD(DUK_DDDPRINT("preincdec to '%!O' -> reg_varbind=%ld, rc_varname=%ld",
(duk_heaphdr *) h_varname, (long) reg_varbind, (long) rc_varname));
} else if (res->t == DUK_IVAL_PROP) {
- duk_reg_t reg_obj; /* allocate to reg only (not const) */
+ duk_regconst_t reg_obj; /* allocate to reg only (not const) */
duk_regconst_t rc_key;
reg_obj = duk__ispec_toregconst_raw(comp_ctx, &res->x1, -1 /*forced_reg*/, 0 /*flags*/); /* don't allow const */
rc_key = duk__ispec_toregconst_raw(comp_ctx, &res->x2, -1 /*forced_reg*/, DUK__IVAL_FLAG_ALLOW_CONST /*flags*/);
duk__emit_a_b_c(comp_ctx,
args_op2 | DUK__EMIT_FLAG_BC_REGCONST, /* e.g. DUK_OP_PREINCP */
- (duk_regconst_t) reg_res,
- (duk_regconst_t) reg_obj,
+ reg_res,
+ reg_obj,
rc_key);
} else {
/* Technically return value is not needed because INVLHS will
@@ -66088,7 +67630,7 @@ DUK_LOCAL void duk__expr_nud(duk_compiler_ctx *comp_ctx, duk_ivalue *res) {
DUK_OP_INVLHS);
}
DUK__SETTEMP(comp_ctx, reg_res + 1);
- duk__ivalue_regconst(res, (duk_regconst_t) reg_res);
+ duk__ivalue_regconst(res, reg_res);
return;
}
@@ -66099,6 +67641,11 @@ DUK_LOCAL void duk__expr_nud(duk_compiler_ctx *comp_ctx, duk_ivalue *res) {
return;
}
+#if defined(DUK_USE_ES6)
+ syntax_error_newtarget:
+ DUK_ERROR_SYNTAX(thr, DUK_STR_INVALID_NEWTARGET);
+#endif
+
syntax_error:
DUK_ERROR_SYNTAX(thr, DUK_STR_INVALID_EXPRESSION);
}
@@ -66109,9 +67656,8 @@ DUK_LOCAL void duk__expr_nud(duk_compiler_ctx *comp_ctx, duk_ivalue *res) {
*/
DUK_LOCAL void duk__expr_led(duk_compiler_ctx *comp_ctx, duk_ivalue *left, duk_ivalue *res) {
duk_hthread *thr = comp_ctx->thr;
- duk_context *ctx = (duk_context *) thr;
duk_token *tk;
- duk_small_int_t tok;
+ duk_small_uint_t tok;
duk_uint32_t args; /* temp variable to pass constants and flags to shared code */
/*
@@ -66161,8 +67707,8 @@ DUK_LOCAL void duk__expr_led(duk_compiler_ctx *comp_ctx, duk_ivalue *left, duk_i
res->t = DUK_IVAL_PROP;
duk__copy_ispec(comp_ctx, &left->x1, &res->x1); /* left.x1 -> res.x1 */
DUK_ASSERT(comp_ctx->curr_token.str1 != NULL);
- duk_push_hstring(ctx, comp_ctx->curr_token.str1);
- duk_replace(ctx, res->x2.valstack_idx);
+ duk_push_hstring(thr, comp_ctx->curr_token.str1);
+ duk_replace(thr, res->x2.valstack_idx);
res->x2.t = DUK_ISPEC_VALUE;
/* special RegExp literal handling after IdentifierName */
@@ -66204,9 +67750,9 @@ DUK_LOCAL void duk__expr_led(duk_compiler_ctx *comp_ctx, duk_ivalue *left, duk_i
}
case DUK_TOK_LPAREN: {
/* function call */
- duk_reg_t reg_cs = DUK__ALLOCTEMPS(comp_ctx, 2);
+ duk_regconst_t reg_cs = DUK__ALLOCTEMPS(comp_ctx, 2);
duk_int_t nargs;
- duk_small_uint_t call_op = DUK_OP_CALL;
+ duk_small_uint_t call_op = DUK_OP_CALL0;
/* XXX: attempt to get the call result to "next temp" whenever
* possible to avoid unnecessary register shuffles.
@@ -66222,12 +67768,12 @@ DUK_LOCAL void duk__expr_led(duk_compiler_ctx *comp_ctx, duk_ivalue *left, duk_i
if (left->t == DUK_IVAL_VAR) {
duk_hstring *h_varname;
- duk_reg_t reg_varbind;
+ duk_regconst_t reg_varbind;
duk_regconst_t rc_varname;
DUK_DDD(DUK_DDDPRINT("function call with identifier base"));
- h_varname = duk_known_hstring(ctx, left->x1.valstack_idx);
+ h_varname = duk_known_hstring(thr, left->x1.valstack_idx);
if (h_varname == DUK_HTHREAD_STRING_EVAL(thr)) {
/* Potential direct eval call detected, flag the CALL
* so that a run-time "direct eval" check is made and
@@ -66237,16 +67783,16 @@ DUK_LOCAL void duk__expr_led(duk_compiler_ctx *comp_ctx, duk_ivalue *left, duk_i
DUK_DDD(DUK_DDDPRINT("function call with identifier 'eval' "
"-> using EVALCALL, marking function "
"as may_direct_eval"));
- call_op = DUK_OP_EVALCALL;
+ call_op |= DUK_BC_CALL_FLAG_CALLED_AS_EVAL;
comp_ctx->curr_func.may_direct_eval = 1;
}
- duk_dup(ctx, left->x1.valstack_idx);
+ duk_dup(thr, left->x1.valstack_idx);
if (duk__lookup_lhs(comp_ctx, &reg_varbind, &rc_varname)) {
duk__emit_a_bc(comp_ctx,
DUK_OP_CSREG | DUK__EMIT_FLAG_A_IS_SOURCE,
- (duk_regconst_t) reg_varbind,
- (duk_regconst_t) (reg_cs + 0));
+ reg_varbind,
+ reg_cs + 0);
} else {
/* XXX: expand target register or constant field to
* reduce shuffling.
@@ -66254,7 +67800,7 @@ DUK_LOCAL void duk__expr_led(duk_compiler_ctx *comp_ctx, duk_ivalue *left, duk_i
DUK_ASSERT(DUK__ISCONST(rc_varname));
duk__emit_a_b(comp_ctx,
DUK_OP_CSVAR | DUK__EMIT_FLAG_BC_REGCONST,
- (duk_regconst_t) (reg_cs + 0),
+ reg_cs + 0,
rc_varname);
}
} else if (left->t == DUK_IVAL_PROP) {
@@ -66263,34 +67809,61 @@ DUK_LOCAL void duk__expr_led(duk_compiler_ctx *comp_ctx, duk_ivalue *left, duk_i
* but a typical call setup took 3 opcodes (e.g. LDREG, LDCONST,
* CSPROP) and the same can be achieved with ordinary loads.
*/
+#if defined(DUK_USE_VERBOSE_ERRORS)
+ duk_regconst_t reg_key;
+#endif
+
DUK_DDD(DUK_DDDPRINT("function call with property base"));
+ /* XXX: For Math.sin() this generates: LDCONST + LDREG +
+ * GETPROPC + call. The LDREG is unnecessary because LDCONST
+ * could be loaded directly into reg_cs + 1. This doesn't
+ * happen now because a variable cannot be in left->x1 of a
+ * DUK_IVAL_PROP. We could notice that left->x1 is a temp
+ * and reuse, but it would still be in the wrong position
+ * (reg_cs + 0 rather than reg_cs + 1).
+ */
duk__ispec_toforcedreg(comp_ctx, &left->x1, reg_cs + 1); /* base */
+#if defined(DUK_USE_VERBOSE_ERRORS)
+ reg_key = duk__ispec_toregconst_raw(comp_ctx, &left->x2, -1, DUK__IVAL_FLAG_ALLOW_CONST /*flags*/);
+ duk__emit_a_b_c(comp_ctx,
+ DUK_OP_GETPROPC | DUK__EMIT_FLAG_BC_REGCONST,
+ reg_cs + 0,
+ reg_cs + 1,
+ reg_key);
+#else
duk__ivalue_toforcedreg(comp_ctx, left, reg_cs + 0); /* base[key] */
+#endif
} else {
DUK_DDD(DUK_DDDPRINT("function call with register base"));
duk__ivalue_toforcedreg(comp_ctx, left, reg_cs + 0);
+#if 0
duk__emit_a_bc(comp_ctx,
DUK_OP_CSREG | DUK__EMIT_FLAG_A_IS_SOURCE,
- (duk_regconst_t) (reg_cs + 0),
- (duk_regconst_t) (reg_cs + 0)); /* in-place setup */
+ reg_cs + 0,
+ reg_cs + 0); /* in-place setup */
+#endif
+ /* Because of in-place setup, REGCS is equivalent to
+ * just this LDUNDEF.
+ */
+ duk__emit_bc(comp_ctx, DUK_OP_LDUNDEF, reg_cs + 1);
}
DUK__SETTEMP(comp_ctx, reg_cs + 2);
nargs = duk__parse_arguments(comp_ctx, res); /* parse args starting from "next temp" */
- /* Tailcalls are handled by back-patching the opcode to TAILCALL to the
- * already emitted instruction later (in return statement parser).
+ /* Tailcalls are handled by back-patching the already emitted opcode
+ * later in return statement parser.
*/
duk__emit_a_bc(comp_ctx,
- call_op | DUK__EMIT_FLAG_NO_SHUFFLE_A,
+ call_op,
(duk_regconst_t) nargs /*numargs*/,
- (duk_regconst_t) reg_cs /*basereg*/);
+ reg_cs /*basereg*/);
DUK__SETTEMP(comp_ctx, reg_cs + 1); /* result in csreg */
- duk__ivalue_regconst(res, (duk_regconst_t) reg_cs);
+ duk__ivalue_regconst(res, reg_cs);
return;
}
@@ -66439,7 +68012,7 @@ DUK_LOCAL void duk__expr_led(duk_compiler_ctx *comp_ctx, duk_ivalue *left, duk_i
/* XXX: common reg allocation need is to reuse a sub-expression's temp reg,
* but only if it really is a temp. Nothing fancy here now.
*/
- duk_reg_t reg_temp;
+ duk_regconst_t reg_temp;
duk_int_t pc_jump1;
duk_int_t pc_jump2;
@@ -66455,7 +68028,7 @@ DUK_LOCAL void duk__expr_led(duk_compiler_ctx *comp_ctx, duk_ivalue *left, duk_i
duk__patch_jump_here(comp_ctx, pc_jump2);
DUK__SETTEMP(comp_ctx, reg_temp + 1);
- duk__ivalue_regconst(res, (duk_regconst_t) reg_temp);
+ duk__ivalue_regconst(res, reg_temp);
return;
}
@@ -66586,11 +68159,11 @@ DUK_LOCAL void duk__expr_led(duk_compiler_ctx *comp_ctx, duk_ivalue *left, duk_i
res->x2.t = res->x1.t;
res->x2.regconst = res->x1.regconst;
- duk_copy(ctx, res->x1.valstack_idx, res->x2.valstack_idx);
+ duk_copy(thr, res->x1.valstack_idx, res->x2.valstack_idx);
res->x1.t = left->x1.t;
res->x1.regconst = left->x1.regconst;
- duk_copy(ctx, left->x1.valstack_idx, res->x1.valstack_idx);
+ duk_copy(thr, left->x1.valstack_idx, res->x1.valstack_idx);
DUK_DDD(DUK_DDDPRINT("binary op, res: t=%ld, x1.t=%ld, x1.regconst=0x%08lx, x2.t=%ld, x2.regconst=0x%08lx",
(long) res->t, (long) res->x1.t, (unsigned long) res->x1.regconst, (long) res->x2.t, (unsigned long) res->x2.regconst));
@@ -66618,7 +68191,7 @@ DUK_LOCAL void duk__expr_led(duk_compiler_ctx *comp_ctx, duk_ivalue *left, duk_i
*/
{
- duk_reg_t reg_temp;
+ duk_regconst_t reg_temp;
duk_int_t pc_jump;
duk_small_uint_t args_truthval = args >> 8;
duk_small_uint_t args_rbp = args & 0xff;
@@ -66631,12 +68204,12 @@ DUK_LOCAL void duk__expr_led(duk_compiler_ctx *comp_ctx, duk_ivalue *left, duk_i
DUK_ASSERT(DUK__ISREG(reg_temp));
duk__emit_bc(comp_ctx,
(args_truthval ? DUK_OP_IFTRUE_R : DUK_OP_IFFALSE_R),
- (duk_regconst_t) reg_temp); /* skip jump conditionally */
+ reg_temp); /* skip jump conditionally */
pc_jump = duk__emit_jump_empty(comp_ctx);
duk__expr_toforcedreg(comp_ctx, res, args_rbp /*rbp_flags*/, reg_temp /*forced_reg*/);
duk__patch_jump_here(comp_ctx, pc_jump);
- duk__ivalue_regconst(res, (duk_regconst_t) reg_temp);
+ duk__ivalue_regconst(res, reg_temp);
return;
}
@@ -66701,17 +68274,17 @@ DUK_LOCAL void duk__expr_led(duk_compiler_ctx *comp_ctx, duk_ivalue *left, duk_i
if (left->t == DUK_IVAL_VAR) {
duk_hstring *h_varname;
- duk_reg_t reg_varbind;
+ duk_regconst_t reg_varbind;
duk_regconst_t rc_varname;
DUK_ASSERT(left->x1.t == DUK_ISPEC_VALUE); /* LHS is already side effect free */
- h_varname = duk_known_hstring(ctx, left->x1.valstack_idx);
+ h_varname = duk_known_hstring(thr, left->x1.valstack_idx);
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);
+ duk_dup(thr, left->x1.valstack_idx);
(void) duk__lookup_lhs(comp_ctx, &reg_varbind, &rc_varname);
if (args_op == DUK_OP_NONE) {
@@ -66723,8 +68296,7 @@ DUK_LOCAL void duk__expr_led(duk_compiler_ctx *comp_ctx, duk_ivalue *left, duk_i
/* '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__ISREG_NOTTEMP(comp_ctx, res->x1.regconst))) {
duk__ivalue_totempconst(comp_ctx, res);
}
}
@@ -66734,13 +68306,13 @@ DUK_LOCAL void duk__expr_led(duk_compiler_ctx *comp_ctx, duk_ivalue *left, duk_i
* can change X, but when we do <op> we must use
* the pre-op value.
*/
- duk_reg_t reg_temp;
+ duk_regconst_t reg_temp;
reg_temp = DUK__ALLOCTEMP(comp_ctx);
if (reg_varbind >= 0) {
- duk_reg_t reg_res;
- duk_reg_t reg_src;
+ duk_regconst_t reg_res;
+ duk_regconst_t reg_src;
duk_int_t pc_temp_load;
duk_int_t pc_before_rhs;
duk_int_t pc_after_rhs;
@@ -66771,7 +68343,7 @@ DUK_LOCAL void duk__expr_led(duk_compiler_ctx *comp_ctx, duk_ivalue *left, duk_i
pc_temp_load = duk__get_current_pc(comp_ctx);
duk__emit_a_bc(comp_ctx,
DUK_OP_LDREG,
- (duk_regconst_t) reg_temp,
+ reg_temp,
reg_varbind);
pc_before_rhs = duk__get_current_pc(comp_ctx);
@@ -66789,7 +68361,7 @@ DUK_LOCAL void duk__expr_led(duk_compiler_ctx *comp_ctx, duk_ivalue *left, duk_i
* one instruction, so use explicit PC computation.
*/
DUK_DD(DUK_DDPRINT("rhs is side effect free, rewind and avoid unnecessary temp for reg-based <op>="));
- DUK_BW_ADD_PTR(comp_ctx->thr, &comp_ctx->curr_func.bw_code, (pc_temp_load - pc_before_rhs) * sizeof(duk_compiler_instr));
+ DUK_BW_ADD_PTR(comp_ctx->thr, &comp_ctx->curr_func.bw_code, (duk_size_t) (pc_temp_load - pc_before_rhs) * sizeof(duk_compiler_instr));
reg_src = reg_varbind;
} else {
DUK_DD(DUK_DDPRINT("rhs evaluation emitted code, not sure if rhs is side effect free; use temp reg for LHS"));
@@ -66798,14 +68370,14 @@ DUK_LOCAL void duk__expr_led(duk_compiler_ctx *comp_ctx, duk_ivalue *left, duk_i
duk__emit_a_b_c(comp_ctx,
args_op | DUK__EMIT_FLAG_BC_REGCONST,
- (duk_regconst_t) reg_res,
- (duk_regconst_t) reg_src,
+ reg_res,
+ reg_src,
res->x1.regconst);
- res->x1.regconst = (duk_regconst_t) reg_res;
+ res->x1.regconst = reg_res;
/* Ensure compact use of temps. */
- if (DUK__ISTEMP(comp_ctx, reg_res)) {
+ if (DUK__ISREG_TEMP(comp_ctx, reg_res)) {
DUK__SETTEMP(comp_ctx, reg_res + 1);
}
} else {
@@ -66815,7 +68387,7 @@ DUK_LOCAL void duk__expr_led(duk_compiler_ctx *comp_ctx, duk_ivalue *left, duk_i
duk__emit_a_bc(comp_ctx,
DUK_OP_GETVAR,
- (duk_regconst_t) reg_temp,
+ reg_temp,
rc_varname);
duk__expr_toregconst(comp_ctx, res, args_rbp /*rbp_flags*/);
@@ -66823,10 +68395,10 @@ DUK_LOCAL void duk__expr_led(duk_compiler_ctx *comp_ctx, duk_ivalue *left, duk_i
duk__emit_a_b_c(comp_ctx,
args_op | DUK__EMIT_FLAG_BC_REGCONST,
- (duk_regconst_t) reg_temp,
- (duk_regconst_t) reg_temp,
+ reg_temp,
+ reg_temp,
res->x1.regconst);
- res->x1.regconst = (duk_regconst_t) reg_temp;
+ res->x1.regconst = reg_temp;
}
DUK_ASSERT(res->t == DUK_IVAL_PLAIN && res->x1.t == DUK_ISPEC_REGCONST);
@@ -66879,10 +68451,10 @@ DUK_LOCAL void duk__expr_led(duk_compiler_ctx *comp_ctx, duk_ivalue *left, duk_i
/* '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;
+ duk_regconst_t reg_obj;
duk_regconst_t rc_key;
duk_regconst_t rc_res;
- duk_reg_t reg_temp;
+ duk_regconst_t reg_temp;
/* Property access expressions ('a[b]') are critical to correct
* LHS evaluation ordering, see test-dev-assign-eval-order*.js.
@@ -66915,8 +68487,8 @@ DUK_LOCAL void duk__expr_led(duk_compiler_ctx *comp_ctx, duk_ivalue *left, duk_i
reg_temp = DUK__ALLOCTEMP(comp_ctx);
duk__emit_a_b_c(comp_ctx,
DUK_OP_GETPROP | DUK__EMIT_FLAG_BC_REGCONST,
- (duk_regconst_t) reg_temp,
- (duk_regconst_t) reg_obj,
+ reg_temp,
+ reg_obj,
rc_key);
duk__expr_toregconst(comp_ctx, res, args_rbp /*rbp_flags*/);
@@ -66924,19 +68496,19 @@ DUK_LOCAL void duk__expr_led(duk_compiler_ctx *comp_ctx, duk_ivalue *left, duk_i
duk__emit_a_b_c(comp_ctx,
args_op | DUK__EMIT_FLAG_BC_REGCONST,
- (duk_regconst_t) reg_temp,
- (duk_regconst_t) reg_temp,
+ reg_temp,
+ reg_temp,
res->x1.regconst);
- rc_res = (duk_regconst_t) reg_temp;
+ rc_res = reg_temp;
}
duk__emit_a_b_c(comp_ctx,
DUK_OP_PUTPROP | DUK__EMIT_FLAG_A_IS_SOURCE | DUK__EMIT_FLAG_BC_REGCONST,
- (duk_regconst_t) reg_obj,
+ reg_obj,
rc_key,
rc_res);
- duk__ivalue_regconst(res, (duk_regconst_t) rc_res);
+ duk__ivalue_regconst(res, rc_res);
} else {
/* No support for lvalues returned from new or function call expressions.
* However, these must NOT cause compile-time SyntaxErrors, but run-time
@@ -66962,7 +68534,7 @@ DUK_LOCAL void duk__expr_led(duk_compiler_ctx *comp_ctx, duk_ivalue *left, duk_i
duk__emit_op_only(comp_ctx, DUK_OP_INVLHS);
- duk__ivalue_regconst(res, (duk_regconst_t) rc_res);
+ duk__ivalue_regconst(res, rc_res);
}
return;
@@ -66981,7 +68553,7 @@ DUK_LOCAL void duk__expr_led(duk_compiler_ctx *comp_ctx, duk_ivalue *left, duk_i
* the previous expression if a LineTerminator occurs before '++'/'--'.
*/
- duk_reg_t reg_res;
+ duk_regconst_t reg_res;
duk_small_uint_t args_op1 = (args >> 8) & 0xff; /* DUK_OP_POSTINCR/DUK_OP_POSTDECR */
duk_small_uint_t args_op2 = args >> 16; /* DUK_OP_POSTINCP_RR/DUK_OP_POSTDECP_RR */
@@ -66993,40 +68565,40 @@ DUK_LOCAL void duk__expr_led(duk_compiler_ctx *comp_ctx, duk_ivalue *left, duk_i
if (left->t == DUK_IVAL_VAR) {
duk_hstring *h_varname;
- duk_reg_t reg_varbind;
+ duk_regconst_t reg_varbind;
duk_regconst_t rc_varname;
- h_varname = duk_known_hstring(ctx, left->x1.valstack_idx);
+ h_varname = duk_known_hstring(thr, left->x1.valstack_idx);
if (duk__hstring_is_eval_or_arguments_in_strict_mode(comp_ctx, h_varname)) {
goto syntax_error;
}
- duk_dup(ctx, left->x1.valstack_idx);
+ duk_dup(thr, left->x1.valstack_idx);
if (duk__lookup_lhs(comp_ctx, &reg_varbind, &rc_varname)) {
duk__emit_a_bc(comp_ctx,
args_op1, /* e.g. DUK_OP_POSTINCR */
- (duk_regconst_t) reg_res,
- (duk_regconst_t) reg_varbind);
+ reg_res,
+ reg_varbind);
} else {
duk__emit_a_bc(comp_ctx,
args_op1 + 4, /* e.g. DUK_OP_POSTINCV */
- (duk_regconst_t) reg_res,
+ reg_res,
rc_varname);
}
DUK_DDD(DUK_DDDPRINT("postincdec to '%!O' -> reg_varbind=%ld, rc_varname=%ld",
(duk_heaphdr *) h_varname, (long) reg_varbind, (long) rc_varname));
} else if (left->t == DUK_IVAL_PROP) {
- duk_reg_t reg_obj; /* allocate to reg only (not const) */
+ duk_regconst_t reg_obj; /* allocate to reg only (not const) */
duk_regconst_t rc_key;
reg_obj = duk__ispec_toregconst_raw(comp_ctx, &left->x1, -1 /*forced_reg*/, 0 /*flags*/); /* don't allow const */
rc_key = duk__ispec_toregconst_raw(comp_ctx, &left->x2, -1 /*forced_reg*/, DUK__IVAL_FLAG_ALLOW_CONST /*flags*/);
duk__emit_a_b_c(comp_ctx,
args_op2 | DUK__EMIT_FLAG_BC_REGCONST, /* e.g. DUK_OP_POSTINCP */
- (duk_regconst_t) reg_res,
- (duk_regconst_t) reg_obj,
+ reg_res,
+ reg_obj,
rc_key);
} else {
/* Technically return value is not needed because INVLHS will
@@ -67043,7 +68615,7 @@ DUK_LOCAL void duk__expr_led(duk_compiler_ctx *comp_ctx, duk_ivalue *left, duk_i
}
DUK__SETTEMP(comp_ctx, reg_res + 1);
- duk__ivalue_regconst(res, (duk_regconst_t) reg_res);
+ duk__ivalue_regconst(res, reg_res);
return;
}
@@ -67057,9 +68629,10 @@ DUK_LOCAL void duk__expr_led(duk_compiler_ctx *comp_ctx, duk_ivalue *left, duk_i
}
DUK_LOCAL duk_small_uint_t duk__expr_lbp(duk_compiler_ctx *comp_ctx) {
- duk_small_int_t tok = comp_ctx->curr_token.t;
+ duk_small_uint_t tok = comp_ctx->curr_token.t;
- DUK_ASSERT(tok >= DUK_TOK_MINVAL && tok <= DUK_TOK_MAXVAL);
+ DUK_ASSERT_DISABLE(tok >= DUK_TOK_MINVAL); /* unsigned */
+ DUK_ASSERT(tok <= DUK_TOK_MAXVAL);
DUK_ASSERT(sizeof(duk__token_lbp) == DUK_TOK_MAXVAL + 1);
/* XXX: integrate support for this into led() instead?
@@ -67102,14 +68675,13 @@ DUK_LOCAL duk_small_uint_t duk__expr_lbp(duk_compiler_ctx *comp_ctx) {
/* main expression parser function */
DUK_LOCAL void duk__expr(duk_compiler_ctx *comp_ctx, duk_ivalue *res, duk_small_uint_t rbp_flags) {
duk_hthread *thr = comp_ctx->thr;
- duk_context *ctx = (duk_context *) thr;
duk_ivalue tmp_alloc; /* 'res' is used for "left", and 'tmp' for "right" */
duk_ivalue *tmp = &tmp_alloc;
duk_small_uint_t rbp;
DUK__RECURSION_INCREASE(comp_ctx, thr);
- duk_require_stack(ctx, DUK__PARSE_EXPR_SLOTS);
+ duk_require_stack(thr, DUK__PARSE_EXPR_SLOTS);
/* filter out flags from exprtop rbp_flags here to save space */
rbp = rbp_flags & DUK__EXPR_RBP_MASK;
@@ -67119,10 +68691,10 @@ DUK_LOCAL void duk__expr(duk_compiler_ctx *comp_ctx, duk_ivalue *res, duk_small_
(long) comp_ctx->curr_func.paren_level));
DUK_MEMZERO(&tmp_alloc, sizeof(tmp_alloc));
- tmp->x1.valstack_idx = duk_get_top(ctx);
+ tmp->x1.valstack_idx = duk_get_top(thr);
tmp->x2.valstack_idx = tmp->x1.valstack_idx + 1;
- duk_push_undefined(ctx);
- duk_push_undefined(ctx);
+ duk_push_undefined(thr);
+ duk_push_undefined(thr);
/* XXX: where to release temp regs in intermediate expressions?
* e.g. 1+2+3 -> don't inflate temp register count when parsing this.
@@ -67139,7 +68711,7 @@ DUK_LOCAL void duk__expr(duk_compiler_ctx *comp_ctx, duk_ivalue *res, duk_small_
if (!(rbp_flags & DUK__EXPR_FLAG_ALLOW_EMPTY)) {
DUK_ERROR_SYNTAX(thr, DUK_STR_EMPTY_EXPR_NOT_ALLOWED);
}
- duk_push_undefined(ctx);
+ duk_push_undefined(thr);
duk__ivalue_plain_fromstack(comp_ctx, res);
goto cleanup;
}
@@ -67155,7 +68727,7 @@ DUK_LOCAL void duk__expr(duk_compiler_ctx *comp_ctx, duk_ivalue *res, duk_small_
cleanup:
/* final result is already in 'res' */
- duk_pop_2(ctx);
+ duk_pop_2(thr);
DUK__RECURSION_DECREASE(comp_ctx, thr);
}
@@ -67186,20 +68758,20 @@ DUK_LOCAL void duk__exprtop(duk_compiler_ctx *comp_ctx, duk_ivalue *res, duk_sma
*/
#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_LOCAL duk_regconst_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_totemp(duk_compiler_ctx *comp_ctx, duk_ivalue *res, duk_small_uint_t rbp_flags) {
+DUK_LOCAL duk_regconst_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_totemp(comp_ctx, res);
}
#endif
-DUK_LOCAL 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 void duk__expr_toforcedreg(duk_compiler_ctx *comp_ctx, duk_ivalue *res, duk_small_uint_t rbp_flags, duk_regconst_t forced_reg) {
DUK_ASSERT(forced_reg >= 0);
duk__expr(comp_ctx, res, rbp_flags);
duk__ivalue_toforcedreg(comp_ctx, res, forced_reg);
@@ -67227,19 +68799,19 @@ DUK_LOCAL void duk__expr_toplain_ignore(duk_compiler_ctx *comp_ctx, duk_ivalue *
duk__ivalue_toplain_ignore(comp_ctx, res);
}
-DUK_LOCAL duk_reg_t duk__exprtop_toreg(duk_compiler_ctx *comp_ctx, duk_ivalue *res, duk_small_uint_t rbp_flags) {
+DUK_LOCAL duk_regconst_t duk__exprtop_toreg(duk_compiler_ctx *comp_ctx, duk_ivalue *res, duk_small_uint_t rbp_flags) {
duk__exprtop(comp_ctx, res, rbp_flags);
return duk__ivalue_toreg(comp_ctx, res);
}
#if 0 /* unused */
-DUK_LOCAL duk_reg_t duk__exprtop_totemp(duk_compiler_ctx *comp_ctx, duk_ivalue *res, duk_small_uint_t rbp_flags) {
+DUK_LOCAL duk_regconst_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_totemp(comp_ctx, res);
}
#endif
-DUK_LOCAL 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 void duk__exprtop_toforcedreg(duk_compiler_ctx *comp_ctx, duk_ivalue *res, duk_small_uint_t rbp_flags, duk_regconst_t forced_reg) {
DUK_ASSERT(forced_reg >= 0);
duk__exprtop(comp_ctx, res, rbp_flags);
duk__ivalue_toforcedreg(comp_ctx, res, forced_reg);
@@ -67293,11 +68865,10 @@ DUK_LOCAL void duk__exprtop_toplain_ignore(duk_compiler_ctx *comp_ctx, duk_ivalu
* as is done in 'for-in' parsing.
*/
-DUK_LOCAL void duk__parse_var_decl(duk_compiler_ctx *comp_ctx, duk_ivalue *res, duk_small_uint_t expr_flags, duk_reg_t *out_reg_varbind, duk_regconst_t *out_rc_varname) {
+DUK_LOCAL void duk__parse_var_decl(duk_compiler_ctx *comp_ctx, duk_ivalue *res, duk_small_uint_t expr_flags, duk_regconst_t *out_reg_varbind, duk_regconst_t *out_rc_varname) {
duk_hthread *thr = comp_ctx->thr;
- duk_context *ctx = (duk_context *) thr;
duk_hstring *h_varname;
- duk_reg_t reg_varbind;
+ duk_regconst_t reg_varbind;
duk_regconst_t rc_varname;
/* assume 'var' has been eaten */
@@ -67320,17 +68891,17 @@ DUK_LOCAL void duk__parse_var_decl(duk_compiler_ctx *comp_ctx, duk_ivalue *res,
duk_uarridx_t n;
DUK_DDD(DUK_DDDPRINT("register variable declaration %!O in pass 1",
(duk_heaphdr *) h_varname));
- n = (duk_uarridx_t) duk_get_length(ctx, comp_ctx->curr_func.decls_idx);
- duk_push_hstring(ctx, h_varname);
- duk_put_prop_index(ctx, comp_ctx->curr_func.decls_idx, n);
- duk_push_int(ctx, DUK_DECL_TYPE_VAR + (0 << 8));
- duk_put_prop_index(ctx, comp_ctx->curr_func.decls_idx, n + 1);
+ n = (duk_uarridx_t) duk_get_length(thr, comp_ctx->curr_func.decls_idx);
+ duk_push_hstring(thr, h_varname);
+ duk_put_prop_index(thr, comp_ctx->curr_func.decls_idx, n);
+ duk_push_int(thr, DUK_DECL_TYPE_VAR + (0 << 8));
+ duk_put_prop_index(thr, comp_ctx->curr_func.decls_idx, n + 1);
}
- duk_push_hstring(ctx, h_varname); /* push before advancing to keep reachable */
+ duk_push_hstring(thr, h_varname); /* push before advancing to keep reachable */
/* register binding lookup is based on varmap (even in first pass) */
- duk_dup_top(ctx);
+ duk_dup_top(thr);
(void) duk__lookup_lhs(comp_ctx, &reg_varbind, &rc_varname);
duk__advance(comp_ctx); /* eat identifier */
@@ -67346,11 +68917,11 @@ DUK_LOCAL void duk__parse_var_decl(duk_compiler_ctx *comp_ctx, duk_ivalue *res,
if (reg_varbind >= 0) {
duk__ivalue_toforcedreg(comp_ctx, res, reg_varbind);
} else {
- duk_reg_t reg_val;
+ duk_regconst_t reg_val;
reg_val = duk__ivalue_toreg(comp_ctx, res);
duk__emit_a_bc(comp_ctx,
DUK_OP_PUTVAR | DUK__EMIT_FLAG_A_IS_SOURCE,
- (duk_regconst_t) reg_val,
+ reg_val,
rc_varname);
}
} else {
@@ -67360,7 +68931,7 @@ DUK_LOCAL void duk__parse_var_decl(duk_compiler_ctx *comp_ctx, duk_ivalue *res,
}
}
- duk_pop(ctx); /* pop varname */
+ duk_pop(thr); /* pop varname */
*out_rc_varname = rc_varname;
*out_reg_varbind = reg_varbind;
@@ -67372,7 +68943,7 @@ DUK_LOCAL void duk__parse_var_decl(duk_compiler_ctx *comp_ctx, duk_ivalue *res,
}
DUK_LOCAL void duk__parse_var_stmt(duk_compiler_ctx *comp_ctx, duk_ivalue *res, duk_small_uint_t expr_flags) {
- duk_reg_t reg_varbind;
+ duk_regconst_t reg_varbind;
duk_regconst_t rc_varname;
duk__advance(comp_ctx); /* eat 'var' */
@@ -67390,10 +68961,9 @@ 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.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 */
+ duk_int_t pc_v34_lhs; /* start variant 3/4 left-hand-side code (L1 in doc/compiler.rst example) */
+ duk_regconst_t temp_reset; /* knock back "next temp" to this whenever possible */
+ duk_regconst_t reg_temps; /* preallocated temporaries (2) for variants 3 and 4 */
DUK_DDD(DUK_DDDPRINT("start parsing a for/for-in statement"));
@@ -67436,7 +69006,7 @@ DUK_LOCAL void duk__parse_for_stmt(duk_compiler_ctx *comp_ctx, duk_ivalue *res,
* Variant 2 or 4
*/
- duk_reg_t reg_varbind; /* variable binding register if register-bound (otherwise < 0) */
+ duk_regconst_t reg_varbind; /* variable binding register if register-bound (otherwise < 0) */
duk_regconst_t rc_varname; /* variable name reg/const, if variable not register-bound */
duk__advance(comp_ctx); /* eat 'var' */
@@ -67453,12 +69023,12 @@ DUK_LOCAL void duk__parse_for_stmt(duk_compiler_ctx *comp_ctx, duk_ivalue *res,
if (reg_varbind >= 0) {
duk__emit_a_bc(comp_ctx,
DUK_OP_LDREG,
- (duk_regconst_t) reg_varbind,
- (duk_regconst_t) (reg_temps + 0));
+ reg_varbind,
+ reg_temps + 0);
} else {
duk__emit_a_bc(comp_ctx,
DUK_OP_PUTVAR | DUK__EMIT_FLAG_A_IS_SOURCE,
- (duk_regconst_t) (reg_temps + 0),
+ reg_temps + 0,
rc_varname);
}
goto parse_3_or_4;
@@ -67505,34 +69075,34 @@ DUK_LOCAL void duk__parse_for_stmt(duk_compiler_ctx *comp_ctx, duk_ivalue *res,
}
if (res->t == DUK_IVAL_VAR) {
- duk_reg_t reg_varbind;
+ duk_regconst_t reg_varbind;
duk_regconst_t rc_varname;
- duk_dup(ctx, res->x1.valstack_idx);
+ duk_dup(thr, res->x1.valstack_idx);
if (duk__lookup_lhs(comp_ctx, &reg_varbind, &rc_varname)) {
duk__emit_a_bc(comp_ctx,
DUK_OP_LDREG,
- (duk_regconst_t) reg_varbind,
- (duk_regconst_t) (reg_temps + 0));
+ reg_varbind,
+ reg_temps + 0);
} else {
duk__emit_a_bc(comp_ctx,
DUK_OP_PUTVAR | DUK__EMIT_FLAG_A_IS_SOURCE,
- (duk_regconst_t) (reg_temps + 0),
+ reg_temps + 0,
rc_varname);
}
} else if (res->t == DUK_IVAL_PROP) {
/* Don't allow a constant for the object (even for a number etc), as
* it goes into the 'A' field of the opcode.
*/
- duk_reg_t reg_obj;
+ duk_regconst_t reg_obj;
duk_regconst_t rc_key;
reg_obj = duk__ispec_toregconst_raw(comp_ctx, &res->x1, -1 /*forced_reg*/, 0 /*flags*/); /* don't allow const */
rc_key = duk__ispec_toregconst_raw(comp_ctx, &res->x2, -1 /*forced_reg*/, DUK__IVAL_FLAG_ALLOW_CONST /*flags*/);
duk__emit_a_b_c(comp_ctx,
DUK_OP_PUTPROP | DUK__EMIT_FLAG_A_IS_SOURCE | DUK__EMIT_FLAG_BC_REGCONST,
- (duk_regconst_t) reg_obj,
+ reg_obj,
rc_key,
- (duk_regconst_t) (reg_temps + 0));
+ reg_temps + 0);
} else {
duk__ivalue_toplain_ignore(comp_ctx, res); /* just in case */
duk__emit_op_only(comp_ctx,
@@ -67652,7 +69222,7 @@ DUK_LOCAL void duk__parse_for_stmt(duk_compiler_ctx *comp_ctx, duk_ivalue *res,
{
duk_int_t pc_l1, pc_l2, pc_l3, pc_l4, pc_l5;
duk_int_t pc_jumpto_l2, pc_jumpto_l3, pc_jumpto_l4, pc_jumpto_l5;
- duk_reg_t reg_target;
+ duk_regconst_t reg_target;
DUK_DDD(DUK_DDDPRINT("shared code for parsing variants 3 and 4, pc_v34_lhs=%ld", (long) pc_v34_lhs));
@@ -67687,8 +69257,8 @@ DUK_LOCAL void duk__parse_for_stmt(duk_compiler_ctx *comp_ctx, duk_ivalue *res,
reg_target = duk__exprtop_toreg(comp_ctx, res, DUK__BP_FOR_EXPR /*rbp_flags*/); /* Expression */
duk__emit_b_c(comp_ctx,
DUK_OP_INITENUM | DUK__EMIT_FLAG_B_IS_TARGET,
- (duk_regconst_t) (reg_temps + 1),
- (duk_regconst_t) reg_target);
+ reg_temps + 1,
+ reg_target);
pc_jumpto_l4 = duk__emit_jump_empty(comp_ctx);
DUK__SETTEMP(comp_ctx, temp_reset);
@@ -67707,8 +69277,8 @@ DUK_LOCAL void duk__parse_for_stmt(duk_compiler_ctx *comp_ctx, duk_ivalue *res,
pc_l4 = duk__get_current_pc(comp_ctx);
duk__emit_b_c(comp_ctx,
DUK_OP_NEXTENUM | DUK__EMIT_FLAG_B_IS_TARGET | DUK__EMIT_FLAG_RESERVE_JUMPSLOT,
- (duk_regconst_t) (reg_temps + 0),
- (duk_regconst_t) (reg_temps + 1));
+ reg_temps + 0,
+ reg_temps + 1);
pc_jumpto_l5 = comp_ctx->emit_jumpslot_pc; /* NEXTENUM jump slot: executed when enum finished */
duk__emit_jump(comp_ctx, pc_l1); /* jump to next loop, using reg_v34_iter as iterated value */
@@ -67745,10 +69315,10 @@ DUK_LOCAL void duk__parse_for_stmt(duk_compiler_ctx *comp_ctx, duk_ivalue *res,
DUK_LOCAL void duk__parse_switch_stmt(duk_compiler_ctx *comp_ctx, duk_ivalue *res, duk_int_t pc_label_site) {
duk_hthread *thr = comp_ctx->thr;
- duk_reg_t temp_at_loop;
+ duk_regconst_t temp_at_loop;
duk_regconst_t rc_switch; /* reg/const for switch value */
duk_regconst_t rc_case; /* reg/const for case value */
- duk_reg_t reg_temp; /* general temp register */
+ duk_regconst_t reg_temp; /* general temp register */
duk_int_t pc_prevcase = -1;
duk_int_t pc_prevstmt = -1;
duk_int_t pc_default = -1; /* -1 == not set, -2 == pending (next statement list) */
@@ -67791,7 +69361,7 @@ DUK_LOCAL void duk__parse_switch_stmt(duk_compiler_ctx *comp_ctx, duk_ivalue *re
for (;;) {
duk_int_t num_stmts;
- duk_small_int_t tok;
+ duk_small_uint_t tok;
/* sufficient for keeping temp reg numbers in check */
DUK__SETTEMP(comp_ctx, temp_at_loop);
@@ -67823,10 +69393,10 @@ DUK_LOCAL void duk__parse_switch_stmt(duk_compiler_ctx *comp_ctx, duk_ivalue *re
reg_temp = DUK__ALLOCTEMP(comp_ctx);
duk__emit_a_b_c(comp_ctx,
DUK_OP_SEQ | DUK__EMIT_FLAG_BC_REGCONST,
- (duk_regconst_t) reg_temp,
+ reg_temp,
rc_switch,
rc_case);
- duk__emit_if_true_skip(comp_ctx, (duk_regconst_t) reg_temp);
+ duk__emit_if_true_skip(comp_ctx, reg_temp);
/* jump to next case clause */
pc_prevcase = duk__emit_jump_empty(comp_ctx); /* no match, next case */
@@ -67943,7 +69513,7 @@ DUK_LOCAL void duk__parse_switch_stmt(duk_compiler_ctx *comp_ctx, duk_ivalue *re
}
DUK_LOCAL void duk__parse_if_stmt(duk_compiler_ctx *comp_ctx, duk_ivalue *res) {
- duk_reg_t temp_reset;
+ duk_regconst_t temp_reset;
duk_regconst_t rc_cond;
duk_int_t pc_jump_false;
@@ -68017,7 +69587,7 @@ DUK_LOCAL void duk__parse_do_stmt(duk_compiler_ctx *comp_ctx, duk_ivalue *res, d
}
DUK_LOCAL void duk__parse_while_stmt(duk_compiler_ctx *comp_ctx, duk_ivalue *res, duk_int_t pc_label_site) {
- duk_reg_t temp_reset;
+ duk_regconst_t temp_reset;
duk_regconst_t rc_cond;
duk_int_t pc_start;
duk_int_t pc_jump_false;
@@ -68136,7 +69706,7 @@ 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, and
- * the context allows it, change the CALL to TAILCALL.
+ * the context allows it, add a tailcall flag to the 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 tail call
@@ -68182,13 +69752,13 @@ DUK_LOCAL void duk__parse_return_stmt(duk_compiler_ctx *comp_ctx, duk_ivalue *re
ins = instr->ins;
op = (duk_small_uint_t) DUK_DEC_OP(ins);
- if (op == DUK_OP_CALL &&
- DUK__ISTEMP(comp_ctx, rc_val) /* see above */) {
+ if ((op & ~0x0fU) == DUK_OP_CALL0 &&
+ DUK__ISREG_TEMP(comp_ctx, rc_val) /* see above */) {
DUK_DDD(DUK_DDDPRINT("return statement detected a tail call opportunity: "
"catch depth is 0, duk__exprtop() emitted >= 1 instructions, "
"and last instruction is a CALL "
"-> change to TAILCALL"));
- ins = (ins & ~DUK_BC_SHIFTED_MASK_OP) | (DUK_OP_TAILCALL << DUK_BC_SHIFT_OP);
+ ins |= DUK_ENC_OP(DUK_BC_CALL_FLAG_TAILCALL);
instr->ins = ins;
}
}
@@ -68208,7 +69778,7 @@ DUK_LOCAL void duk__parse_return_stmt(duk_compiler_ctx *comp_ctx, duk_ivalue *re
}
DUK_LOCAL void duk__parse_throw_stmt(duk_compiler_ctx *comp_ctx, duk_ivalue *res) {
- duk_reg_t reg_val;
+ duk_regconst_t reg_val;
duk__advance(comp_ctx); /* eat 'throw' */
@@ -68221,13 +69791,12 @@ DUK_LOCAL void duk__parse_throw_stmt(duk_compiler_ctx *comp_ctx, duk_ivalue *res
reg_val = duk__exprtop_toreg(comp_ctx, res, DUK__BP_FOR_EXPR /*rbp_flags*/);
duk__emit_bc(comp_ctx,
DUK_OP_THROW,
- (duk_regconst_t) reg_val);
+ reg_val);
}
DUK_LOCAL void duk__parse_try_stmt(duk_compiler_ctx *comp_ctx, duk_ivalue *res) {
duk_hthread *thr = comp_ctx->thr;
- duk_context *ctx = (duk_context *) thr;
- duk_reg_t reg_catch; /* reg_catch+0 and reg_catch+1 are reserved for TRYCATCH */
+ duk_regconst_t reg_catch; /* reg_catch+0 and reg_catch+1 are reserved for TRYCATCH */
duk_regconst_t rc_varname = 0;
duk_small_uint_t trycatch_flags = 0;
duk_int_t pc_ldconst = -1;
@@ -68301,7 +69870,7 @@ DUK_LOCAL void duk__parse_try_stmt(duk_compiler_ctx *comp_ctx, duk_ivalue *res)
duk_hstring *h_var;
duk_int_t varmap_value; /* for storing/restoring the varmap binding for catch variable */
- DUK_DDD(DUK_DDDPRINT("stack top at start of catch clause: %ld", (long) duk_get_top(ctx)));
+ DUK_DDD(DUK_DDDPRINT("stack top at start of catch clause: %ld", (long) duk_get_top(thr)));
trycatch_flags |= DUK_BC_TRYCATCH_FLAG_HAVE_CATCH;
@@ -68317,7 +69886,7 @@ DUK_LOCAL void duk__parse_try_stmt(duk_compiler_ctx *comp_ctx, duk_ivalue *res)
h_var = comp_ctx->curr_token.str1;
DUK_ASSERT(h_var != NULL);
- duk_push_hstring(ctx, h_var); /* keep in on valstack, use borrowed ref below */
+ duk_push_hstring(thr, h_var); /* keep in on valstack, use borrowed ref below */
if (comp_ctx->curr_func.is_strict &&
((h_var == DUK_HTHREAD_STRING_EVAL(thr)) ||
@@ -68326,7 +69895,7 @@ DUK_LOCAL void duk__parse_try_stmt(duk_compiler_ctx *comp_ctx, duk_ivalue *res)
goto syntax_error;
}
- duk_dup_top(ctx);
+ duk_dup_top(thr);
rc_varname = duk__getconst(comp_ctx);
DUK_DDD(DUK_DDDPRINT("catch clause, rc_varname=0x%08lx (%ld)",
(unsigned long) rc_varname, (long) rc_varname));
@@ -68337,60 +69906,60 @@ DUK_LOCAL void duk__parse_try_stmt(duk_compiler_ctx *comp_ctx, duk_ivalue *res)
duk__advance_expect(comp_ctx, DUK_TOK_LCURLY);
DUK_DDD(DUK_DDDPRINT("varmap before modifying for catch clause: %!iT",
- (duk_tval *) duk_get_tval(ctx, comp_ctx->curr_func.varmap_idx)));
+ (duk_tval *) duk_get_tval(thr, comp_ctx->curr_func.varmap_idx)));
- duk_dup_top(ctx);
- duk_get_prop(ctx, comp_ctx->curr_func.varmap_idx);
- if (duk_is_undefined(ctx, -1)) {
+ duk_dup_top(thr);
+ duk_get_prop(thr, comp_ctx->curr_func.varmap_idx);
+ if (duk_is_undefined(thr, -1)) {
varmap_value = -2;
- } else if (duk_is_null(ctx, -1)) {
+ } else if (duk_is_null(thr, -1)) {
varmap_value = -1;
} else {
- DUK_ASSERT(duk_is_number(ctx, -1));
- varmap_value = duk_get_int(ctx, -1);
+ DUK_ASSERT(duk_is_number(thr, -1));
+ varmap_value = duk_get_int(thr, -1);
DUK_ASSERT(varmap_value >= 0);
}
- duk_pop(ctx);
+ duk_pop(thr);
#if 0
/* It'd be nice to do something like this - but it doesn't
* work for closures created inside the catch clause.
*/
- duk_dup_top(ctx);
- duk_push_int(ctx, (duk_int_t) (reg_catch + 0));
- duk_put_prop(ctx, comp_ctx->curr_func.varmap_idx);
+ duk_dup_top(thr);
+ duk_push_int(thr, (duk_int_t) (reg_catch + 0));
+ duk_put_prop(thr, comp_ctx->curr_func.varmap_idx);
#endif
- duk_dup_top(ctx);
- duk_push_null(ctx);
- duk_put_prop(ctx, comp_ctx->curr_func.varmap_idx);
+ duk_dup_top(thr);
+ duk_push_null(thr);
+ duk_put_prop(thr, comp_ctx->curr_func.varmap_idx);
duk__emit_a_bc(comp_ctx,
DUK_OP_PUTVAR | DUK__EMIT_FLAG_A_IS_SOURCE,
- (duk_regconst_t) (reg_catch + 0) /*value*/,
+ reg_catch + 0 /*value*/,
rc_varname /*varname*/);
DUK_DDD(DUK_DDDPRINT("varmap before parsing catch clause: %!iT",
- (duk_tval *) duk_get_tval(ctx, comp_ctx->curr_func.varmap_idx)));
+ (duk_tval *) duk_get_tval(thr, comp_ctx->curr_func.varmap_idx)));
duk__parse_stmts(comp_ctx, 0 /*allow_source_elem*/, 0 /*expect_eof*/);
/* the DUK_TOK_RCURLY is eaten by duk__parse_stmts() */
if (varmap_value == -2) {
/* not present */
- duk_del_prop(ctx, comp_ctx->curr_func.varmap_idx);
+ duk_del_prop(thr, comp_ctx->curr_func.varmap_idx);
} else {
if (varmap_value == -1) {
- duk_push_null(ctx);
+ duk_push_null(thr);
} else {
DUK_ASSERT(varmap_value >= 0);
- duk_push_int(ctx, varmap_value);
+ duk_push_int(thr, varmap_value);
}
- duk_put_prop(ctx, comp_ctx->curr_func.varmap_idx);
+ duk_put_prop(thr, comp_ctx->curr_func.varmap_idx);
}
/* varname is popped by above code */
DUK_DDD(DUK_DDDPRINT("varmap after restore catch clause: %!iT",
- (duk_tval *) duk_get_tval(ctx, comp_ctx->curr_func.varmap_idx)));
+ (duk_tval *) duk_get_tval(thr, comp_ctx->curr_func.varmap_idx)));
duk__emit_op_only(comp_ctx,
DUK_OP_ENDCATCH);
@@ -68403,7 +69972,7 @@ DUK_LOCAL void duk__parse_try_stmt(duk_compiler_ctx *comp_ctx, duk_ivalue *res)
trycatch_flags |= DUK_BC_TRYCATCH_FLAG_CATCH_BINDING;
- DUK_DDD(DUK_DDDPRINT("stack top at end of catch clause: %ld", (long) duk_get_top(ctx)));
+ DUK_DDD(DUK_DDDPRINT("stack top at end of catch clause: %ld", (long) duk_get_top(thr)));
}
if (comp_ctx->curr_token.t == DUK_TOK_FINALLY) {
@@ -68416,9 +69985,9 @@ DUK_LOCAL void duk__parse_try_stmt(duk_compiler_ctx *comp_ctx, duk_ivalue *res)
duk__advance_expect(comp_ctx, DUK_TOK_LCURLY);
duk__parse_stmts(comp_ctx, 0 /*allow_source_elem*/, 0 /*expect_eof*/);
/* the DUK_TOK_RCURLY is eaten by duk__parse_stmts() */
- duk__emit_b(comp_ctx,
- DUK_OP_ENDFIN,
- reg_catch); /* rethrow */
+ duk__emit_abc(comp_ctx,
+ DUK_OP_ENDFIN,
+ reg_catch); /* rethrow */
}
if (!(trycatch_flags & DUK_BC_TRYCATCH_FLAG_HAVE_CATCH) &&
@@ -68462,7 +70031,7 @@ DUK_LOCAL void duk__parse_try_stmt(duk_compiler_ctx *comp_ctx, duk_ivalue *res)
DUK_LOCAL void duk__parse_with_stmt(duk_compiler_ctx *comp_ctx, duk_ivalue *res) {
duk_int_t pc_trycatch;
duk_int_t pc_finished;
- duk_reg_t reg_catch;
+ duk_regconst_t reg_catch;
duk_small_uint_t trycatch_flags;
if (comp_ctx->curr_func.is_strict) {
@@ -68484,7 +70053,7 @@ DUK_LOCAL void duk__parse_with_stmt(duk_compiler_ctx *comp_ctx, duk_ivalue *res)
duk__emit_a_bc(comp_ctx,
DUK_OP_TRYCATCH | DUK__EMIT_FLAG_NO_SHUFFLE_A,
(duk_regconst_t) trycatch_flags /*a*/,
- (duk_regconst_t) reg_catch /*bc*/);
+ reg_catch /*bc*/);
duk__emit_invalid(comp_ctx); /* catch jump */
duk__emit_invalid(comp_ctx); /* finished jump */
@@ -68524,10 +70093,9 @@ DUK_LOCAL duk_int_t duk__stmt_label_site(duk_compiler_ctx *comp_ctx, duk_int_t l
*/
DUK_LOCAL void duk__parse_stmt(duk_compiler_ctx *comp_ctx, duk_ivalue *res, duk_bool_t allow_source_elem) {
duk_hthread *thr = comp_ctx->thr;
- duk_context *ctx = (duk_context *) thr;
duk_bool_t dir_prol_at_entry; /* directive prologue status at entry */
- duk_reg_t temp_at_entry;
- duk_uarridx_t labels_len_at_entry;
+ duk_regconst_t temp_at_entry;
+ duk_size_t labels_len_at_entry;
duk_int_t pc_at_entry; /* assumed to also be PC of "LABEL" */
duk_int_t stmt_id;
duk_small_uint_t stmt_flags = 0;
@@ -68539,7 +70107,7 @@ DUK_LOCAL void duk__parse_stmt(duk_compiler_ctx *comp_ctx, duk_ivalue *res, duk_
temp_at_entry = DUK__GETTEMP(comp_ctx);
pc_at_entry = duk__get_current_pc(comp_ctx);
- labels_len_at_entry = (duk_uarridx_t) duk_get_length(ctx, comp_ctx->curr_func.labelnames_idx);
+ labels_len_at_entry = duk_get_length(thr, comp_ctx->curr_func.labelnames_idx);
stmt_id = comp_ctx->curr_func.stmt_next++;
dir_prol_at_entry = comp_ctx->curr_func.in_directive_prologue;
@@ -68624,7 +70192,7 @@ DUK_LOCAL void duk__parse_stmt(duk_compiler_ctx *comp_ctx, duk_ivalue *res, duk_
DUK_DDD(DUK_DDDPRINT("function declaration statement"));
#if defined(DUK_USE_ASSERTIONS)
- top_before = duk_get_top(ctx);
+ top_before = duk_get_top(thr);
#endif
duk__advance(comp_ctx); /* eat 'function' */
@@ -68638,18 +70206,18 @@ DUK_LOCAL void duk__parse_stmt(duk_compiler_ctx *comp_ctx, duk_ivalue *res, duk_
duk_uarridx_t n;
#if defined(DUK_USE_ASSERTIONS)
- DUK_ASSERT(duk_get_top(ctx) == top_before + 1);
+ DUK_ASSERT(duk_get_top(thr) == top_before + 1);
#endif
DUK_DDD(DUK_DDDPRINT("register function declaration %!T in pass 1, fnum %ld",
- duk_get_tval(ctx, -1), (long) fnum));
- n = (duk_uarridx_t) duk_get_length(ctx, comp_ctx->curr_func.decls_idx);
+ duk_get_tval(thr, -1), (long) fnum));
+ n = (duk_uarridx_t) duk_get_length(thr, comp_ctx->curr_func.decls_idx);
/* funcname is at index -1 */
- duk_put_prop_index(ctx, comp_ctx->curr_func.decls_idx, n);
- duk_push_int(ctx, (duk_int_t) (DUK_DECL_TYPE_FUNC + (fnum << 8)));
- duk_put_prop_index(ctx, comp_ctx->curr_func.decls_idx, n + 1);
+ duk_put_prop_index(thr, comp_ctx->curr_func.decls_idx, n);
+ duk_push_int(thr, (duk_int_t) (DUK_DECL_TYPE_FUNC + (fnum << 8)));
+ duk_put_prop_index(thr, comp_ctx->curr_func.decls_idx, n + 1);
} else {
#if defined(DUK_USE_ASSERTIONS)
- DUK_ASSERT(duk_get_top(ctx) == top_before);
+ DUK_ASSERT(duk_get_top(thr) == top_before);
#endif
}
@@ -68860,7 +70428,7 @@ DUK_LOCAL void duk__parse_stmt(duk_compiler_ctx *comp_ctx, duk_ivalue *res, duk_
/* expected ival */
DUK_ASSERT(res->t == DUK_IVAL_VAR);
DUK_ASSERT(res->x1.t == DUK_ISPEC_VALUE);
- DUK_ASSERT(DUK_TVAL_IS_STRING(duk_get_tval(ctx, res->x1.valstack_idx)));
+ DUK_ASSERT(DUK_TVAL_IS_STRING(duk_get_tval(thr, res->x1.valstack_idx)));
h_lab = comp_ctx->prev_token.str1;
DUK_ASSERT(h_lab != NULL);
@@ -68898,7 +70466,7 @@ DUK_LOCAL void duk__parse_stmt(duk_compiler_ctx *comp_ctx, duk_ivalue *res, duk_
/* expected ival */
DUK_ASSERT(res->t == DUK_IVAL_PLAIN);
DUK_ASSERT(res->x1.t == DUK_ISPEC_VALUE);
- DUK_ASSERT(DUK_TVAL_IS_STRING(duk_get_tval(ctx, res->x1.valstack_idx)));
+ DUK_ASSERT(DUK_TVAL_IS_STRING(duk_get_tval(thr, res->x1.valstack_idx)));
h_dir = comp_ctx->prev_token.str1;
DUK_ASSERT(h_dir != NULL);
@@ -68966,7 +70534,7 @@ DUK_LOCAL void duk__parse_stmt(duk_compiler_ctx *comp_ctx, duk_ivalue *res, duk_
*/
if (stmt_flags & DUK__HAS_VAL) {
- duk_reg_t reg_stmt_value = comp_ctx->curr_func.reg_stmt_value;
+ duk_regconst_t reg_stmt_value = comp_ctx->curr_func.reg_stmt_value;
if (reg_stmt_value >= 0) {
duk__ivalue_toforcedreg(comp_ctx, res, reg_stmt_value);
} else {
@@ -69045,13 +70613,12 @@ DUK_LOCAL void duk__parse_stmt(duk_compiler_ctx *comp_ctx, duk_ivalue *res, duk_
DUK_LOCAL void duk__parse_stmts(duk_compiler_ctx *comp_ctx, duk_bool_t allow_source_elem, duk_bool_t expect_eof) {
duk_hthread *thr = comp_ctx->thr;
- duk_context *ctx = (duk_context *) thr;
duk_ivalue res_alloc;
duk_ivalue *res = &res_alloc;
/* Setup state. Initial ivalue is 'undefined'. */
- duk_require_stack(ctx, DUK__PARSE_STATEMENTS_SLOTS);
+ duk_require_stack(thr, DUK__PARSE_STATEMENTS_SLOTS);
/* XXX: 'res' setup can be moved to function body level; in fact, two 'res'
* intermediate values suffice for parsing of each function. Nesting is needed
@@ -69061,10 +70628,10 @@ DUK_LOCAL void duk__parse_stmts(duk_compiler_ctx *comp_ctx, duk_bool_t allow_sou
DUK_MEMZERO(&res_alloc, sizeof(res_alloc));
res->t = DUK_IVAL_PLAIN;
res->x1.t = DUK_ISPEC_VALUE;
- res->x1.valstack_idx = duk_get_top(ctx);
+ res->x1.valstack_idx = duk_get_top(thr);
res->x2.valstack_idx = res->x1.valstack_idx + 1;
- duk_push_undefined(ctx);
- duk_push_undefined(ctx);
+ duk_push_undefined(thr);
+ duk_push_undefined(thr);
/* Parse statements until a closing token (EOF or '}') is found. */
@@ -69096,7 +70663,7 @@ DUK_LOCAL void duk__parse_stmts(duk_compiler_ctx *comp_ctx, duk_bool_t allow_sou
/* Tear down state. */
- duk_pop_2(ctx);
+ duk_pop_2(thr);
}
/*
@@ -69131,9 +70698,8 @@ DUK_LOCAL void duk__parse_stmts(duk_compiler_ctx *comp_ctx, duk_bool_t allow_sou
* handle cases with a very large number of variables?
*/
-DUK_LOCAL void duk__init_varmap_and_prologue_for_pass2(duk_compiler_ctx *comp_ctx, duk_reg_t *out_stmt_value_reg) {
+DUK_LOCAL void duk__init_varmap_and_prologue_for_pass2(duk_compiler_ctx *comp_ctx, duk_regconst_t *out_stmt_value_reg) {
duk_hthread *thr = comp_ctx->thr;
- duk_context *ctx = (duk_context *) thr;
duk_hstring *h_name;
duk_bool_t configurable_bindings;
duk_uarridx_t num_args;
@@ -69146,7 +70712,7 @@ DUK_LOCAL void duk__init_varmap_and_prologue_for_pass2(duk_compiler_ctx *comp_ct
#endif
#if defined(DUK_USE_ASSERTIONS)
- entry_top = duk_get_top(ctx);
+ entry_top = duk_get_top(thr);
#endif
/*
@@ -69163,21 +70729,21 @@ DUK_LOCAL void duk__init_varmap_and_prologue_for_pass2(duk_compiler_ctx *comp_ct
* (there's no support for shuffling them now).
*/
- num_args = (duk_uarridx_t) duk_get_length(ctx, comp_ctx->curr_func.argnames_idx);
+ num_args = (duk_uarridx_t) duk_get_length(thr, comp_ctx->curr_func.argnames_idx);
DUK_DDD(DUK_DDDPRINT("num_args=%ld", (long) num_args));
/* XXX: check num_args */
for (i = 0; i < num_args; i++) {
- duk_get_prop_index(ctx, comp_ctx->curr_func.argnames_idx, i);
- h_name = duk_known_hstring(ctx, -1);
+ duk_get_prop_index(thr, comp_ctx->curr_func.argnames_idx, i);
+ h_name = duk_known_hstring(thr, -1);
if (comp_ctx->curr_func.is_strict) {
if (duk__hstring_is_eval_or_arguments(comp_ctx, h_name)) {
DUK_DDD(DUK_DDDPRINT("arg named 'eval' or 'arguments' in strict mode -> SyntaxError"));
goto error_argname;
}
- duk_dup_top(ctx);
- if (duk_has_prop(ctx, comp_ctx->curr_func.varmap_idx)) {
+ duk_dup_top(thr);
+ if (duk_has_prop(thr, comp_ctx->curr_func.varmap_idx)) {
DUK_DDD(DUK_DDDPRINT("duplicate arg name in strict mode -> SyntaxError"));
goto error_argname;
}
@@ -69202,14 +70768,14 @@ DUK_LOCAL void duk__init_varmap_and_prologue_for_pass2(duk_compiler_ctx *comp_ct
/* only functions can have arguments */
DUK_ASSERT(comp_ctx->curr_func.is_function);
- duk_push_uarridx(ctx, i); /* -> [ ... name index ] */
- duk_put_prop(ctx, comp_ctx->curr_func.varmap_idx); /* -> [ ... ] */
+ duk_push_uarridx(thr, i); /* -> [ ... name index ] */
+ duk_put_prop(thr, comp_ctx->curr_func.varmap_idx); /* -> [ ... ] */
/* no code needs to be emitted, the regs already have values */
}
/* use temp_next for tracking register allocations */
- DUK__SETTEMP_CHECKMAX(comp_ctx, (duk_reg_t) num_args);
+ DUK__SETTEMP_CHECKMAX(comp_ctx, (duk_regconst_t) num_args);
/*
* After arguments, allocate special registers (like shuffling temps)
@@ -69219,7 +70785,7 @@ DUK_LOCAL void duk__init_varmap_and_prologue_for_pass2(duk_compiler_ctx *comp_ct
*out_stmt_value_reg = DUK__ALLOCTEMP(comp_ctx);
}
if (comp_ctx->curr_func.needs_shuffle) {
- duk_reg_t shuffle_base = DUK__ALLOCTEMPS(comp_ctx, 3);
+ duk_regconst_t shuffle_base = DUK__ALLOCTEMPS(comp_ctx, 3);
comp_ctx->curr_func.shuffle1 = shuffle_base;
comp_ctx->curr_func.shuffle2 = shuffle_base + 1;
comp_ctx->curr_func.shuffle3 = shuffle_base + 2;
@@ -69237,47 +70803,47 @@ DUK_LOCAL void duk__init_varmap_and_prologue_for_pass2(duk_compiler_ctx *comp_ct
* Function declarations
*/
- num_decls = (duk_uarridx_t) duk_get_length(ctx, comp_ctx->curr_func.decls_idx);
+ num_decls = (duk_uarridx_t) duk_get_length(thr, comp_ctx->curr_func.decls_idx);
DUK_DDD(DUK_DDDPRINT("num_decls=%ld -> %!T",
(long) num_decls,
- (duk_tval *) duk_get_tval(ctx, comp_ctx->curr_func.decls_idx)));
+ (duk_tval *) duk_get_tval(thr, comp_ctx->curr_func.decls_idx)));
for (i = 0; i < num_decls; i += 2) {
duk_int_t decl_type;
duk_int_t fnum;
- duk_get_prop_index(ctx, comp_ctx->curr_func.decls_idx, i + 1); /* decl type */
- decl_type = duk_to_int(ctx, -1);
+ duk_get_prop_index(thr, comp_ctx->curr_func.decls_idx, i + 1); /* decl type */
+ decl_type = duk_to_int(thr, -1);
fnum = decl_type >> 8; /* XXX: macros */
decl_type = decl_type & 0xff;
- duk_pop(ctx);
+ duk_pop(thr);
if (decl_type != DUK_DECL_TYPE_FUNC) {
continue;
}
- duk_get_prop_index(ctx, comp_ctx->curr_func.decls_idx, i); /* decl name */
+ duk_get_prop_index(thr, comp_ctx->curr_func.decls_idx, i); /* decl name */
/* XXX: spilling */
if (comp_ctx->curr_func.is_function) {
- duk_reg_t reg_bind;
- duk_dup_top(ctx);
- if (duk_has_prop(ctx, comp_ctx->curr_func.varmap_idx)) {
+ duk_regconst_t reg_bind;
+ duk_dup_top(thr);
+ if (duk_has_prop(thr, comp_ctx->curr_func.varmap_idx)) {
/* shadowed; update value */
- duk_dup_top(ctx);
- duk_get_prop(ctx, comp_ctx->curr_func.varmap_idx);
- reg_bind = duk_to_int(ctx, -1); /* [ ... name reg_bind ] */
+ duk_dup_top(thr);
+ duk_get_prop(thr, comp_ctx->curr_func.varmap_idx);
+ reg_bind = duk_to_int(thr, -1); /* [ ... name reg_bind ] */
duk__emit_a_bc(comp_ctx,
DUK_OP_CLOSURE,
- (duk_regconst_t) reg_bind,
+ reg_bind,
(duk_regconst_t) fnum);
} else {
/* function: always register bound */
reg_bind = DUK__ALLOCTEMP(comp_ctx);
duk__emit_a_bc(comp_ctx,
DUK_OP_CLOSURE,
- (duk_regconst_t) reg_bind,
+ reg_bind,
(duk_regconst_t) fnum);
- duk_push_int(ctx, (duk_int_t) reg_bind);
+ duk_push_int(thr, (duk_int_t) reg_bind);
}
} else {
/* Function declaration for global/eval code is emitted even
@@ -69288,14 +70854,14 @@ DUK_LOCAL void duk__init_varmap_and_prologue_for_pass2(duk_compiler_ctx *comp_ct
* update the binding value.
*/
- duk_reg_t reg_temp = DUK__ALLOCTEMP(comp_ctx);
- duk_dup_top(ctx);
+ duk_regconst_t reg_temp = DUK__ALLOCTEMP(comp_ctx);
+ duk_dup_top(thr);
rc_name = duk__getconst(comp_ctx);
- duk_push_null(ctx);
+ duk_push_null(thr);
duk__emit_a_bc(comp_ctx,
DUK_OP_CLOSURE,
- (duk_regconst_t) reg_temp,
+ reg_temp,
(duk_regconst_t) fnum);
declvar_flags = DUK_PROPDESC_FLAG_WRITABLE |
@@ -69310,19 +70876,19 @@ DUK_LOCAL void duk__init_varmap_and_prologue_for_pass2(duk_compiler_ctx *comp_ct
DUK_OP_DECLVAR | DUK__EMIT_FLAG_NO_SHUFFLE_A | DUK__EMIT_FLAG_BC_REGCONST,
(duk_regconst_t) declvar_flags /*flags*/,
rc_name /*name*/,
- (duk_regconst_t) reg_temp /*value*/);
+ reg_temp /*value*/);
DUK__SETTEMP(comp_ctx, reg_temp); /* forget temp */
}
DUK_DDD(DUK_DDDPRINT("function declaration to varmap: %!T -> %!T",
- (duk_tval *) duk_get_tval(ctx, -2),
- (duk_tval *) duk_get_tval(ctx, -1)));
+ (duk_tval *) duk_get_tval(thr, -2),
+ (duk_tval *) duk_get_tval(thr, -1)));
#if defined(DUK_USE_FASTINT)
- DUK_ASSERT(DUK_TVAL_IS_NULL(duk_get_tval(ctx, -1)) || DUK_TVAL_IS_FASTINT(duk_get_tval(ctx, -1)));
+ DUK_ASSERT(DUK_TVAL_IS_NULL(duk_get_tval(thr, -1)) || DUK_TVAL_IS_FASTINT(duk_get_tval(thr, -1)));
#endif
- duk_put_prop(ctx, comp_ctx->curr_func.varmap_idx); /* [ ... name reg/null ] -> [ ... ] */
+ duk_put_prop(thr, comp_ctx->curr_func.varmap_idx); /* [ ... name reg/null ] -> [ ... ] */
}
/*
@@ -69332,7 +70898,7 @@ DUK_LOCAL void duk__init_varmap_and_prologue_for_pass2(duk_compiler_ctx *comp_ct
* 'arguments' is referenced inside the function body.
*/
- if (duk_has_prop_stridx(ctx, comp_ctx->curr_func.varmap_idx, DUK_STRIDX_LC_ARGUMENTS)) {
+ if (duk_has_prop_stridx(thr, comp_ctx->curr_func.varmap_idx, DUK_STRIDX_LC_ARGUMENTS)) {
DUK_DDD(DUK_DDDPRINT("'arguments' is shadowed by argument or function declaration "
"-> arguments object creation can be skipped"));
comp_ctx->curr_func.is_arguments_shadowed = 1;
@@ -69349,22 +70915,22 @@ DUK_LOCAL void duk__init_varmap_and_prologue_for_pass2(duk_compiler_ctx *comp_ct
for (i = 0; i < num_decls; i += 2) {
duk_int_t decl_type;
- duk_get_prop_index(ctx, comp_ctx->curr_func.decls_idx, i + 1); /* decl type */
- decl_type = duk_to_int(ctx, -1);
+ duk_get_prop_index(thr, comp_ctx->curr_func.decls_idx, i + 1); /* decl type */
+ decl_type = duk_to_int(thr, -1);
decl_type = decl_type & 0xff;
- duk_pop(ctx);
+ duk_pop(thr);
if (decl_type != DUK_DECL_TYPE_VAR) {
continue;
}
- duk_get_prop_index(ctx, comp_ctx->curr_func.decls_idx, i); /* decl name */
+ duk_get_prop_index(thr, comp_ctx->curr_func.decls_idx, i); /* decl name */
- if (duk_has_prop(ctx, comp_ctx->curr_func.varmap_idx)) {
+ if (duk_has_prop(thr, comp_ctx->curr_func.varmap_idx)) {
/* shadowed, ignore */
} else {
- duk_get_prop_index(ctx, comp_ctx->curr_func.decls_idx, i); /* decl name */
- h_name = duk_known_hstring(ctx, -1);
+ duk_get_prop_index(thr, comp_ctx->curr_func.decls_idx, i); /* decl name */
+ h_name = duk_known_hstring(thr, -1);
if (h_name == DUK_HTHREAD_STRING_LC_ARGUMENTS(thr) &&
!comp_ctx->curr_func.is_arguments_shadowed) {
@@ -69372,19 +70938,19 @@ DUK_LOCAL void duk__init_varmap_and_prologue_for_pass2(duk_compiler_ctx *comp_ct
DUK_DDD(DUK_DDDPRINT("'arguments' not shadowed by a function declaration, "
"but appears as a variable declaration -> treat as "
"a no-op for variable declaration purposes"));
- duk_pop(ctx);
+ duk_pop(thr);
continue;
}
/* XXX: spilling */
if (comp_ctx->curr_func.is_function) {
- duk_reg_t reg_bind = DUK__ALLOCTEMP(comp_ctx);
+ duk_regconst_t reg_bind = DUK__ALLOCTEMP(comp_ctx);
/* no need to init reg, it will be undefined on entry */
- duk_push_int(ctx, (duk_int_t) reg_bind);
+ duk_push_int(thr, (duk_int_t) reg_bind);
} else {
- duk_dup_top(ctx);
+ duk_dup_top(thr);
rc_name = duk__getconst(comp_ctx);
- duk_push_null(ctx);
+ duk_push_null(thr);
declvar_flags = DUK_PROPDESC_FLAG_WRITABLE |
DUK_PROPDESC_FLAG_ENUMERABLE;
@@ -69396,10 +70962,10 @@ DUK_LOCAL void duk__init_varmap_and_prologue_for_pass2(duk_compiler_ctx *comp_ct
DUK_OP_DECLVAR | DUK__EMIT_FLAG_NO_SHUFFLE_A | DUK__EMIT_FLAG_BC_REGCONST,
(duk_regconst_t) declvar_flags /*flags*/,
rc_name /*name*/,
- (duk_regconst_t) 0 /*value*/);
+ 0 /*value*/);
}
- duk_put_prop(ctx, comp_ctx->curr_func.varmap_idx); /* [ ... name reg/null ] -> [ ... ] */
+ duk_put_prop(thr, comp_ctx->curr_func.varmap_idx); /* [ ... name reg/null ] -> [ ... ] */
}
}
@@ -69408,10 +70974,10 @@ DUK_LOCAL void duk__init_varmap_and_prologue_for_pass2(duk_compiler_ctx *comp_ct
*/
DUK_DDD(DUK_DDDPRINT("varmap: %!T, is_arguments_shadowed=%ld",
- (duk_tval *) duk_get_tval(ctx, comp_ctx->curr_func.varmap_idx),
+ (duk_tval *) duk_get_tval(thr, comp_ctx->curr_func.varmap_idx),
(long) comp_ctx->curr_func.is_arguments_shadowed));
- DUK_ASSERT_TOP(ctx, entry_top);
+ DUK_ASSERT_TOP(thr, entry_top);
return;
error_outofregs:
@@ -69462,16 +71028,14 @@ DUK_LOCAL void duk__init_varmap_and_prologue_for_pass2(duk_compiler_ctx *comp_ct
DUK_LOCAL void duk__parse_func_body(duk_compiler_ctx *comp_ctx, duk_bool_t expect_eof, duk_bool_t implicit_return_value, duk_small_int_t expect_token) {
duk_compiler_func *func;
duk_hthread *thr;
- duk_context *ctx;
- duk_reg_t reg_stmt_value = -1;
+ duk_regconst_t reg_stmt_value = -1;
duk_lexer_point lex_pt;
- duk_reg_t temp_first;
+ duk_regconst_t temp_first;
duk_small_int_t compile_round = 1;
DUK_ASSERT(comp_ctx != NULL);
thr = comp_ctx->thr;
- ctx = (duk_context *) thr;
DUK_ASSERT(thr != NULL);
func = &comp_ctx->curr_func;
@@ -69479,7 +71043,7 @@ DUK_LOCAL void duk__parse_func_body(duk_compiler_ctx *comp_ctx, duk_bool_t expec
DUK__RECURSION_INCREASE(comp_ctx, thr);
- duk_require_stack(ctx, DUK__FUNCTION_BODY_REQUIRE_SLOTS);
+ duk_require_stack(thr, DUK__FUNCTION_BODY_REQUIRE_SLOTS);
/*
* Store lexer position for a later rewind
@@ -69694,7 +71258,7 @@ DUK_LOCAL void duk__parse_func_body(duk_compiler_ctx *comp_ctx, duk_bool_t expec
DUK_ASSERT(comp_ctx->curr_func.catch_depth == 0);
if (reg_stmt_value >= 0) {
DUK_ASSERT(DUK__ISREG(reg_stmt_value));
- duk__emit_bc(comp_ctx, DUK_OP_RETREG, (duk_regconst_t) reg_stmt_value /*reg*/);
+ duk__emit_bc(comp_ctx, DUK_OP_RETREG, reg_stmt_value /*reg*/);
} else {
duk__emit_op_only(comp_ctx, DUK_OP_RETUNDEF);
}
@@ -69737,7 +71301,6 @@ DUK_LOCAL void duk__parse_func_body(duk_compiler_ctx *comp_ctx, duk_bool_t expec
/* Parse formals. */
DUK_LOCAL void duk__parse_func_formals(duk_compiler_ctx *comp_ctx) {
duk_hthread *thr = comp_ctx->thr;
- duk_context *ctx = (duk_context *) thr;
duk_bool_t first = 1;
duk_uarridx_t n;
@@ -69763,7 +71326,7 @@ DUK_LOCAL void duk__parse_func_formals(duk_compiler_ctx *comp_ctx) {
*/
if (comp_ctx->curr_token.t != DUK_TOK_IDENTIFIER) {
- DUK_ERROR_SYNTAX(thr, "expected identifier");
+ DUK_ERROR_SYNTAX(thr, DUK_STR_EXPECTED_IDENTIFIER);
}
DUK_ASSERT(comp_ctx->curr_token.t == DUK_TOK_IDENTIFIER);
DUK_ASSERT(comp_ctx->curr_token.str1 != NULL);
@@ -69771,9 +71334,9 @@ DUK_LOCAL void duk__parse_func_formals(duk_compiler_ctx *comp_ctx) {
(duk_heaphdr *) comp_ctx->curr_token.str1));
/* XXX: append primitive */
- duk_push_hstring(ctx, comp_ctx->curr_token.str1);
- n = (duk_uarridx_t) duk_get_length(ctx, comp_ctx->curr_func.argnames_idx);
- duk_put_prop_index(ctx, comp_ctx->curr_func.argnames_idx, n);
+ duk_push_hstring(thr, comp_ctx->curr_token.str1);
+ n = (duk_uarridx_t) duk_get_length(thr, comp_ctx->curr_func.argnames_idx);
+ duk_put_prop_index(thr, comp_ctx->curr_func.argnames_idx, n);
duk__advance(comp_ctx); /* eat identifier */
}
@@ -69785,7 +71348,6 @@ DUK_LOCAL void duk__parse_func_formals(duk_compiler_ctx *comp_ctx) {
*/
DUK_LOCAL void duk__parse_func_like_raw(duk_compiler_ctx *comp_ctx, duk_small_uint_t flags) {
duk_hthread *thr = comp_ctx->thr;
- duk_context *ctx = (duk_context *) thr;
duk_token *tok;
duk_bool_t no_advance;
@@ -69824,22 +71386,22 @@ DUK_LOCAL void duk__parse_func_like_raw(duk_compiler_ctx *comp_ctx, duk_small_ui
if (flags & DUK__FUNC_FLAG_GETSET) {
/* PropertyName -> IdentifierName | StringLiteral | NumericLiteral */
if (tok->t_nores == DUK_TOK_IDENTIFIER || tok->t == DUK_TOK_STRING) {
- duk_push_hstring(ctx, tok->str1); /* keep in valstack */
+ duk_push_hstring(thr, tok->str1); /* keep in valstack */
} else if (tok->t == DUK_TOK_NUMBER) {
- duk_push_number(ctx, tok->num);
- duk_to_string(ctx, -1);
+ duk_push_number(thr, tok->num);
+ duk_to_string(thr, -1);
} else {
DUK_ERROR_SYNTAX(thr, DUK_STR_INVALID_GETSET_NAME);
}
- comp_ctx->curr_func.h_name = duk_known_hstring(ctx, -1); /* borrowed reference */
+ comp_ctx->curr_func.h_name = duk_known_hstring(thr, -1); /* borrowed reference */
} else {
/* Function name is an Identifier (not IdentifierName), but we get
* the raw name (not recognizing keywords) here and perform the name
* checks only after pass 1.
*/
if (tok->t_nores == DUK_TOK_IDENTIFIER) {
- duk_push_hstring(ctx, tok->str1); /* keep in valstack */
- comp_ctx->curr_func.h_name = duk_known_hstring(ctx, -1); /* borrowed reference */
+ duk_push_hstring(thr, tok->str1); /* keep in valstack */
+ comp_ctx->curr_func.h_name = duk_known_hstring(thr, -1); /* borrowed reference */
} else {
/* valstack will be unbalanced, which is OK */
DUK_ASSERT((flags & DUK__FUNC_FLAG_GETSET) == 0);
@@ -69906,7 +71468,6 @@ DUK_LOCAL void duk__parse_func_like_raw(duk_compiler_ctx *comp_ctx, duk_small_ui
*/
DUK_LOCAL duk_int_t duk__parse_func_like_fnum(duk_compiler_ctx *comp_ctx, duk_small_uint_t flags) {
duk_hthread *thr = comp_ctx->thr;
- duk_context *ctx = (duk_context *) thr;
duk_compiler_func old_func;
duk_idx_t entry_top;
duk_int_t fnum;
@@ -69919,12 +71480,12 @@ DUK_LOCAL duk_int_t duk__parse_func_like_fnum(duk_compiler_ctx *comp_ctx, duk_sm
duk_lexer_point lex_pt;
fnum = comp_ctx->curr_func.fnum_next++;
- duk_get_prop_index(ctx, comp_ctx->curr_func.funcs_idx, (duk_uarridx_t) (fnum * 3 + 1));
- lex_pt.offset = duk_to_int(ctx, -1);
- duk_pop(ctx);
- duk_get_prop_index(ctx, comp_ctx->curr_func.funcs_idx, (duk_uarridx_t) (fnum * 3 + 2));
- lex_pt.line = duk_to_int(ctx, -1);
- duk_pop(ctx);
+ duk_get_prop_index(thr, comp_ctx->curr_func.funcs_idx, (duk_uarridx_t) (fnum * 3 + 1));
+ lex_pt.offset = (duk_size_t) duk_to_uint(thr, -1);
+ duk_pop(thr);
+ duk_get_prop_index(thr, comp_ctx->curr_func.funcs_idx, (duk_uarridx_t) (fnum * 3 + 2));
+ lex_pt.line = duk_to_int(thr, -1);
+ duk_pop(thr);
DUK_DDD(DUK_DDDPRINT("second pass of an inner func, skip the function, reparse closing brace; lex offset=%ld, line=%ld",
(long) lex_pt.offset, (long) lex_pt.line));
@@ -69943,7 +71504,7 @@ DUK_LOCAL duk_int_t duk__parse_func_like_fnum(duk_compiler_ctx *comp_ctx, duk_sm
* to restore it later, and switch to using a new function in comp_ctx.
*/
- entry_top = duk_get_top(ctx);
+ entry_top = duk_get_top(thr);
DUK_DDD(DUK_DDDPRINT("before func: entry_top=%ld, curr_tok.start_offset=%ld",
(long) entry_top, (long) comp_ctx->curr_token.start_offset));
@@ -69986,7 +71547,7 @@ DUK_LOCAL duk_int_t duk__parse_func_like_fnum(duk_compiler_ctx *comp_ctx, duk_sm
DUK_ASSERT(comp_ctx->lex.input[comp_ctx->prev_token.start_offset] == (duk_uint8_t) DUK_ASC_RCURLY);
/* XXX: append primitive */
- DUK_ASSERT(duk_get_length(ctx, old_func.funcs_idx) == (duk_size_t) (old_func.fnum_next * 3));
+ DUK_ASSERT(duk_get_length(thr, old_func.funcs_idx) == (duk_size_t) (old_func.fnum_next * 3));
fnum = old_func.fnum_next++;
if (fnum > DUK__MAX_FUNCS) {
@@ -69994,11 +71555,11 @@ DUK_LOCAL duk_int_t duk__parse_func_like_fnum(duk_compiler_ctx *comp_ctx, duk_sm
}
/* array writes autoincrement length */
- (void) duk_put_prop_index(ctx, old_func.funcs_idx, (duk_uarridx_t) (fnum * 3));
- duk_push_size_t(ctx, comp_ctx->prev_token.start_offset);
- (void) duk_put_prop_index(ctx, old_func.funcs_idx, (duk_uarridx_t) (fnum * 3 + 1));
- duk_push_int(ctx, comp_ctx->prev_token.start_line);
- (void) duk_put_prop_index(ctx, old_func.funcs_idx, (duk_uarridx_t) (fnum * 3 + 2));
+ (void) duk_put_prop_index(thr, old_func.funcs_idx, (duk_uarridx_t) (fnum * 3));
+ duk_push_size_t(thr, comp_ctx->prev_token.start_offset);
+ (void) duk_put_prop_index(thr, old_func.funcs_idx, (duk_uarridx_t) (fnum * 3 + 1));
+ duk_push_int(thr, comp_ctx->prev_token.start_line);
+ (void) duk_put_prop_index(thr, old_func.funcs_idx, (duk_uarridx_t) (fnum * 3 + 2));
/*
* Cleanup: restore original function, restore valstack state.
@@ -70009,11 +71570,11 @@ DUK_LOCAL duk_int_t duk__parse_func_like_fnum(duk_compiler_ctx *comp_ctx, duk_sm
if (flags & DUK__FUNC_FLAG_PUSHNAME_PASS1) {
DUK_ASSERT(comp_ctx->curr_func.h_name != NULL);
- duk_push_hstring(ctx, comp_ctx->curr_func.h_name);
- duk_replace(ctx, entry_top);
- duk_set_top(ctx, entry_top + 1);
+ duk_push_hstring(thr, comp_ctx->curr_func.h_name);
+ duk_replace(thr, entry_top);
+ duk_set_top(thr, entry_top + 1);
} else {
- duk_set_top(ctx, entry_top);
+ duk_set_top(thr, entry_top);
}
DUK_MEMCPY((void *) &comp_ctx->curr_func, (void *) &old_func, sizeof(duk_compiler_func));
@@ -70034,8 +71595,7 @@ DUK_LOCAL duk_int_t duk__parse_func_like_fnum(duk_compiler_ctx *comp_ctx, duk_sm
/* XXX: source code property */
-DUK_LOCAL duk_ret_t duk__js_compile_raw(duk_context *ctx, void *udata) {
- duk_hthread *thr = (duk_hthread *) ctx;
+DUK_LOCAL duk_ret_t duk__js_compile_raw(duk_hthread *thr, void *udata) {
duk_hstring *h_filename;
duk__compiler_stkstate *comp_stk;
duk_compiler_ctx *comp_ctx;
@@ -70054,7 +71614,7 @@ DUK_LOCAL duk_ret_t duk__js_compile_raw(duk_context *ctx, void *udata) {
* Arguments check
*/
- entry_top = duk_get_top(ctx);
+ entry_top = duk_get_top(thr);
DUK_ASSERT(entry_top >= 1);
comp_stk = (duk__compiler_stkstate *) udata;
@@ -70068,7 +71628,7 @@ DUK_LOCAL duk_ret_t duk__js_compile_raw(duk_context *ctx, void *udata) {
is_strict = (flags & DUK_COMPILE_STRICT ? 1 : 0);
is_funcexpr = (flags & DUK_COMPILE_FUNCEXPR ? 1 : 0);
- h_filename = duk_get_hstring(ctx, -1); /* may be undefined */
+ h_filename = duk_get_hstring(thr, -1); /* may be undefined */
/*
* Init compiler and lexer contexts
@@ -70084,13 +71644,13 @@ DUK_LOCAL duk_ret_t duk__js_compile_raw(duk_context *ctx, void *udata) {
comp_ctx->curr_token.str2 = NULL;
#endif
- duk_require_stack(ctx, DUK__COMPILE_ENTRY_SLOTS);
+ duk_require_stack(thr, DUK__COMPILE_ENTRY_SLOTS);
- duk_push_dynamic_buffer(ctx, 0); /* entry_top + 0 */
- duk_push_undefined(ctx); /* entry_top + 1 */
- duk_push_undefined(ctx); /* entry_top + 2 */
- duk_push_undefined(ctx); /* entry_top + 3 */
- duk_push_undefined(ctx); /* entry_top + 4 */
+ duk_push_dynamic_buffer(thr, 0); /* entry_top + 0 */
+ duk_push_undefined(thr); /* entry_top + 1 */
+ duk_push_undefined(thr); /* entry_top + 2 */
+ duk_push_undefined(thr); /* entry_top + 3 */
+ duk_push_undefined(thr); /* entry_top + 4 */
comp_ctx->thr = thr;
comp_ctx->h_filename = h_filename;
@@ -70108,7 +71668,7 @@ DUK_LOCAL duk_ret_t duk__js_compile_raw(duk_context *ctx, void *udata) {
comp_ctx->lex.slot1_idx = comp_ctx->tok11_idx;
comp_ctx->lex.slot2_idx = comp_ctx->tok12_idx;
comp_ctx->lex.buf_idx = entry_top + 0;
- comp_ctx->lex.buf = (duk_hbuffer_dynamic *) duk_known_hbuffer(ctx, entry_top + 0);
+ comp_ctx->lex.buf = (duk_hbuffer_dynamic *) duk_known_hbuffer(thr, entry_top + 0);
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;
@@ -70131,9 +71691,9 @@ DUK_LOCAL duk_ret_t duk__js_compile_raw(duk_context *ctx, void *udata) {
*/
DUK_ASSERT(func->h_name == NULL);
} else {
- duk_push_hstring_stridx(ctx, (is_eval ? DUK_STRIDX_EVAL :
+ duk_push_hstring_stridx(thr, (is_eval ? DUK_STRIDX_EVAL :
DUK_STRIDX_GLOBAL));
- func->h_name = duk_get_hstring(ctx, -1);
+ func->h_name = duk_get_hstring(thr, -1);
}
/*
@@ -70185,7 +71745,6 @@ DUK_LOCAL duk_ret_t duk__js_compile_raw(duk_context *ctx, void *udata) {
}
DUK_INTERNAL void duk_js_compile(duk_hthread *thr, const duk_uint8_t *src_buffer, duk_size_t src_length, duk_small_uint_t flags) {
- duk_context *ctx = (duk_context *) thr;
duk__compiler_stkstate comp_stk;
duk_compiler_ctx *prev_ctx;
duk_ret_t safe_rc;
@@ -70205,12 +71764,12 @@ DUK_INTERNAL void duk_js_compile(duk_hthread *thr, const duk_uint8_t *src_buffer
prev_ctx = thr->compile_ctx;
thr->compile_ctx = &comp_stk.comp_ctx_alloc; /* for duk_error_augment.c */
- safe_rc = duk_safe_call(ctx, duk__js_compile_raw, (void *) &comp_stk /*udata*/, 1 /*nargs*/, 1 /*nret*/);
+ safe_rc = duk_safe_call(thr, duk__js_compile_raw, (void *) &comp_stk /*udata*/, 1 /*nargs*/, 1 /*nrets*/);
thr->compile_ctx = prev_ctx; /* must restore reliably before returning */
if (safe_rc != DUK_EXEC_SUCCESS) {
- DUK_D(DUK_DPRINT("compilation failed: %!T", duk_get_tval(ctx, -1)));
- (void) duk_throw(ctx);
+ DUK_D(DUK_DPRINT("compilation failed: %!T", duk_get_tval(thr, -1)));
+ (void) duk_throw(thr);
}
/* [ ... template ] */
@@ -70271,7 +71830,8 @@ DUK_INTERNAL void duk_js_compile(duk_hthread *thr, const duk_uint8_t *src_buffer
#undef DUK__HAS_VAL
#undef DUK__ISCONST
#undef DUK__ISREG
-#undef DUK__ISTEMP
+#undef DUK__ISREG_NOTTEMP
+#undef DUK__ISREG_TEMP
#undef DUK__IS_TERMINAL
#undef DUK__IVAL_FLAG_ALLOW_CONST
#undef DUK__IVAL_FLAG_REQUIRE_SHORT
@@ -70309,7 +71869,7 @@ DUK_INTERNAL void duk_js_compile(duk_hthread *thr, const duk_uint8_t *src_buffer
* Local declarations.
*/
-DUK_LOCAL_DECL void duk__js_execute_bytecode_inner(duk_hthread *entry_thread, duk_size_t entry_callstack_top);
+DUK_LOCAL_DECL void duk__js_execute_bytecode_inner(duk_hthread *entry_thread, duk_activation *entry_act);
/*
* Misc helpers.
@@ -70318,8 +71878,10 @@ DUK_LOCAL_DECL void duk__js_execute_bytecode_inner(duk_hthread *entry_thread, du
/* Forced inline declaration, only applied for performance oriented build. */
#if defined(DUK_USE_EXEC_PREFER_SIZE)
#define DUK__INLINE_PERF
+#define DUK__NOINLINE_PERF
#else
#define DUK__INLINE_PERF DUK_ALWAYS_INLINE
+#define DUK__NOINLINE_PERF DUK_NOINLINE
#endif
/* Replace value stack top to value at 'tv_ptr'. Optimize for
@@ -70331,7 +71893,7 @@ DUK_LOCAL_DECL void duk__js_execute_bytecode_inner(duk_hthread *entry_thread, du
duk_tval *duk__tvdst; \
duk_tval duk__tvtmp; \
duk__thr = (thr); \
- duk__tvsrc = DUK_GET_TVAL_NEGIDX((duk_context *) duk__thr, -1); \
+ duk__tvsrc = DUK_GET_TVAL_NEGIDX(duk__thr, -1); \
duk__tvdst = (tv_ptr); \
DUK_TVAL_SET_TVAL(&duk__tvtmp, duk__tvdst); \
DUK_TVAL_SET_TVAL(duk__tvdst, duk__tvsrc); \
@@ -70341,7 +71903,7 @@ DUK_LOCAL_DECL void duk__js_execute_bytecode_inner(duk_hthread *entry_thread, du
} while (0)
/* XXX: candidate of being an internal shared API call */
-#if !defined(DUK_USE_EXEC_PREFER_SIZE)
+#if 0 /* unused */
DUK_LOCAL void duk__push_tvals_incref_only(duk_hthread *thr, duk_tval *tv_src, duk_small_uint_fast_t count) {
duk_tval *tv_dst;
duk_size_t copy_size;
@@ -70400,15 +71962,13 @@ DUK_LOCAL DUK__INLINE_PERF void duk__vm_arith_add(duk_hthread *thr, duk_tval *tv
* Custom types also have special behavior implemented here.
*/
- duk_context *ctx = (duk_context *) thr;
duk_double_union du;
DUK_ASSERT(thr != NULL);
- DUK_ASSERT(ctx != NULL);
DUK_ASSERT(tv_x != NULL); /* may be reg or const */
DUK_ASSERT(tv_y != NULL); /* may be reg or const */
DUK_ASSERT_DISABLE(idx_z >= 0); /* unsigned */
- DUK_ASSERT((duk_uint_t) idx_z < (duk_uint_t) duk_get_top(ctx));
+ DUK_ASSERT((duk_uint_t) idx_z < (duk_uint_t) duk_get_top(thr));
/*
* Fast paths
@@ -70428,7 +71988,7 @@ DUK_LOCAL DUK__INLINE_PERF void duk__vm_arith_add(duk_hthread *thr, duk_tval *tv
v2 = DUK_TVAL_GET_FASTINT(tv_y);
v3 = v1 + v2;
v3_hi = (duk_int32_t) (v3 >> 32);
- if (DUK_LIKELY(v3_hi >= -0x8000LL && v3_hi <= 0x7fffLL)) {
+ if (DUK_LIKELY(v3_hi >= DUK_I64_CONSTANT(-0x8000) && v3_hi <= DUK_I64_CONSTANT(0x7fff))) {
tv_z = thr->valstack_bottom + idx_z;
DUK_TVAL_SET_FASTINT_UPDREF(thr, tv_z, v3); /* side effects */
return;
@@ -70446,8 +72006,8 @@ DUK_LOCAL DUK__INLINE_PERF void duk__vm_arith_add(duk_hthread *thr, duk_tval *tv
du.d = DUK_TVAL_GET_NUMBER(tv_x) + DUK_TVAL_GET_NUMBER(tv_y);
#if defined(DUK_USE_EXEC_PREFER_SIZE)
- duk_push_number(ctx, du.d); /* will NaN normalize result */
- duk_replace(ctx, idx_z);
+ duk_push_number(thr, du.d); /* will NaN normalize result */
+ duk_replace(thr, (duk_idx_t) idx_z);
#else /* DUK_USE_EXEC_PREFER_SIZE */
DUK_DBLUNION_NORMALIZE_NAN_CHECK(&du);
DUK_ASSERT(DUK_DBLUNION_IS_NORMALIZED(&du));
@@ -70461,40 +72021,38 @@ DUK_LOCAL DUK__INLINE_PERF void duk__vm_arith_add(duk_hthread *thr, duk_tval *tv
* Slow path: potentially requires function calls for coercion
*/
- duk_push_tval(ctx, tv_x);
- duk_push_tval(ctx, tv_y);
- duk_to_primitive(ctx, -2, DUK_HINT_NONE); /* side effects -> don't use tv_x, tv_y after */
- duk_to_primitive(ctx, -1, DUK_HINT_NONE);
+ duk_push_tval(thr, tv_x);
+ duk_push_tval(thr, tv_y);
+ duk_to_primitive(thr, -2, DUK_HINT_NONE); /* side effects -> don't use tv_x, tv_y after */
+ duk_to_primitive(thr, -1, DUK_HINT_NONE);
/* Since Duktape 2.x plain buffers are treated like ArrayBuffer. */
- if (duk_is_string(ctx, -2) || duk_is_string(ctx, -1)) {
+ if (duk_is_string(thr, -2) || duk_is_string(thr, -1)) {
/* Symbols shouldn't technically be handled here, but should
* go into the default ToNumber() coercion path instead and
* fail there with a TypeError. However, there's a ToString()
- * here which also fails with TypeError so no explicit check
- * is needed.
+ * in duk_concat_2() which also fails with TypeError so no
+ * explicit check is needed.
*/
- duk_to_string(ctx, -2);
- duk_to_string(ctx, -1);
- duk_concat(ctx, 2); /* [... s1 s2] -> [... s1+s2] */
+ duk_concat_2(thr); /* [... s1 s2] -> [... s1+s2] */
} else {
duk_double_t d1, d2;
- d1 = duk_to_number_m2(ctx);
- d2 = duk_to_number_m1(ctx);
- DUK_ASSERT(duk_is_number(ctx, -2));
- DUK_ASSERT(duk_is_number(ctx, -1));
+ d1 = duk_to_number_m2(thr);
+ d2 = duk_to_number_m1(thr);
+ DUK_ASSERT(duk_is_number(thr, -2));
+ DUK_ASSERT(duk_is_number(thr, -1));
DUK_ASSERT_DOUBLE_IS_NORMALIZED(d1);
DUK_ASSERT_DOUBLE_IS_NORMALIZED(d2);
du.d = d1 + d2;
- duk_pop_2(ctx);
- duk_push_number(ctx, du.d); /* will NaN normalize result */
+ duk_pop_2_unsafe(thr);
+ duk_push_number(thr, du.d); /* will NaN normalize result */
}
- duk_replace(ctx, (duk_idx_t) idx_z); /* side effects */
+ duk_replace(thr, (duk_idx_t) idx_z); /* side effects */
}
-DUK_LOCAL DUK__INLINE_PERF void duk__vm_arith_binary_op(duk_hthread *thr, duk_tval *tv_x, duk_tval *tv_y, duk_idx_t idx_z, duk_small_uint_fast_t opcode) {
+DUK_LOCAL DUK__INLINE_PERF void duk__vm_arith_binary_op(duk_hthread *thr, duk_tval *tv_x, duk_tval *tv_y, duk_uint_fast_t idx_z, duk_small_uint_fast_t opcode) {
/*
* Arithmetic operations other than '+' have number-only semantics
* and are implemented here. The separate switch-case here means a
@@ -70503,7 +72061,6 @@ DUK_LOCAL DUK__INLINE_PERF void duk__vm_arith_binary_op(duk_hthread *thr, duk_tv
* E5 Sections 11.5, 11.5.1, 11.5.2, 11.5.3, 11.6, 11.6.1, 11.6.2, 11.6.3.
*/
- duk_context *ctx = (duk_context *) thr;
duk_double_t d1, d2;
duk_double_union du;
duk_small_uint_fast_t opcode_shifted;
@@ -70512,11 +72069,10 @@ DUK_LOCAL DUK__INLINE_PERF void duk__vm_arith_binary_op(duk_hthread *thr, duk_tv
#endif
DUK_ASSERT(thr != NULL);
- DUK_ASSERT(ctx != NULL);
DUK_ASSERT(tv_x != NULL); /* may be reg or const */
DUK_ASSERT(tv_y != NULL); /* may be reg or const */
DUK_ASSERT_DISABLE(idx_z >= 0); /* unsigned */
- DUK_ASSERT((duk_uint_t) idx_z < (duk_uint_t) duk_get_top(ctx));
+ DUK_ASSERT((duk_uint_t) idx_z < (duk_uint_t) duk_get_top(thr));
opcode_shifted = opcode >> 2; /* Get base opcode without reg/const modifiers. */
@@ -70539,8 +72095,8 @@ DUK_LOCAL DUK__INLINE_PERF void duk__vm_arith_binary_op(duk_hthread *thr, duk_tv
* 32-bit inputs. Avoid zero inputs to avoid
* negative zero issues (-1 * 0 = -0, for instance).
*/
- if (v1 >= -0x80000000LL && v1 <= 0x7fffffffLL && v1 != 0 &&
- v2 >= -0x80000000LL && v2 <= 0x7fffffffLL && v2 != 0) {
+ if (v1 >= DUK_I64_CONSTANT(-0x80000000) && v1 <= DUK_I64_CONSTANT(0x7fffffff) && v1 != 0 &&
+ v2 >= DUK_I64_CONSTANT(-0x80000000) && v2 <= DUK_I64_CONSTANT(0x7fffffff) && v2 != 0) {
v3 = v1 * v2;
} else {
goto skip_fastint;
@@ -70583,7 +72139,7 @@ DUK_LOCAL DUK__INLINE_PERF void duk__vm_arith_binary_op(duk_hthread *thr, duk_tv
}
v3_hi = (duk_int32_t) (v3 >> 32);
- if (DUK_LIKELY(v3_hi >= -0x8000LL && v3_hi <= 0x7fffLL)) {
+ if (DUK_LIKELY(v3_hi >= DUK_I64_CONSTANT(-0x8000) && v3_hi <= DUK_I64_CONSTANT(0x7fff))) {
tv_z = thr->valstack_bottom + idx_z;
DUK_TVAL_SET_FASTINT_UPDREF(thr, tv_z, v3); /* side effects */
return;
@@ -70598,15 +72154,15 @@ DUK_LOCAL DUK__INLINE_PERF void duk__vm_arith_binary_op(duk_hthread *thr, duk_tv
d1 = DUK_TVAL_GET_NUMBER(tv_x);
d2 = DUK_TVAL_GET_NUMBER(tv_y);
} else {
- duk_push_tval(ctx, tv_x);
- duk_push_tval(ctx, tv_y);
- d1 = duk_to_number_m2(ctx); /* side effects */
- d2 = duk_to_number_m1(ctx);
- DUK_ASSERT(duk_is_number(ctx, -2));
- DUK_ASSERT(duk_is_number(ctx, -1));
+ duk_push_tval(thr, tv_x);
+ duk_push_tval(thr, tv_y);
+ d1 = duk_to_number_m2(thr); /* side effects */
+ d2 = duk_to_number_m1(thr);
+ DUK_ASSERT(duk_is_number(thr, -2));
+ DUK_ASSERT(duk_is_number(thr, -1));
DUK_ASSERT_DOUBLE_IS_NORMALIZED(d1);
DUK_ASSERT_DOUBLE_IS_NORMALIZED(d2);
- duk_pop_2(ctx);
+ duk_pop_2_unsafe(thr);
}
switch (opcode_shifted) {
@@ -70640,8 +72196,8 @@ DUK_LOCAL DUK__INLINE_PERF void duk__vm_arith_binary_op(duk_hthread *thr, duk_tv
}
#if defined(DUK_USE_EXEC_PREFER_SIZE)
- duk_push_number(ctx, du.d); /* will NaN normalize result */
- duk_replace(ctx, idx_z);
+ duk_push_number(thr, du.d); /* will NaN normalize result */
+ duk_replace(thr, (duk_idx_t) idx_z);
#else /* DUK_USE_EXEC_PREFER_SIZE */
/* important to use normalized NaN with 8-byte tagged types */
DUK_DBLUNION_NORMALIZE_NAN_CHECK(&du);
@@ -70662,7 +72218,6 @@ DUK_LOCAL DUK__INLINE_PERF void duk__vm_bitwise_binary_op(duk_hthread *thr, duk_
* E5 Sections 11.10, 11.7.1, 11.7.2, 11.7.3
*/
- duk_context *ctx = (duk_context *) thr;
duk_int32_t i1, i2, i3;
duk_uint32_t u1, u2, u3;
#if defined(DUK_USE_FASTINT)
@@ -70676,11 +72231,10 @@ DUK_LOCAL DUK__INLINE_PERF void duk__vm_bitwise_binary_op(duk_hthread *thr, duk_
#endif
DUK_ASSERT(thr != NULL);
- DUK_ASSERT(ctx != NULL);
DUK_ASSERT(tv_x != NULL); /* may be reg or const */
DUK_ASSERT(tv_y != NULL); /* may be reg or const */
DUK_ASSERT_DISABLE(idx_z >= 0); /* unsigned */
- DUK_ASSERT((duk_uint_t) idx_z < (duk_uint_t) duk_get_top(ctx));
+ DUK_ASSERT((duk_uint_t) idx_z < (duk_uint_t) duk_get_top(thr));
opcode_shifted = opcode >> 2; /* Get base opcode without reg/const modifiers. */
@@ -70692,11 +72246,11 @@ DUK_LOCAL DUK__INLINE_PERF void duk__vm_bitwise_binary_op(duk_hthread *thr, duk_
else
#endif /* DUK_USE_FASTINT */
{
- duk_push_tval(ctx, tv_x);
- duk_push_tval(ctx, tv_y);
- i1 = duk_to_int32(ctx, -2);
- i2 = duk_to_int32(ctx, -1);
- duk_pop_2(ctx);
+ duk_push_tval(thr, tv_x);
+ duk_push_tval(thr, tv_y);
+ i1 = duk_to_int32(thr, -2);
+ i2 = duk_to_int32(thr, -1);
+ duk_pop_2_unsafe(thr);
}
switch (opcode_shifted) {
@@ -70771,8 +72325,8 @@ DUK_LOCAL DUK__INLINE_PERF void duk__vm_bitwise_binary_op(duk_hthread *thr, duk_
DUK_ASSERT_DOUBLE_IS_NORMALIZED(d3); /* always normalized */
#if defined(DUK_USE_EXEC_PREFER_SIZE)
- duk_push_number(ctx, d3); /* would NaN normalize result, but unnecessary */
- duk_replace(ctx, idx_z);
+ duk_push_number(thr, d3); /* would NaN normalize result, but unnecessary */
+ duk_replace(thr, (duk_idx_t) idx_z);
#else /* DUK_USE_EXEC_PREFER_SIZE */
tv_z = thr->valstack_bottom + idx_z;
DUK_TVAL_SET_NUMBER_UPDREF(thr, tv_z, d3); /* side effects */
@@ -70781,7 +72335,7 @@ DUK_LOCAL DUK__INLINE_PERF void duk__vm_bitwise_binary_op(duk_hthread *thr, duk_
}
/* In-place unary operation. */
-DUK_LOCAL DUK__INLINE_PERF void duk__vm_arith_unary_op(duk_hthread *thr, duk_idx_t idx_src, duk_idx_t idx_dst, duk_small_uint_fast_t opcode) {
+DUK_LOCAL DUK__INLINE_PERF void duk__vm_arith_unary_op(duk_hthread *thr, duk_uint_fast_t idx_src, duk_uint_fast_t idx_dst, duk_small_uint_fast_t opcode) {
/*
* Arithmetic operations other than '+' have number-only semantics
* and are implemented here. The separate switch-case here means a
@@ -70790,18 +72344,16 @@ DUK_LOCAL DUK__INLINE_PERF void duk__vm_arith_unary_op(duk_hthread *thr, duk_idx
* E5 Sections 11.5, 11.5.1, 11.5.2, 11.5.3, 11.6, 11.6.1, 11.6.2, 11.6.3.
*/
- duk_context *ctx = (duk_context *) thr;
duk_tval *tv;
duk_double_t d1;
duk_double_union du;
DUK_ASSERT(thr != NULL);
- DUK_ASSERT(ctx != NULL);
DUK_ASSERT(opcode == DUK_OP_UNM || opcode == DUK_OP_UNP);
- DUK_ASSERT(idx_src >= 0);
- DUK_ASSERT(idx_dst >= 0);
+ DUK_ASSERT_DISABLE(idx_src >= 0);
+ DUK_ASSERT_DISABLE(idx_dst >= 0);
- tv = DUK_GET_TVAL_POSIDX(ctx, idx_src);
+ tv = DUK_GET_TVAL_POSIDX(thr, (duk_idx_t) idx_src);
#if defined(DUK_USE_FASTINT)
if (DUK_TVAL_IS_FASTINT(tv)) {
@@ -70815,7 +72367,7 @@ DUK_LOCAL DUK__INLINE_PERF void duk__vm_arith_unary_op(duk_hthread *thr, duk_idx
*/
if (DUK_LIKELY(v1 != DUK_FASTINT_MIN && v1 != 0)) {
v2 = -v1;
- tv = DUK_GET_TVAL_POSIDX(ctx, idx_dst);
+ tv = DUK_GET_TVAL_POSIDX(thr, (duk_idx_t) idx_dst);
DUK_TVAL_SET_FASTINT_UPDREF(thr, tv, v2);
return;
}
@@ -70823,7 +72375,7 @@ DUK_LOCAL DUK__INLINE_PERF void duk__vm_arith_unary_op(duk_hthread *thr, duk_idx
/* ToNumber() for a fastint is a no-op. */
DUK_ASSERT(opcode == DUK_OP_UNP);
v2 = v1;
- tv = DUK_GET_TVAL_POSIDX(ctx, idx_dst);
+ tv = DUK_GET_TVAL_POSIDX(thr, (duk_idx_t) idx_dst);
DUK_TVAL_SET_FASTINT_UPDREF(thr, tv, v2);
return;
}
@@ -70834,8 +72386,7 @@ DUK_LOCAL DUK__INLINE_PERF void duk__vm_arith_unary_op(duk_hthread *thr, duk_idx
if (DUK_TVAL_IS_NUMBER(tv)) {
d1 = DUK_TVAL_GET_NUMBER(tv);
} else {
- d1 = duk_to_number(ctx, idx_src); /* side effects, perform in-place */
- DUK_ASSERT(DUK_TVAL_IS_NUMBER(DUK_GET_TVAL_POSIDX(ctx, idx_src)));
+ d1 = duk_to_number_tval(thr, tv); /* side effects */
}
if (opcode == DUK_OP_UNP) {
@@ -70845,7 +72396,7 @@ DUK_LOCAL DUK__INLINE_PERF void duk__vm_arith_unary_op(duk_hthread *thr, duk_idx
du.d = d1;
DUK_ASSERT(DUK_DBLUNION_IS_NORMALIZED(&du));
#if defined(DUK_USE_FASTINT)
- tv = DUK_GET_TVAL_POSIDX(ctx, idx_dst);
+ tv = DUK_GET_TVAL_POSIDX(thr, (duk_idx_t) idx_dst);
DUK_TVAL_SET_NUMBER_CHKFAST_UPDREF(thr, tv, du.d); /* always 'fast', i.e. inlined */
return;
#endif
@@ -70857,7 +72408,7 @@ DUK_LOCAL DUK__INLINE_PERF void duk__vm_arith_unary_op(duk_hthread *thr, duk_idx
}
/* XXX: size optimize: push+replace? */
- tv = DUK_GET_TVAL_POSIDX(ctx, idx_dst);
+ tv = DUK_GET_TVAL_POSIDX(thr, (duk_idx_t) idx_dst);
DUK_TVAL_SET_NUMBER_UPDREF(thr, tv, du.d);
}
@@ -70866,19 +72417,16 @@ DUK_LOCAL DUK__INLINE_PERF void duk__vm_bitwise_not(duk_hthread *thr, duk_uint_f
* E5 Section 11.4.8
*/
- duk_context *ctx = (duk_context *) thr;
duk_tval *tv;
duk_int32_t i1, i2;
DUK_ASSERT(thr != NULL);
- DUK_ASSERT(ctx != NULL);
DUK_ASSERT_DISABLE(idx_src >= 0);
DUK_ASSERT_DISABLE(idx_dst >= 0);
- DUK_ASSERT((duk_uint_t) idx_src < (duk_uint_t) duk_get_top(ctx));
- DUK_ASSERT((duk_uint_t) idx_dst < (duk_uint_t) duk_get_top(ctx));
- DUK_UNREF(thr); /* w/o refcounts */
+ DUK_ASSERT((duk_uint_t) idx_src < (duk_uint_t) duk_get_top(thr));
+ DUK_ASSERT((duk_uint_t) idx_dst < (duk_uint_t) duk_get_top(thr));
- tv = DUK_GET_TVAL_POSIDX(ctx, idx_src);
+ tv = DUK_GET_TVAL_POSIDX(thr, (duk_idx_t) idx_src);
#if defined(DUK_USE_FASTINT)
if (DUK_TVAL_IS_FASTINT(tv)) {
@@ -70887,48 +72435,46 @@ DUK_LOCAL DUK__INLINE_PERF void duk__vm_bitwise_not(duk_hthread *thr, duk_uint_f
else
#endif /* DUK_USE_FASTINT */
{
- i1 = duk_to_int32(ctx, idx_src); /* side effects */
+ duk_push_tval(thr, tv);
+ i1 = duk_to_int32(thr, -1); /* side effects */
+ duk_pop_unsafe(thr);
}
/* Result is always fastint compatible. */
i2 = ~i1;
- tv = DUK_GET_TVAL_POSIDX(ctx, idx_dst);
+ tv = DUK_GET_TVAL_POSIDX(thr, (duk_idx_t) idx_dst);
DUK_TVAL_SET_I32_UPDREF(thr, tv, i2); /* side effects */
}
-DUK_LOCAL DUK__INLINE_PERF void duk__vm_logical_not(duk_hthread *thr, duk_idx_t idx_src, duk_idx_t idx_dst) {
+DUK_LOCAL DUK__INLINE_PERF void duk__vm_logical_not(duk_hthread *thr, duk_uint_fast_t idx_src, duk_uint_fast_t idx_dst) {
/*
* E5 Section 11.4.9
*/
- duk_context *ctx = (duk_context *) thr;
duk_tval *tv;
duk_bool_t res;
DUK_ASSERT(thr != NULL);
- DUK_ASSERT(ctx != NULL);
DUK_ASSERT_DISABLE(idx_src >= 0);
DUK_ASSERT_DISABLE(idx_dst >= 0);
- DUK_ASSERT((duk_uint_t) idx_src < (duk_uint_t) duk_get_top(ctx));
- DUK_ASSERT((duk_uint_t) idx_dst < (duk_uint_t) duk_get_top(ctx));
- DUK_UNREF(thr); /* w/o refcounts */
+ DUK_ASSERT((duk_uint_t) idx_src < (duk_uint_t) duk_get_top(thr));
+ DUK_ASSERT((duk_uint_t) idx_dst < (duk_uint_t) duk_get_top(thr));
/* ToBoolean() does not require any operations with side effects so
* we can do it efficiently. For footprint it would be better to use
* duk_js_toboolean() and then push+replace to the result slot.
*/
- tv = DUK_GET_TVAL_POSIDX(ctx, idx_src);
+ tv = DUK_GET_TVAL_POSIDX(thr, (duk_idx_t) idx_src);
res = duk_js_toboolean(tv); /* does not modify 'tv' */
DUK_ASSERT(res == 0 || res == 1);
res ^= 1;
- tv = DUK_GET_TVAL_POSIDX(ctx, idx_dst);
+ tv = DUK_GET_TVAL_POSIDX(thr, (duk_idx_t) idx_dst);
/* XXX: size optimize: push+replace? */
DUK_TVAL_SET_BOOLEAN_UPDREF(thr, tv, res); /* side effects */
}
/* XXX: size optimized variant */
DUK_LOCAL DUK__INLINE_PERF void duk__prepost_incdec_reg_helper(duk_hthread *thr, duk_tval *tv_dst, duk_tval *tv_src, duk_small_uint_t op) {
- duk_context *ctx = (duk_context *) thr;
duk_double_t x, y, z;
/* Two lowest bits of opcode are used to distinguish
@@ -70987,15 +72533,15 @@ DUK_LOCAL DUK__INLINE_PERF void duk__prepost_incdec_reg_helper(duk_hthread *thr,
bc = (duk_idx_t) (tv_src - thr->valstack_bottom); /* XXX: pass index explicitly? */
tv_src = NULL; /* no longer referenced */
- x = duk_to_number(ctx, bc);
+ x = duk_to_number(thr, bc);
if (op & 0x01) {
y = x - 1.0;
} else {
y = x + 1.0;
}
- duk_push_number(ctx, y);
- duk_replace(ctx, bc);
+ duk_push_number(thr, y);
+ duk_replace(thr, bc);
tv_dst = (duk_tval *) (void *) (((duk_uint8_t *) thr->valstack_bottom) + off_dst);
}
@@ -71004,8 +72550,7 @@ DUK_LOCAL DUK__INLINE_PERF void duk__prepost_incdec_reg_helper(duk_hthread *thr,
DUK_TVAL_SET_NUMBER_UPDREF(thr, tv_dst, z); /* side effects */
}
-DUK_LOCAL DUK__INLINE_PERF void duk__prepost_incdec_var_helper(duk_hthread *thr, duk_small_uint_t idx_dst, duk_tval *tv_id, duk_small_uint_t op, duk_uint_t is_strict) {
- duk_context *ctx = (duk_context *) thr;
+DUK_LOCAL DUK__INLINE_PERF void duk__prepost_incdec_var_helper(duk_hthread *thr, duk_small_uint_t idx_dst, duk_tval *tv_id, duk_small_uint_t op, duk_small_uint_t is_strict) {
duk_activation *act;
duk_double_t x, y;
duk_hstring *name;
@@ -71038,7 +72583,7 @@ DUK_LOCAL DUK__INLINE_PERF void duk__prepost_incdec_var_helper(duk_hthread *thr,
* not intuitive.
*/
- x = duk_to_number_m2(ctx);
+ x = duk_to_number_m2(thr);
if (op & 0x01) {
y = x - 1.0;
} else {
@@ -71048,21 +72593,21 @@ DUK_LOCAL DUK__INLINE_PERF void duk__prepost_incdec_var_helper(duk_hthread *thr,
/* [... x this] */
if (op & 0x02) {
- duk_push_number(ctx, y); /* -> [ ... x this y ] */
- act = thr->callstack_curr;
- duk_js_putvar_activation(thr, act, name, DUK_GET_TVAL_NEGIDX(ctx, -1), is_strict);
- duk_pop_2(ctx); /* -> [ ... x ] */
+ duk_push_number(thr, y); /* -> [ ... x this y ] */
+ DUK_ASSERT(act == thr->callstack_curr);
+ duk_js_putvar_activation(thr, act, name, DUK_GET_TVAL_NEGIDX(thr, -1), is_strict);
+ duk_pop_2_unsafe(thr); /* -> [ ... x ] */
} else {
- duk_pop_2(ctx); /* -> [ ... ] */
- duk_push_number(ctx, y); /* -> [ ... y ] */
- act = thr->callstack_curr;
- duk_js_putvar_activation(thr, act, name, DUK_GET_TVAL_NEGIDX(ctx, -1), is_strict);
+ duk_pop_2_unsafe(thr); /* -> [ ... ] */
+ duk_push_number(thr, y); /* -> [ ... y ] */
+ DUK_ASSERT(act == thr->callstack_curr);
+ duk_js_putvar_activation(thr, act, name, DUK_GET_TVAL_NEGIDX(thr, -1), is_strict);
}
#if defined(DUK_USE_EXEC_PREFER_SIZE)
- duk_replace(ctx, (duk_idx_t) idx_dst);
+ duk_replace(thr, (duk_idx_t) idx_dst);
#else /* DUK_USE_EXEC_PREFER_SIZE */
- DUK__REPLACE_TO_TVPTR(thr, DUK_GET_TVAL_POSIDX(ctx, idx_dst));
+ DUK__REPLACE_TO_TVPTR(thr, DUK_GET_TVAL_POSIDX(thr, (duk_idx_t) idx_dst));
#endif /* DUK_USE_EXEC_PREFER_SIZE */
}
@@ -71087,119 +72632,118 @@ DUK_LOCAL DUK__INLINE_PERF void duk__prepost_incdec_var_helper(duk_hthread *thr,
* top are combined into one pass.
*/
-/* 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) {
+/* Reconfigure value stack for return to an Ecmascript function at
+ * callstack top (caller unwinds).
+ */
+DUK_LOCAL void duk__reconfig_valstack_ecma_return(duk_hthread *thr) {
duk_activation *act;
duk_hcompfunc *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_COMPFUNC(DUK_ACT_GET_FUNC(thr->callstack + act_idx)));
- DUK_ASSERT_DISABLE(thr->callstack[act_idx].idx_retval >= 0); /* unsigned */
+ act = thr->callstack_curr;
+ DUK_ASSERT(act != NULL);
+ DUK_ASSERT(DUK_ACT_GET_FUNC(act) != NULL);
+ DUK_ASSERT(DUK_HOBJECT_IS_COMPFUNC(DUK_ACT_GET_FUNC(act)));
/* 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.
*/
- act = thr->callstack + act_idx;
h_func = (duk_hcompfunc *) DUK_ACT_GET_FUNC(act);
- 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;
+ thr->valstack_bottom = (duk_tval *) (void *) ((duk_uint8_t *) thr->valstack + act->bottom_byteoff);
+ DUK_ASSERT(act->retval_byteoff >= act->bottom_byteoff);
+ clamp_top = (duk_idx_t) ((act->retval_byteoff - act->bottom_byteoff + sizeof(duk_tval)) / sizeof(duk_tval)); /* +1 = one retval */
+ duk_set_top_and_wipe(thr, h_func->nregs, clamp_top);
- (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_ASSERT((duk_uint8_t *) thr->valstack_end >= (duk_uint8_t *) thr->valstack + act->reserve_byteoff);
+ thr->valstack_end = (duk_tval *) (void *) ((duk_uint8_t *) thr->valstack + act->reserve_byteoff);
- duk_set_top((duk_context *) thr, h_func->nregs);
+ /* XXX: a best effort shrink check would be OK here */
}
-DUK_LOCAL void duk__reconfig_valstack_ecma_catcher(duk_hthread *thr, duk_size_t act_idx, duk_size_t cat_idx) {
- duk_activation *act;
+/* Reconfigure value stack for an Ecmascript catcher. Use topmost catcher
+ * in 'act'.
+ */
+DUK_LOCAL void duk__reconfig_valstack_ecma_catcher(duk_hthread *thr, duk_activation *act) {
duk_catcher *cat;
duk_hcompfunc *h_func;
+ duk_size_t idx_bottom;
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_COMPFUNC(DUK_ACT_GET_FUNC(thr->callstack + act_idx)));
- DUK_ASSERT_DISABLE(thr->callstack[act_idx].idx_retval >= 0); /* unsigned */
+ DUK_ASSERT(act != NULL);
+ DUK_ASSERT(DUK_ACT_GET_FUNC(act) != NULL);
+ DUK_ASSERT(DUK_HOBJECT_IS_COMPFUNC(DUK_ACT_GET_FUNC(act)));
+ cat = act->cat;
+ DUK_ASSERT(cat != NULL);
- act = thr->callstack + act_idx;
- cat = thr->catchstack + cat_idx;
h_func = (duk_hcompfunc *) DUK_ACT_GET_FUNC(act);
- 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;
+ thr->valstack_bottom = (duk_tval *) (void *) ((duk_uint8_t *) thr->valstack + act->bottom_byteoff);
+ idx_bottom = (duk_size_t) (thr->valstack_bottom - thr->valstack);
+ DUK_ASSERT(cat->idx_base >= idx_bottom);
+ clamp_top = (duk_idx_t) (cat->idx_base - idx_bottom + 2); /* +2 = catcher value, catcher lj_type */
+ duk_set_top_and_wipe(thr, h_func->nregs, clamp_top);
- (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_ASSERT((duk_uint8_t *) thr->valstack_end >= (duk_uint8_t *) thr->valstack + act->reserve_byteoff);
+ thr->valstack_end = (duk_tval *) (void *) ((duk_uint8_t *) thr->valstack + act->reserve_byteoff);
- duk_set_top((duk_context *) thr, h_func->nregs);
+ /* XXX: a best effort shrink check would be OK here */
}
-/* 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) {
+/* Set catcher regs: idx_base+0 = value, idx_base+1 = lj_type.
+ * No side effects.
+ */
+DUK_LOCAL void duk__set_catcher_regs_norz(duk_hthread *thr, duk_catcher *cat, 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;
+ tv1 = thr->valstack + cat->idx_base;
DUK_ASSERT(tv1 < thr->valstack_top);
- DUK_TVAL_SET_TVAL_UPDREF(thr, tv1, tv_val_unstable); /* side effects */
+ DUK_TVAL_SET_TVAL_UPDREF_NORZ(thr, tv1, tv_val_unstable);
- tv1 = thr->valstack + thr->catchstack[cat_idx].idx_base + 1;
+ tv1++;
+ DUK_ASSERT(tv1 == thr->valstack + cat->idx_base + 1);
DUK_ASSERT(tv1 < thr->valstack_top);
-
- DUK_TVAL_SET_U32_UPDREF(thr, tv1, (duk_uint32_t) lj_type); /* side effects */
+ DUK_TVAL_SET_U32_UPDREF_NORZ(thr, tv1, (duk_uint32_t) lj_type);
}
-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_LOCAL void duk__handle_catch(duk_hthread *thr, duk_tval *tv_val_unstable, duk_small_uint_t lj_type) {
duk_activation *act;
+ duk_catcher *cat;
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);
+ act = thr->callstack_curr;
+ DUK_ASSERT(act != NULL);
+ DUK_ASSERT(act->cat != NULL);
+ DUK_ASSERT(DUK_CAT_GET_TYPE(act->cat) == DUK_CAT_TYPE_TCF);
- duk_hthread_catchstack_unwind_norz(thr, cat_idx + 1);
- duk_hthread_callstack_unwind_norz(thr, thr->catchstack[cat_idx].callstack_index + 1);
+ duk__set_catcher_regs_norz(thr, act->cat, tv_val_unstable, lj_type);
DUK_ASSERT(thr->callstack_top >= 1);
DUK_ASSERT(thr->callstack_curr != NULL);
DUK_ASSERT(DUK_ACT_GET_FUNC(thr->callstack_curr) != NULL);
DUK_ASSERT(DUK_HOBJECT_IS_COMPFUNC(DUK_ACT_GET_FUNC(thr->callstack_curr)));
- duk__reconfig_valstack_ecma_catcher(thr, thr->callstack_top - 1, cat_idx);
+ DUK_ASSERT(thr->callstack_top >= 1);
+ DUK_ASSERT(act == thr->callstack_curr);
+ DUK_ASSERT(act != NULL);
+ duk__reconfig_valstack_ecma_catcher(thr, act);
DUK_ASSERT(thr->callstack_top >= 1);
- act = thr->callstack_curr;
+ DUK_ASSERT(act == thr->callstack_curr);
DUK_ASSERT(act != NULL);
- act->curr_pc = thr->catchstack[cat_idx].pc_base + 0; /* +0 = catch */
- act = NULL;
+ cat = act->cat;
+ DUK_ASSERT(cat != NULL);
+
+ act->curr_pc = cat->pc_base + 0; /* +0 = catch */
/*
* If entering a 'catch' block which requires an automatic
@@ -71211,31 +72755,26 @@ DUK_LOCAL void duk__handle_catch(duk_hthread *thr, duk_size_t cat_idx, duk_tval
* which implies the binding is not deletable.
*/
- if (DUK_CAT_HAS_CATCH_BINDING_ENABLED(&thr->catchstack[cat_idx])) {
+ if (DUK_CAT_HAS_CATCH_BINDING_ENABLED(cat)) {
duk_hdecenv *new_env;
DUK_DDD(DUK_DDDPRINT("catcher has an automatic catch binding"));
- /* Note: 'act' is dangerous here because it may get invalidate at many
- * points, so we re-lookup it multiple times.
- */
DUK_ASSERT(thr->callstack_top >= 1);
- act = thr->callstack_curr;
+ DUK_ASSERT(act == thr->callstack_curr);
DUK_ASSERT(act != NULL);
if (act->lex_env == NULL) {
DUK_ASSERT(act->var_env == NULL);
DUK_DDD(DUK_DDDPRINT("delayed environment initialization"));
- /* this may have side effects, so re-lookup act */
duk_js_init_activation_environment_records_delayed(thr, act);
- act = thr->callstack_curr;
+ DUK_ASSERT(act == thr->callstack_curr);
DUK_ASSERT(act != NULL);
}
DUK_ASSERT(act->lex_env != NULL);
DUK_ASSERT(act->var_env != NULL);
DUK_ASSERT(DUK_ACT_GET_FUNC(act) != NULL);
- DUK_UNREF(act); /* unreferenced without assertions */
/* XXX: If an out-of-memory happens here, longjmp state asserts
* will be triggered at present and a try-catch fails to catch.
@@ -71247,7 +72786,7 @@ DUK_LOCAL void duk__handle_catch(duk_hthread *thr, duk_size_t cat_idx, duk_tval
DUK_HOBJECT_FLAG_EXTENSIBLE |
DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_DECENV));
DUK_ASSERT(new_env != NULL);
- duk_push_hobject(ctx, (duk_hobject *) new_env);
+ duk_push_hobject(thr, (duk_hobject *) new_env);
DUK_ASSERT(DUK_HOBJECT_GET_PROTOTYPE(thr->heap, (duk_hobject *) new_env) == NULL);
DUK_DDD(DUK_DDDPRINT("new_env allocated: %!iO", (duk_heaphdr *) new_env));
@@ -71258,12 +72797,12 @@ DUK_LOCAL void duk__handle_catch(duk_hthread *thr, duk_size_t cat_idx, duk_tval
*/
/* XXX: duk_xdef_prop() may cause an out-of-memory, see above. */
- DUK_ASSERT(thr->catchstack[cat_idx].h_varname != NULL);
- duk_push_hstring(ctx, thr->catchstack[cat_idx].h_varname);
- duk_push_tval(ctx, thr->valstack + thr->catchstack[cat_idx].idx_base);
- duk_xdef_prop(ctx, -3, DUK_PROPDESC_FLAGS_W); /* writable, not configurable */
+ DUK_ASSERT(cat->h_varname != NULL);
+ duk_push_hstring(thr, cat->h_varname);
+ duk_push_tval(thr, thr->valstack + cat->idx_base);
+ duk_xdef_prop(thr, -3, DUK_PROPDESC_FLAGS_W); /* writable, not configurable */
- act = thr->callstack_curr;
+ DUK_ASSERT(act == thr->callstack_curr);
DUK_ASSERT(act != NULL);
DUK_HOBJECT_SET_PROTOTYPE(thr->heap, (duk_hobject *) new_env, act->lex_env);
act->lex_env = (duk_hobject *) new_env;
@@ -71272,66 +72811,74 @@ DUK_LOCAL void duk__handle_catch(duk_hthread *thr, duk_size_t cat_idx, duk_tval
* prototype, decref for act->lex_env overwrite.
*/
- DUK_CAT_SET_LEXENV_ACTIVE(&thr->catchstack[cat_idx]);
+ DUK_CAT_SET_LEXENV_ACTIVE(cat);
- duk_pop(ctx);
+ duk_pop_unsafe(thr);
DUK_DDD(DUK_DDDPRINT("new_env finished: %!iO", (duk_heaphdr *) new_env));
}
- DUK_CAT_CLEAR_CATCH_ENABLED(&thr->catchstack[cat_idx]);
+ DUK_CAT_CLEAR_CATCH_ENABLED(cat);
}
-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_LOCAL void duk__handle_finally(duk_hthread *thr, duk_tval *tv_val_unstable, duk_small_uint_t lj_type) {
duk_activation *act;
+ duk_catcher *cat;
DUK_ASSERT(thr != NULL);
DUK_ASSERT(tv_val_unstable != NULL);
- duk__set_catcher_regs(thr, cat_idx, tv_val_unstable, lj_type);
+ act = thr->callstack_curr;
+ DUK_ASSERT(act != NULL);
+ DUK_ASSERT(act->cat != NULL);
+ DUK_ASSERT(DUK_CAT_GET_TYPE(act->cat) == DUK_CAT_TYPE_TCF);
- duk_hthread_catchstack_unwind_norz(thr, cat_idx + 1); /* cat_idx catcher is kept, even for finally */
- duk_hthread_callstack_unwind_norz(thr, thr->catchstack[cat_idx].callstack_index + 1);
+ duk__set_catcher_regs_norz(thr, act->cat, tv_val_unstable, lj_type);
DUK_ASSERT(thr->callstack_top >= 1);
DUK_ASSERT(thr->callstack_curr != NULL);
DUK_ASSERT(DUK_ACT_GET_FUNC(thr->callstack_curr) != NULL);
DUK_ASSERT(DUK_HOBJECT_IS_COMPFUNC(DUK_ACT_GET_FUNC(thr->callstack_curr)));
- duk__reconfig_valstack_ecma_catcher(thr, thr->callstack_top - 1, cat_idx);
+ DUK_ASSERT(thr->callstack_top >= 1);
+ DUK_ASSERT(act == thr->callstack_curr);
+ DUK_ASSERT(act != NULL);
+ duk__reconfig_valstack_ecma_catcher(thr, act);
DUK_ASSERT(thr->callstack_top >= 1);
- act = thr->callstack_curr;
+ DUK_ASSERT(act == thr->callstack_curr);
DUK_ASSERT(act != NULL);
- act->curr_pc = thr->catchstack[cat_idx].pc_base + 1; /* +1 = finally */
- act = NULL;
+ cat = act->cat;
+ DUK_ASSERT(cat != NULL);
- DUK_CAT_CLEAR_FINALLY_ENABLED(&thr->catchstack[cat_idx]);
+ act->curr_pc = cat->pc_base + 1; /* +1 = finally */
+
+ DUK_CAT_CLEAR_FINALLY_ENABLED(cat);
}
-DUK_LOCAL void duk__handle_label(duk_hthread *thr, duk_size_t cat_idx, duk_small_uint_t lj_type) {
+DUK_LOCAL void duk__handle_label(duk_hthread *thr, duk_small_uint_t lj_type) {
duk_activation *act;
+ duk_catcher *cat;
DUK_ASSERT(thr != NULL);
DUK_ASSERT(thr->callstack_top >= 1);
act = thr->callstack_curr;
DUK_ASSERT(act != NULL);
-
DUK_ASSERT(DUK_ACT_GET_FUNC(act) != NULL);
DUK_ASSERT(DUK_HOBJECT_HAS_COMPFUNC(DUK_ACT_GET_FUNC(act)));
/* +0 = break, +1 = continue */
- act->curr_pc = thr->catchstack[cat_idx].pc_base + (lj_type == DUK_LJ_TYPE_CONTINUE ? 1 : 0);
- act = NULL; /* invalidated */
+ cat = act->cat;
+ DUK_ASSERT(cat != NULL);
+ DUK_ASSERT(DUK_CAT_GET_TYPE(cat) == DUK_CAT_TYPE_LABEL);
- duk_hthread_catchstack_unwind_norz(thr, cat_idx + 1); /* keep label catcher */
- /* no need to unwind callstack */
+ act->curr_pc = cat->pc_base + (lj_type == DUK_LJ_TYPE_CONTINUE ? 1 : 0);
/* valstack should not need changes */
#if defined(DUK_USE_ASSERTIONS)
DUK_ASSERT(thr->callstack_top >= 1);
- act = thr->callstack_curr;
+ DUK_ASSERT(act == thr->callstack_curr);
DUK_ASSERT(act != NULL);
DUK_ASSERT((duk_size_t) (thr->valstack_top - thr->valstack_bottom) ==
(duk_size_t) ((duk_hcompfunc *) DUK_ACT_GET_FUNC(act))->nregs);
@@ -71340,41 +72887,35 @@ DUK_LOCAL void duk__handle_label(duk_hthread *thr, duk_size_t cat_idx, duk_small
/* 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.
+ * Caller unwinds so that top of callstack is the activation we return to.
*/
#if defined(DUK_USE_COROUTINE_SUPPORT)
-DUK_LOCAL void duk__handle_yield(duk_hthread *thr, duk_hthread *resumer, duk_size_t act_idx, duk_tval *tv_val_unstable) {
+DUK_LOCAL void duk__handle_yield(duk_hthread *thr, duk_hthread *resumer, duk_tval *tv_val_unstable) {
+ duk_activation *act_resumer;
duk_tval *tv1;
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_COMPFUNC(DUK_ACT_GET_FUNC(resumer->callstack + act_idx))); /* resume caller must be an ecmascript func */
-
- tv1 = resumer->valstack + resumer->callstack[act_idx].idx_retval; /* return value from Duktape.Thread.resume() */
- DUK_TVAL_SET_TVAL_UPDREF(thr, tv1, tv_val_unstable); /* side effects */
+ act_resumer = resumer->callstack_curr;
+ DUK_ASSERT(act_resumer != NULL);
+ DUK_ASSERT(DUK_ACT_GET_FUNC(act_resumer) != NULL);
+ DUK_ASSERT(DUK_HOBJECT_IS_COMPFUNC(DUK_ACT_GET_FUNC(act_resumer))); /* resume caller must be an ecmascript func */
- duk_hthread_callstack_unwind_norz(resumer, act_idx + 1); /* unwind to 'resume' caller */
+ tv1 = (duk_tval *) (void *) ((duk_uint8_t *) resumer->valstack + act_resumer->retval_byteoff); /* return value from Duktape.Thread.resume() */
+ DUK_TVAL_SET_TVAL_UPDREF(thr, tv1, tv_val_unstable); /* side effects */ /* XXX: avoid side effects */
- /* no need to unwind catchstack */
- duk__reconfig_valstack_ecma_return(resumer, act_idx);
+ duk__reconfig_valstack_ecma_return(resumer);
/* caller must change active thread, and set thr->resumer to NULL */
}
#endif /* DUK_USE_COROUTINE_SUPPORT */
-DUK_LOCAL
-duk_small_uint_t duk__handle_longjmp(duk_hthread *thr,
- duk_hthread *entry_thread,
- duk_size_t entry_callstack_top) {
- duk_size_t entry_callstack_index;
+DUK_LOCAL duk_small_uint_t duk__handle_longjmp(duk_hthread *thr, duk_activation *entry_act) {
duk_small_uint_t retval = DUK__LONGJMP_RESTART;
DUK_ASSERT(thr != NULL);
- DUK_ASSERT(entry_thread != NULL);
- DUK_ASSERT(entry_callstack_top > 0); /* guarantees entry_callstack_top - 1 >= 0 */
-
- entry_callstack_index = entry_callstack_top - 1;
+ DUK_ASSERT(entry_act != NULL);
/* 'thr' is the current thread, as no-one resumes except us and we
* switch 'thr' in that case.
@@ -71410,7 +72951,6 @@ duk_small_uint_t duk__handle_longjmp(duk_hthread *thr,
duk_tval *tv;
duk_tval *tv2;
- duk_size_t act_idx;
duk_hthread *resumee;
/* duk_bi_duk_object_yield() and duk_bi_duk_object_resume() ensure all of these are met */
@@ -71418,10 +72958,10 @@ duk_small_uint_t duk__handle_longjmp(duk_hthread *thr,
DUK_ASSERT(thr->state == DUK_HTHREAD_STATE_RUNNING); /* unchanged by Duktape.Thread.resume() */
DUK_ASSERT(thr->callstack_top >= 2); /* Ecmascript activation + Duktape.Thread.resume() activation */
DUK_ASSERT(thr->callstack_curr != NULL);
+ DUK_ASSERT(thr->callstack_curr->parent != NULL);
DUK_ASSERT(DUK_ACT_GET_FUNC(thr->callstack_curr) != NULL &&
DUK_HOBJECT_IS_NATFUNC(DUK_ACT_GET_FUNC(thr->callstack_curr)) &&
((duk_hnatfunc *) DUK_ACT_GET_FUNC(thr->callstack_curr))->func == duk_bi_thread_resume);
- DUK_ASSERT_DISABLE((thr->callstack_curr - 1)->idx_retval >= 0); /* unsigned */
tv = &thr->heap->lj.value2; /* resumee */
DUK_ASSERT(DUK_TVAL_IS_OBJECT(tv));
@@ -71439,8 +72979,6 @@ duk_small_uint_t duk__handle_longjmp(duk_hthread *thr,
(DUK_ACT_GET_FUNC(resumee->callstack_curr) != NULL &&
DUK_HOBJECT_IS_NATFUNC(DUK_ACT_GET_FUNC(resumee->callstack_curr)) &&
((duk_hnatfunc *) DUK_ACT_GET_FUNC(resumee->callstack_curr))->func == duk_bi_thread_yield));
- DUK_ASSERT_DISABLE(resumee->state != DUK_HTHREAD_STATE_YIELDED ||
- (resumee->callstack_curr - 1)->idx_retval >= 0); /* idx_retval unsigned */
DUK_ASSERT(resumee->state != DUK_HTHREAD_STATE_INACTIVE ||
resumee->callstack_top == 0); /* INACTIVE: no activation, single function value on valstack */
@@ -71473,19 +73011,28 @@ duk_small_uint_t duk__handle_longjmp(duk_hthread *thr,
DUK_DD(DUK_DDPRINT("-> resume with an error, converted to a throw in the resumee, propagate"));
goto check_longjmp;
} else if (resumee->state == DUK_HTHREAD_STATE_YIELDED) {
- act_idx = resumee->callstack_top - 2; /* Ecmascript function */
- DUK_ASSERT_DISABLE(resumee->callstack[act_idx].idx_retval >= 0); /* unsigned */
+ /* Unwind previous Duktape.Thread.yield() call. The
+ * activation remaining must always be an Ecmascript
+ * call now (yield() accepts calls from Ecmascript
+ * only).
+ */
+ duk_activation *act_resumee;
+
+ DUK_ASSERT(resumee->callstack_top >= 2);
+ act_resumee = resumee->callstack_curr; /* Duktape.Thread.yield() */
+ DUK_ASSERT(act_resumee != NULL);
+ act_resumee = act_resumee->parent; /* Ecmascript call site for yield() */
+ DUK_ASSERT(act_resumee != NULL);
- tv = resumee->valstack + resumee->callstack[act_idx].idx_retval; /* return value from Duktape.Thread.yield() */
+ tv = (duk_tval *) (void *) ((duk_uint8_t *) resumee->valstack + act_resumee->retval_byteoff); /* return value from Duktape.Thread.yield() */
DUK_ASSERT(tv >= resumee->valstack && tv < resumee->valstack_top);
tv2 = &thr->heap->lj.value1;
- DUK_TVAL_SET_TVAL_UPDREF(thr, tv, tv2); /* side effects */
-
- duk_hthread_callstack_unwind_norz(resumee, act_idx + 1); /* unwind to 'yield' caller */
+ DUK_TVAL_SET_TVAL_UPDREF(thr, tv, tv2); /* side effects */ /* XXX: avoid side effects */
- /* no need to unwind catchstack */
+ duk_hthread_activation_unwind_norz(resumee); /* unwind to 'yield' caller */
+ /* no need to unwind catch stack */
- duk__reconfig_valstack_ecma_return(resumee, act_idx);
+ duk__reconfig_valstack_ecma_return(resumee);
DUK_ASSERT(resumee->resumer == NULL);
resumee->resumer = thr;
@@ -71500,22 +73047,21 @@ duk_small_uint_t duk__handle_longjmp(duk_hthread *thr,
retval = DUK__LONGJMP_RESTART;
goto wipe_and_return;
} else {
+ /* Initial resume call. */
duk_small_uint_t call_flags;
- duk_bool_t setup_rc;
+ duk_int_t setup_rc;
/* resumee: [... initial_func] (currently actually: [initial_func]) */
- duk_push_undefined((duk_context *) resumee);
+ duk_push_undefined(resumee);
tv = &thr->heap->lj.value1;
- duk_push_tval((duk_context *) resumee, tv);
+ duk_push_tval(resumee, tv);
/* resumee: [... initial_func undefined(= this) resume_value ] */
- call_flags = DUK_CALL_FLAG_IS_RESUME; /* is resume, not a tail call */
+ call_flags = DUK_CALL_FLAG_ALLOW_ECMATOECMA; /* not tailcall, ecma-to-ecma (assumed to succeed) */
- setup_rc = duk_handle_ecma_call_setup(resumee,
- 1, /* num_stack_args */
- call_flags); /* call_flags */
+ setup_rc = duk_handle_call_unprotected_nargs(resumee, 1 /*nargs*/, call_flags);
if (setup_rc == 0) {
/* This shouldn't happen; Duktape.Thread.resume()
* should make sure of that. If it does happen
@@ -71557,16 +73103,18 @@ duk_small_uint_t duk__handle_longjmp(duk_hthread *thr,
/* duk_bi_duk_object_yield() and duk_bi_duk_object_resume() ensure all of these are met */
+#if 0 /* entry_thread not available for assert */
DUK_ASSERT(thr != entry_thread); /* Duktape.Thread.yield() should prevent */
+#endif
DUK_ASSERT(thr->state == DUK_HTHREAD_STATE_RUNNING); /* unchanged from Duktape.Thread.yield() */
DUK_ASSERT(thr->callstack_top >= 2); /* Ecmascript activation + Duktape.Thread.yield() activation */
DUK_ASSERT(thr->callstack_curr != NULL);
+ DUK_ASSERT(thr->callstack_curr->parent != NULL);
DUK_ASSERT(DUK_ACT_GET_FUNC(thr->callstack_curr) != NULL &&
DUK_HOBJECT_IS_NATFUNC(DUK_ACT_GET_FUNC(thr->callstack_curr)) &&
((duk_hnatfunc *) DUK_ACT_GET_FUNC(thr->callstack_curr))->func == duk_bi_thread_yield);
- DUK_ASSERT(DUK_ACT_GET_FUNC(thr->callstack_curr - 1) != NULL &&
- DUK_HOBJECT_IS_COMPFUNC(DUK_ACT_GET_FUNC(thr->callstack_curr - 1))); /* an Ecmascript function */
- DUK_ASSERT_DISABLE((thr->callstack_curr - 1)->idx_retval >= 0); /* unsigned */
+ DUK_ASSERT(DUK_ACT_GET_FUNC(thr->callstack_curr->parent) != NULL &&
+ DUK_HOBJECT_IS_COMPFUNC(DUK_ACT_GET_FUNC(thr->callstack_curr->parent))); /* an Ecmascript function */
resumer = thr->resumer;
@@ -71574,12 +73122,12 @@ duk_small_uint_t duk__handle_longjmp(duk_hthread *thr,
DUK_ASSERT(resumer->state == DUK_HTHREAD_STATE_RESUMED); /* written by a previous RESUME handling */
DUK_ASSERT(resumer->callstack_top >= 2); /* Ecmascript activation + Duktape.Thread.resume() activation */
DUK_ASSERT(resumer->callstack_curr != NULL);
+ DUK_ASSERT(resumer->callstack_curr->parent != NULL);
DUK_ASSERT(DUK_ACT_GET_FUNC(resumer->callstack_curr) != NULL &&
DUK_HOBJECT_IS_NATFUNC(DUK_ACT_GET_FUNC(resumer->callstack_curr)) &&
((duk_hnatfunc *) DUK_ACT_GET_FUNC(resumer->callstack_curr))->func == duk_bi_thread_resume);
- DUK_ASSERT(DUK_ACT_GET_FUNC(resumer->callstack_curr - 1) != NULL &&
- DUK_HOBJECT_IS_COMPFUNC(DUK_ACT_GET_FUNC(resumer->callstack_curr - 1))); /* an Ecmascript function */
- DUK_ASSERT_DISABLE((resumer->callstack_curr - 1)->idx_retval >= 0); /* unsigned */
+ DUK_ASSERT(DUK_ACT_GET_FUNC(resumer->callstack_curr->parent) != NULL &&
+ DUK_HOBJECT_IS_COMPFUNC(DUK_ACT_GET_FUNC(resumer->callstack_curr->parent))); /* an Ecmascript function */
if (thr->heap->lj.iserror) {
thr->state = DUK_HTHREAD_STATE_YIELDED;
@@ -71596,7 +73144,8 @@ 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, &thr->heap->lj.value1);
+ duk_hthread_activation_unwind_norz(resumer);
+ duk__handle_yield(thr, resumer, &thr->heap->lj.value1);
thr->state = DUK_HTHREAD_STATE_YIELDED;
thr->resumer = NULL;
@@ -71635,77 +73184,75 @@ duk_small_uint_t duk__handle_longjmp(duk_hthread *thr,
* Ecmascript activations.
*/
+ duk_activation *act;
duk_catcher *cat;
duk_hthread *resumer;
- cat = thr->catchstack + thr->catchstack_top - 1;
- while (cat >= thr->catchstack) {
- if (thr == entry_thread &&
- cat->callstack_index < entry_callstack_index) {
- /* entry level reached */
+ for (;;) {
+ act = thr->callstack_curr;
+ if (act == NULL) {
break;
}
- if (DUK_CAT_HAS_CATCH_ENABLED(cat)) {
- DUK_ASSERT(DUK_CAT_GET_TYPE(cat) == DUK_CAT_TYPE_TCF);
+ for (;;) {
+ cat = act->cat;
+ if (cat == NULL) {
+ break;
+ }
+
+ if (DUK_CAT_HAS_CATCH_ENABLED(cat)) {
+ DUK_ASSERT(DUK_CAT_GET_TYPE(cat) == DUK_CAT_TYPE_TCF);
- duk__handle_catch(thr,
- cat - thr->catchstack,
- &thr->heap->lj.value1,
- DUK_LJ_TYPE_THROW);
+ duk__handle_catch(thr,
+ &thr->heap->lj.value1,
+ DUK_LJ_TYPE_THROW);
- DUK_DD(DUK_DDPRINT("-> throw caught by a 'catch' clause, restart execution"));
- retval = DUK__LONGJMP_RESTART;
- goto wipe_and_return;
- }
+ DUK_DD(DUK_DDPRINT("-> throw caught by a 'catch' clause, restart execution"));
+ retval = DUK__LONGJMP_RESTART;
+ goto wipe_and_return;
+ }
- if (DUK_CAT_HAS_FINALLY_ENABLED(cat)) {
- DUK_ASSERT(DUK_CAT_GET_TYPE(cat) == DUK_CAT_TYPE_TCF);
- DUK_ASSERT(!DUK_CAT_HAS_CATCH_ENABLED(cat));
+ if (DUK_CAT_HAS_FINALLY_ENABLED(cat)) {
+ DUK_ASSERT(DUK_CAT_GET_TYPE(cat) == DUK_CAT_TYPE_TCF);
+ DUK_ASSERT(!DUK_CAT_HAS_CATCH_ENABLED(cat));
- duk__handle_finally(thr,
- cat - thr->catchstack,
- &thr->heap->lj.value1,
- DUK_LJ_TYPE_THROW);
+ duk__handle_finally(thr,
+ &thr->heap->lj.value1,
+ DUK_LJ_TYPE_THROW);
- DUK_DD(DUK_DDPRINT("-> throw caught by a 'finally' clause, restart execution"));
- retval = DUK__LONGJMP_RESTART;
- goto wipe_and_return;
+ DUK_DD(DUK_DDPRINT("-> throw caught by a 'finally' clause, restart execution"));
+ retval = DUK__LONGJMP_RESTART;
+ goto wipe_and_return;
+ }
+
+ duk_hthread_catcher_unwind_norz(thr, act);
}
- cat--;
- }
+ if (act == entry_act) {
+ /* Not caught by anything before entry level; rethrow and let the
+ * final catcher finish unwinding (esp. value stack).
+ */
+ DUK_D(DUK_DPRINT("-> throw propagated up to entry level, rethrow and exit bytecode executor"));
+ retval = DUK__LONGJMP_RETHROW;
+ goto just_return;
+ }
- if (thr == entry_thread) {
- /* not caught by anything before entry level; rethrow and let the
- * final catcher unwind everything
- */
-#if 0
- duk_hthread_catchstack_unwind_norz(thr, (cat - thr->catchstack) + 1); /* leave 'cat' as top catcher (also works if catchstack exhausted) */
- duk_hthread_callstack_unwind_norz(thr, entry_callstack_index + 1);
- DUK_REFZERO_CHECK_SLOW(thr);
-#endif
- DUK_D(DUK_DPRINT("-> throw propagated up to entry level, rethrow and exit bytecode executor"));
- retval = DUK__LONGJMP_RETHROW;
- goto just_return;
- /* Note: MUST NOT wipe_and_return here, as heap->lj must remain intact */
+ duk_hthread_activation_unwind_norz(thr);
}
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);
+ /* 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
- * exception etc (this is OK, but needs careful testing)
+ * exception etc (this is OK, but needs careful testing).
*/
DUK_ASSERT(thr->resumer != NULL);
DUK_ASSERT(thr->resumer->callstack_top >= 2); /* Ecmascript activation + Duktape.Thread.resume() activation */
DUK_ASSERT(thr->resumer->callstack_curr != NULL);
- DUK_ASSERT(DUK_ACT_GET_FUNC(thr->resumer->callstack_curr) != NULL &&
- DUK_HOBJECT_IS_NATFUNC(DUK_ACT_GET_FUNC(thr->resumer->callstack_curr)) &&
- ((duk_hnatfunc *) DUK_ACT_GET_FUNC(thr->resumer->callstack_curr))->func == duk_bi_thread_resume); /* Duktape.Thread.resume() */
- DUK_ASSERT(DUK_ACT_GET_FUNC(thr->resumer->callstack_curr - 1) != NULL &&
- DUK_HOBJECT_IS_COMPFUNC(DUK_ACT_GET_FUNC(thr->resumer->callstack_curr - 1))); /* an Ecmascript function */
+ DUK_ASSERT(thr->resumer->callstack_curr->parent != NULL);
+ DUK_ASSERT(DUK_ACT_GET_FUNC(thr->resumer->callstack_curr->parent) != NULL &&
+ DUK_HOBJECT_IS_COMPFUNC(DUK_ACT_GET_FUNC(thr->resumer->callstack_curr->parent))); /* an Ecmascript function */
resumer = thr->resumer;
@@ -71766,70 +73313,61 @@ duk_small_uint_t duk__handle_longjmp(duk_hthread *thr,
* handling because it has a measurable performance impact in ordinary
* environments and an extreme impact in Emscripten (GH-342).
*/
-DUK_LOCAL void duk__handle_break_or_continue(duk_hthread *thr,
- duk_uint_t label_id,
- duk_small_uint_t lj_type) {
+DUK_LOCAL DUK__NOINLINE_PERF void duk__handle_break_or_continue(duk_hthread *thr,
+ duk_uint_t label_id,
+ duk_small_uint_t lj_type) {
+ duk_activation *act;
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.
+ /* Find a matching label catcher or 'finally' catcher in
+ * the same function, unwinding catchers as we go.
*
- * 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.
+ * 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));
+ act = thr->callstack_curr;
+ DUK_ASSERT(act != NULL);
- while (cat >= thr->catchstack) {
- if (cat->callstack_index != orig_callstack_index) {
+ for (;;) {
+ cat = act->cat;
+ if (cat == NULL) {
break;
}
- DUK_DDD(DUK_DDDPRINT("considering catcher %ld: type=%ld label=%ld",
- (long) (cat - thr->catchstack),
+
+ DUK_DDD(DUK_DDDPRINT("considering catcher %p: type=%ld label=%ld",
+ (void *) cat,
(long) DUK_CAT_GET_TYPE(cat),
(long) DUK_CAT_GET_LABEL(cat)));
+ /* XXX: bit mask test; FINALLY <-> TCF, single bit mask would suffice? */
+
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 */
-
DUK_TVAL_SET_U32(&tv_tmp, (duk_uint32_t) label_id);
- duk__handle_finally(thr, cat_idx, &tv_tmp, lj_type);
+ duk__handle_finally(thr, &tv_tmp, lj_type);
DUK_DD(DUK_DDPRINT("-> break/continue caught by 'finally', restart execution"));
return;
}
if (DUK_CAT_GET_TYPE(cat) == DUK_CAT_TYPE_LABEL &&
(duk_uint_t) DUK_CAT_GET_LABEL(cat) == label_id) {
- duk_size_t cat_idx;
-
- cat_idx = (duk_size_t) (cat - thr->catchstack);
- duk__handle_label(thr, cat_idx, lj_type);
+ duk__handle_label(thr, lj_type);
DUK_DD(DUK_DDPRINT("-> break/continue caught by a label catcher (in the same function), restart execution"));
return;
}
- cat--;
+
+ duk_hthread_catcher_unwind_norz(thr, act);
}
- /* should never happen, but be robust */
+ /* Should never happen, but be robust. */
DUK_D(DUK_DPRINT("-> break/continue not caught by anything in the current function (should never happen), throw internal error"));
DUK_ERROR_INTERNAL(thr);
return;
@@ -71839,22 +73377,19 @@ DUK_LOCAL void duk__handle_break_or_continue(duk_hthread *thr,
* it has a measurable performance impact in ordinary environments and an extreme
* impact in Emscripten (GH-342). Return value is on value stack top.
*/
-DUK_LOCAL duk_small_uint_t duk__handle_return(duk_hthread *thr,
- duk_hthread *entry_thread,
- duk_size_t entry_callstack_top) {
+DUK_LOCAL duk_small_uint_t duk__handle_return(duk_hthread *thr, duk_activation *entry_act) {
duk_tval *tv1;
duk_tval *tv2;
#if defined(DUK_USE_COROUTINE_SUPPORT)
duk_hthread *resumer;
#endif
+ duk_activation *act;
duk_catcher *cat;
- duk_size_t new_cat_top;
- duk_size_t orig_callstack_index;
/* We can directly access value stack here. */
DUK_ASSERT(thr != NULL);
- DUK_ASSERT(entry_thread != NULL);
+ DUK_ASSERT(entry_act != NULL);
DUK_ASSERT(thr->valstack_top - 1 >= thr->valstack_bottom);
tv1 = thr->valstack_top - 1;
DUK_TVAL_CHKFAST_INPLACE_FAST(tv1); /* fastint downgrade check for return values */
@@ -71882,78 +73417,69 @@ DUK_LOCAL duk_small_uint_t duk__handle_return(duk_hthread *thr,
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 */
- DUK_ASSERT(thr->callstack_curr != NULL);
- orig_callstack_index = thr->callstack_top - 1;
+ act = thr->callstack_curr;
+ DUK_ASSERT(act != NULL);
- while (cat >= thr->catchstack) {
- if (cat->callstack_index != orig_callstack_index) {
+ for (;;) {
+ cat = act->cat;
+ if (cat == NULL) {
break;
}
+
if (DUK_CAT_GET_TYPE(cat) == DUK_CAT_TYPE_TCF &&
DUK_CAT_HAS_FINALLY_ENABLED(cat)) {
- duk_size_t cat_idx;
-
- cat_idx = (duk_size_t) (cat - thr->catchstack); /* get before side effects */
-
DUK_ASSERT(thr->valstack_top - 1 >= thr->valstack_bottom);
- duk__handle_finally(thr, cat_idx, thr->valstack_top - 1, DUK_LJ_TYPE_RETURN);
+ duk__handle_finally(thr, thr->valstack_top - 1, DUK_LJ_TYPE_RETURN);
DUK_DD(DUK_DDPRINT("-> return caught by 'finally', restart execution"));
return DUK__RETHAND_RESTART;
}
- cat--;
- }
- /* If out of catchstack, cat = thr->catchstack - 1;
- * new_cat_top will be 0 in that case.
- */
- new_cat_top = (duk_size_t) ((cat + 1) - thr->catchstack);
- cat = NULL; /* avoid referencing, invalidated */
- DUK_DDD(DUK_DDDPRINT("no catcher in catch stack, return to calling activation / yield"));
+ duk_hthread_catcher_unwind_norz(thr, act);
+ }
- if (thr == entry_thread &&
- thr->callstack_top == entry_callstack_top) {
- /* Return to the bytecode executor caller which will unwind stacks.
+ if (act == entry_act) {
+ /* Return to the bytecode executor caller who will unwind stacks
+ * and handle constructor post-processing.
* Return value is already on the stack top: [ ... retval ].
*/
- /* XXX: could unwind catchstack here, so that call handling
- * didn't need to do that?
- */
DUK_DDD(DUK_DDDPRINT("-> return propagated up to entry level, exit bytecode executor"));
return DUK__RETHAND_FINISHED;
}
if (thr->callstack_top >= 2) {
/* There is a caller; it MUST be an Ecmascript caller (otherwise it would
- * match entry level check)
+ * match entry_act check).
*/
-
- DUK_DDD(DUK_DDDPRINT("return to Ecmascript caller, idx_retval=%ld, lj_value1=%!T",
- (long) (thr->callstack_curr - 1)->idx_retval,
+ DUK_DDD(DUK_DDDPRINT("return to Ecmascript caller, retval_byteoff=%ld, lj_value1=%!T",
+ (long) (thr->callstack_curr->parent->retval_byteoff),
(duk_tval *) &thr->heap->lj.value1));
- DUK_ASSERT(DUK_HOBJECT_IS_COMPFUNC(DUK_ACT_GET_FUNC(thr->callstack_curr - 1))); /* must be ecmascript */
+ DUK_ASSERT(thr->callstack_curr != NULL);
+ DUK_ASSERT(thr->callstack_curr->parent != NULL);
+ DUK_ASSERT(DUK_HOBJECT_IS_COMPFUNC(DUK_ACT_GET_FUNC(thr->callstack_curr->parent))); /* must be ecmascript */
- tv1 = thr->valstack + (thr->callstack_curr - 1)->idx_retval;
+#if defined(DUK_USE_ES6_PROXY)
+ if (thr->callstack_curr->flags & (DUK_ACT_FLAG_CONSTRUCT | DUK_ACT_FLAG_CONSTRUCT_PROXY)) {
+ duk_call_construct_postprocess(thr, thr->callstack_curr->flags & DUK_ACT_FLAG_CONSTRUCT_PROXY); /* side effects */
+ }
+#else
+ if (thr->callstack_curr->flags & DUK_ACT_FLAG_CONSTRUCT) {
+ duk_call_construct_postprocess(thr, 0); /* side effects */
+ }
+#endif
+
+ tv1 = (duk_tval *) (void *) ((duk_uint8_t *) thr->valstack + thr->callstack_curr->parent->retval_byteoff);
DUK_ASSERT(thr->valstack_top - 1 >= thr->valstack_bottom);
tv2 = thr->valstack_top - 1;
DUK_TVAL_SET_TVAL_UPDREF(thr, tv1, tv2); /* side effects */
- DUK_DDD(DUK_DDDPRINT("return value at idx_retval=%ld is %!T",
- (long) (thr->callstack_curr - 1)->idx_retval,
- (duk_tval *) (thr->valstack + (thr->callstack_curr - 1)->idx_retval)));
+ /* Catch stack unwind happens inline in callstack unwind. */
+ duk_hthread_activation_unwind_norz(thr);
- duk_hthread_catchstack_unwind_norz(thr, new_cat_top); /* leave 'cat' as top catcher (also works if catchstack exhausted) */
- duk_hthread_callstack_unwind_norz(thr, thr->callstack_top - 1);
- duk__reconfig_valstack_ecma_return(thr, thr->callstack_top - 1);
+ duk__reconfig_valstack_ecma_return(thr);
DUK_DD(DUK_DDPRINT("-> return not intercepted, restart execution in caller"));
return DUK__RETHAND_RESTART;
@@ -71965,12 +73491,12 @@ DUK_LOCAL duk_small_uint_t duk__handle_return(duk_hthread *thr,
DUK_ASSERT(thr->resumer != NULL);
DUK_ASSERT(thr->resumer->callstack_top >= 2); /* Ecmascript activation + Duktape.Thread.resume() activation */
DUK_ASSERT(thr->resumer->callstack_curr != NULL);
+ DUK_ASSERT(thr->resumer->callstack_curr->parent != NULL);
DUK_ASSERT(DUK_ACT_GET_FUNC(thr->resumer->callstack_curr) != NULL &&
- DUK_HOBJECT_IS_NATFUNC(DUK_ACT_GET_FUNC(thr->resumer->callstack_curr)) &&
- ((duk_hnatfunc *) DUK_ACT_GET_FUNC(thr->resumer->callstack_curr))->func == duk_bi_thread_resume); /* Duktape.Thread.resume() */
- DUK_ASSERT(DUK_ACT_GET_FUNC(thr->resumer->callstack_curr - 1) != NULL &&
- DUK_HOBJECT_IS_COMPFUNC(DUK_ACT_GET_FUNC(thr->resumer->callstack_curr - 1))); /* an Ecmascript function */
- DUK_ASSERT_DISABLE((thr->resumer->callstack_curr - 1)->idx_retval >= 0); /* unsigned */
+ DUK_HOBJECT_IS_NATFUNC(DUK_ACT_GET_FUNC(thr->resumer->callstack_curr)) &&
+ ((duk_hnatfunc *) DUK_ACT_GET_FUNC(thr->resumer->callstack_curr))->func == duk_bi_thread_resume); /* Duktape.Thread.resume() */
+ DUK_ASSERT(DUK_ACT_GET_FUNC(thr->resumer->callstack_curr->parent) != NULL &&
+ DUK_HOBJECT_IS_COMPFUNC(DUK_ACT_GET_FUNC(thr->resumer->callstack_curr->parent))); /* an Ecmascript function */
DUK_ASSERT(thr->state == DUK_HTHREAD_STATE_RUNNING);
DUK_ASSERT(thr->resumer->state == DUK_HTHREAD_STATE_RESUMED);
@@ -71978,7 +73504,8 @@ DUK_LOCAL duk_small_uint_t duk__handle_return(duk_hthread *thr,
/* Share yield longjmp handler. */
DUK_ASSERT(thr->valstack_top - 1 >= thr->valstack_bottom);
- duk__handle_yield(thr, resumer, resumer->callstack_top - 2, thr->valstack_top - 1);
+ duk_hthread_activation_unwind_norz(resumer);
+ duk__handle_yield(thr, resumer, thr->valstack_top - 1);
duk_hthread_terminate(thr); /* updates thread state, minimizes its allocations */
DUK_ASSERT(thr->state == DUK_HTHREAD_STATE_TERMINATED);
@@ -72032,7 +73559,6 @@ DUK_LOCAL duk_small_uint_t duk__handle_return(duk_hthread *thr,
#if defined(DUK_USE_DEBUGGER_SUPPORT)
DUK_LOCAL void duk__interrupt_handle_debugger(duk_hthread *thr, duk_bool_t *out_immediate, duk_small_uint_t *out_interrupt_retval) {
- duk_context *ctx;
duk_activation *act;
duk_breakpoint *bp;
duk_breakpoint **bp_active;
@@ -72042,7 +73568,6 @@ DUK_LOCAL void duk__interrupt_handle_debugger(duk_hthread *thr, duk_bool_t *out_
DUK_ASSERT(thr->heap->dbg_processing == 0); /* don't re-enter e.g. during Eval */
- ctx = (duk_context *) thr;
act = thr->callstack_curr;
DUK_ASSERT(act != NULL);
@@ -72052,22 +73577,28 @@ DUK_LOCAL void duk__interrupt_handle_debugger(duk_hthread *thr, duk_bool_t *out_
*/
/*
+ * Single opcode step check
+ */
+
+ if (thr->heap->dbg_pause_flags & DUK_PAUSE_FLAG_ONE_OPCODE_ACTIVE) {
+ DUK_D(DUK_DPRINT("PAUSE TRIGGERED by one opcode step"));
+ duk_debug_set_paused(thr->heap);
+ }
+
+ /*
* Breakpoint and step state checks
*/
if (act->flags & DUK_ACT_FLAG_BREAKPOINT_ACTIVE ||
- (thr->heap->dbg_step_thread == thr &&
- thr->heap->dbg_step_csindex == thr->callstack_top - 1)) {
+ (thr->heap->dbg_pause_act == thr->callstack_curr)) {
line = duk_debug_curr_line(thr);
if (act->prev_line != line) {
/* Stepped? Step out is handled by callstack unwind. */
- if ((thr->heap->dbg_step_type == DUK_STEP_TYPE_INTO ||
- thr->heap->dbg_step_type == DUK_STEP_TYPE_OVER) &&
- (thr->heap->dbg_step_thread == thr) &&
- (thr->heap->dbg_step_csindex == thr->callstack_top - 1) &&
- (line != thr->heap->dbg_step_startline)) {
- DUK_D(DUK_DPRINT("STEP STATE TRIGGERED PAUSE at line %ld",
+ if ((thr->heap->dbg_pause_flags & DUK_PAUSE_FLAG_LINE_CHANGE) &&
+ (thr->heap->dbg_pause_act == thr->callstack_curr) &&
+ (line != thr->heap->dbg_pause_startline)) {
+ DUK_D(DUK_DPRINT("PAUSE TRIGGERED by line change, at line %ld",
(long) line));
duk_debug_set_paused(thr->heap);
}
@@ -72093,7 +73624,7 @@ DUK_LOCAL void duk__interrupt_handle_debugger(duk_hthread *thr, duk_bool_t *out_
DUK_ASSERT(bp->filename != NULL);
if (act->prev_line != bp->line && line == bp->line) {
- DUK_D(DUK_DPRINT("BREAKPOINT TRIGGERED at %!O:%ld",
+ DUK_D(DUK_DPRINT("PAUSE TRIGGERED by breakpoint at %!O:%ld",
(duk_heaphdr *) bp->filename, (long) bp->line));
duk_debug_set_paused(thr->heap);
}
@@ -72102,7 +73633,7 @@ DUK_LOCAL void duk__interrupt_handle_debugger(duk_hthread *thr, duk_bool_t *out_
;
}
- act->prev_line = line;
+ act->prev_line = (duk_uint32_t) line;
}
/*
@@ -72126,7 +73657,8 @@ DUK_LOCAL void duk__interrupt_handle_debugger(duk_hthread *thr, duk_bool_t *out_
}
/* XXX: remove heap->dbg_exec_counter, use heap->inst_count_interrupt instead? */
- thr->heap->dbg_exec_counter += thr->interrupt_init;
+ DUK_ASSERT(thr->interrupt_init >= 0);
+ thr->heap->dbg_exec_counter += (duk_uint_t) thr->interrupt_init;
if (thr->heap->dbg_exec_counter - thr->heap->dbg_last_counter >= DUK_HEAP_DBG_RATELIMIT_OPCODES) {
/* Overflow of the execution counter is fine and doesn't break
* anything here.
@@ -72135,12 +73667,14 @@ DUK_LOCAL void duk__interrupt_handle_debugger(duk_hthread *thr, duk_bool_t *out_
duk_double_t now, diff_last;
thr->heap->dbg_last_counter = thr->heap->dbg_exec_counter;
- now = DUK_USE_DATE_GET_NOW(ctx);
+ now = duk_time_get_monotonic_time(thr);
diff_last = now - thr->heap->dbg_last_time;
if (diff_last < 0.0 || diff_last >= (duk_double_t) DUK_HEAP_DBG_RATELIMIT_MILLISECS) {
- /* Negative value checked so that a "time jump" works
- * reasonably.
+ /* Monotonic time should not experience time jumps,
+ * but the provider may be missing and we're actually
+ * using Ecmascript time. So, tolerate negative values
+ * so that a time jump works reasonably.
*
* Same interval is now used for status sending and
* peeking.
@@ -72167,7 +73701,6 @@ DUK_LOCAL void duk__interrupt_handle_debugger(duk_hthread *thr, duk_bool_t *out_
* detaching.
*/
- act = NULL; /* may be changed */
if (process_messages) {
DUK_ASSERT(thr->heap->dbg_processing == 0);
processed_messages = duk_debug_process_messages(thr, 0 /*no_block*/);
@@ -72183,13 +73716,12 @@ DUK_LOCAL void duk__interrupt_handle_debugger(duk_hthread *thr, duk_bool_t *out_
*/
if (duk_debug_is_attached(thr->heap)) {
- act = thr->callstack_curr; /* relookup, may have changed */
+ DUK_ASSERT(act == thr->callstack_curr);
DUK_ASSERT(act != NULL);
if (act->flags & DUK_ACT_FLAG_BREAKPOINT_ACTIVE ||
- ((thr->heap->dbg_step_type == DUK_STEP_TYPE_INTO ||
- thr->heap->dbg_step_type == DUK_STEP_TYPE_OVER) &&
- thr->heap->dbg_step_thread == thr &&
- thr->heap->dbg_step_csindex == thr->callstack_top - 1) ||
+ (thr->heap->dbg_pause_flags & DUK_PAUSE_FLAG_ONE_OPCODE) ||
+ ((thr->heap->dbg_pause_flags & DUK_PAUSE_FLAG_LINE_CHANGE) &&
+ thr->heap->dbg_pause_act == thr->callstack_curr) ||
DUK_HEAP_HAS_DEBUGGER_PAUSED(thr->heap)) {
*out_immediate = 1;
}
@@ -72200,6 +73732,13 @@ DUK_LOCAL void duk__interrupt_handle_debugger(duk_hthread *thr, duk_bool_t *out_
if (processed_messages) {
DUK_D(DUK_DPRINT("processed debug messages, restart execution to recheck possibly changed breakpoints"));
*out_interrupt_retval = DUK__INT_RESTART;
+ } else {
+ if (thr->heap->dbg_pause_flags & DUK_PAUSE_FLAG_ONE_OPCODE) {
+ /* Set 'pause after one opcode' active only when we're
+ * actually just about to execute code.
+ */
+ thr->heap->dbg_pause_flags |= DUK_PAUSE_FLAG_ONE_OPCODE_ACTIVE;
+ }
}
} else {
DUK_D(DUK_DPRINT("debugger became detached, resume normal execution"));
@@ -72207,7 +73746,7 @@ DUK_LOCAL void duk__interrupt_handle_debugger(duk_hthread *thr, duk_bool_t *out_
}
#endif /* DUK_USE_DEBUGGER_SUPPORT */
-DUK_LOCAL DUK_NOINLINE DUK_COLD duk_small_uint_t duk__executor_interrupt(duk_hthread *thr) {
+DUK_LOCAL DUK__NOINLINE_PERF DUK_COLD duk_small_uint_t duk__executor_interrupt(duk_hthread *thr) {
duk_int_t ctr;
duk_activation *act;
duk_hcompfunc *fun;
@@ -72216,7 +73755,6 @@ DUK_LOCAL DUK_NOINLINE DUK_COLD duk_small_uint_t duk__executor_interrupt(duk_hth
DUK_ASSERT(thr != NULL);
DUK_ASSERT(thr->heap != NULL);
- DUK_ASSERT(thr->callstack != NULL);
DUK_ASSERT(thr->callstack_top > 0);
#if defined(DUK_USE_DEBUG)
@@ -72294,8 +73832,7 @@ DUK_LOCAL DUK_NOINLINE DUK_COLD duk_small_uint_t duk__executor_interrupt(duk_hth
* detaching (to finish off the pending detach).
*/
duk__interrupt_handle_debugger(thr, &immediate, &retval);
- act = thr->callstack_curr; /* relookup if changed */
- DUK_UNREF(act); /* 'act' is no longer accessed, scanbuild fix */
+ DUK_ASSERT(act == thr->callstack_curr);
}
#endif /* DUK_USE_DEBUGGER_SUPPORT */
@@ -72431,21 +73968,19 @@ DUK_LOCAL void duk__executor_recheck_debugger(duk_hthread *thr, duk_activation *
DUK_DD(DUK_DDPRINT("ACTIVE BREAKPOINTS: %ld", (long) (bp_active - thr->heap->dbg_breakpoints_active)));
/* Force pause if we were doing "step into" in another activation. */
- if (thr->heap->dbg_step_thread != NULL &&
- thr->heap->dbg_step_type == DUK_STEP_TYPE_INTO &&
- (thr->heap->dbg_step_thread != thr ||
- thr->heap->dbg_step_csindex != thr->callstack_top - 1)) {
- DUK_D(DUK_DPRINT("STEP INTO ACTIVE, FORCE PAUSED"));
+ if ((thr->heap->dbg_pause_flags & DUK_PAUSE_FLAG_FUNC_ENTRY) &&
+ thr->heap->dbg_pause_act != thr->callstack_curr) {
+ DUK_D(DUK_DPRINT("PAUSE TRIGGERED by function entry"));
duk_debug_set_paused(thr->heap);
}
/* Force interrupt right away if we're paused or in "checked mode".
* Step out is handled by callstack unwind.
*/
- if (act->flags & (DUK_ACT_FLAG_BREAKPOINT_ACTIVE) ||
+ if ((act->flags & DUK_ACT_FLAG_BREAKPOINT_ACTIVE) ||
DUK_HEAP_HAS_DEBUGGER_PAUSED(thr->heap) ||
- (thr->heap->dbg_step_type != DUK_STEP_TYPE_OUT &&
- thr->heap->dbg_step_csindex == thr->callstack_top - 1)) {
+ ((thr->heap->dbg_pause_flags & DUK_PAUSE_FLAG_LINE_CHANGE) &&
+ thr->heap->dbg_pause_act == thr->callstack_curr)) {
/* We'll need to interrupt early so recompute the init
* counter to reflect the number of bytecode instructions
* executed so that step counts for e.g. debugger rate
@@ -72459,6 +73994,519 @@ DUK_LOCAL void duk__executor_recheck_debugger(duk_hthread *thr, duk_activation *
#endif /* DUK_USE_DEBUGGER_SUPPORT */
/*
+ * Opcode handlers for opcodes with a lot of code and which are relatively
+ * rare; NOINLINE to reduce amount of code in main bytecode dispatcher.
+ */
+
+DUK_LOCAL DUK__NOINLINE_PERF void duk__handle_op_initset_initget(duk_hthread *thr, duk_uint_fast32_t ins) {
+ duk_bool_t is_set = (DUK_DEC_OP(ins) == DUK_OP_INITSET);
+ duk_uint_fast_t idx;
+ duk_uint_t defprop_flags;
+
+ /* A -> object register (acts as a source)
+ * BC -> BC+0 contains key, BC+1 closure (value)
+ */
+
+ /* INITSET/INITGET are only used to initialize object literal keys.
+ * There may be a previous propery in ES2015 because duplicate property
+ * names are allowed.
+ */
+
+ /* This could be made more optimal by accessing internals directly. */
+
+ idx = (duk_uint_fast_t) DUK_DEC_BC(ins);
+ duk_dup(thr, (duk_idx_t) (idx + 0)); /* key */
+ duk_dup(thr, (duk_idx_t) (idx + 1)); /* getter/setter */
+ if (is_set) {
+ defprop_flags = DUK_DEFPROP_HAVE_SETTER |
+ DUK_DEFPROP_FORCE |
+ DUK_DEFPROP_SET_ENUMERABLE |
+ DUK_DEFPROP_SET_CONFIGURABLE;
+ } else {
+ defprop_flags = DUK_DEFPROP_HAVE_GETTER |
+ DUK_DEFPROP_FORCE |
+ DUK_DEFPROP_SET_ENUMERABLE |
+ DUK_DEFPROP_SET_CONFIGURABLE;
+ }
+ duk_def_prop(thr, (duk_idx_t) DUK_DEC_A(ins), defprop_flags);
+}
+
+DUK_LOCAL DUK__NOINLINE_PERF void duk__handle_op_trycatch(duk_hthread *thr, duk_uint_fast32_t ins, duk_instr_t *curr_pc) {
+ duk_activation *act;
+ duk_catcher *cat;
+ duk_tval *tv1;
+ duk_small_uint_fast_t a;
+ duk_small_uint_fast_t bc;
+
+ /* A -> flags
+ * BC -> reg_catch; base register for two registers used both during
+ * trycatch setup and when catch is triggered
+ *
+ * If DUK_BC_TRYCATCH_FLAG_CATCH_BINDING set:
+ * reg_catch + 0: catch binding variable name (string).
+ * Automatic declarative environment is established for
+ * the duration of the 'catch' clause.
+ *
+ * If DUK_BC_TRYCATCH_FLAG_WITH_BINDING set:
+ * reg_catch + 0: with 'target value', which is coerced to
+ * an object and then used as a bindind object for an
+ * environment record. The binding is initialized here, for
+ * the 'try' clause.
+ *
+ * Note that a TRYCATCH generated for a 'with' statement has no
+ * catch or finally parts.
+ */
+
+ /* XXX: TRYCATCH handling should be reworked to avoid creating
+ * an explicit scope unless it is actually needed (e.g. function
+ * instances or eval is executed inside the catch block). This
+ * rework is not trivial because the compiler doesn't have an
+ * intermediate representation. When the rework is done, the
+ * opcode format can also be made more straightforward.
+ */
+
+ /* XXX: side effect handling is quite awkward here */
+
+ DUK_DDD(DUK_DDDPRINT("TRYCATCH: reg_catch=%ld, have_catch=%ld, "
+ "have_finally=%ld, catch_binding=%ld, with_binding=%ld (flags=0x%02lx)",
+ (long) DUK_DEC_BC(ins),
+ (long) (DUK_DEC_A(ins) & DUK_BC_TRYCATCH_FLAG_HAVE_CATCH ? 1 : 0),
+ (long) (DUK_DEC_A(ins) & DUK_BC_TRYCATCH_FLAG_HAVE_FINALLY ? 1 : 0),
+ (long) (DUK_DEC_A(ins) & DUK_BC_TRYCATCH_FLAG_CATCH_BINDING ? 1 : 0),
+ (long) (DUK_DEC_A(ins) & DUK_BC_TRYCATCH_FLAG_WITH_BINDING ? 1 : 0),
+ (unsigned long) DUK_DEC_A(ins)));
+
+ a = DUK_DEC_A(ins);
+ bc = DUK_DEC_BC(ins);
+
+ /* Registers 'bc' and 'bc + 1' are written in longjmp handling
+ * and if their previous values (which are temporaries) become
+ * unreachable -and- have a finalizer, there'll be a function
+ * call during error handling which is not supported now (GH-287).
+ * Ensure that both 'bc' and 'bc + 1' have primitive values to
+ * guarantee no finalizer calls in error handling. Scrubbing also
+ * ensures finalizers for the previous values run here rather than
+ * later. Error handling related values are also written to 'bc'
+ * and 'bc + 1' but those values never become unreachable during
+ * error handling, so there's no side effect problem even if the
+ * error value has a finalizer.
+ */
+ duk_dup(thr, (duk_idx_t) bc); /* Stabilize value. */
+ duk_to_undefined(thr, (duk_idx_t) bc);
+ duk_to_undefined(thr, (duk_idx_t) (bc + 1));
+
+ /* Allocate catcher and populate it. Doesn't have to
+ * be fully atomic, but the catcher must be in a
+ * consistent state if side effects (such as finalizer
+ * calls) occur.
+ */
+
+ cat = duk_hthread_catcher_alloc(thr);
+ DUK_ASSERT(cat != NULL);
+
+ cat->flags = DUK_CAT_TYPE_TCF;
+ cat->h_varname = NULL;
+ cat->pc_base = (duk_instr_t *) curr_pc; /* pre-incremented, points to first jump slot */
+ cat->idx_base = (duk_size_t) (thr->valstack_bottom - thr->valstack) + bc;
+
+ act = thr->callstack_curr;
+ DUK_ASSERT(act != NULL);
+ cat->parent = act->cat;
+ act->cat = cat;
+
+ if (a & DUK_BC_TRYCATCH_FLAG_HAVE_CATCH) {
+ cat->flags |= DUK_CAT_FLAG_CATCH_ENABLED;
+ }
+ if (a & DUK_BC_TRYCATCH_FLAG_HAVE_FINALLY) {
+ cat->flags |= DUK_CAT_FLAG_FINALLY_ENABLED;
+ }
+ if (a & DUK_BC_TRYCATCH_FLAG_CATCH_BINDING) {
+ DUK_DDD(DUK_DDDPRINT("catch binding flag set to catcher"));
+ cat->flags |= DUK_CAT_FLAG_CATCH_BINDING_ENABLED;
+ tv1 = DUK_GET_TVAL_NEGIDX(thr, -1);
+ DUK_ASSERT(DUK_TVAL_IS_STRING(tv1));
+
+ /* borrowed reference; although 'tv1' comes from a register,
+ * its value was loaded using LDCONST so the constant will
+ * also exist and be reachable.
+ */
+ cat->h_varname = DUK_TVAL_GET_STRING(tv1);
+ } else if (a & DUK_BC_TRYCATCH_FLAG_WITH_BINDING) {
+ duk_hobjenv *env;
+ duk_hobject *target;
+
+ /* Delayed env initialization for activation (if needed). */
+ DUK_ASSERT(thr->callstack_top >= 1);
+ DUK_ASSERT(act == thr->callstack_curr);
+ DUK_ASSERT(act != NULL);
+ if (act->lex_env == NULL) {
+ DUK_DDD(DUK_DDDPRINT("delayed environment initialization"));
+ DUK_ASSERT(act->var_env == NULL);
+
+ duk_js_init_activation_environment_records_delayed(thr, act);
+ DUK_ASSERT(act == thr->callstack_curr);
+ DUK_UNREF(act); /* 'act' is no longer accessed, scanbuild fix */
+ }
+ DUK_ASSERT(act->lex_env != NULL);
+ DUK_ASSERT(act->var_env != NULL);
+
+ /* Coerce 'with' target. */
+ target = duk_to_hobject(thr, -1);
+ DUK_ASSERT(target != NULL);
+
+ /* Create an object environment; it is not pushed
+ * so avoid side effects very carefully until it is
+ * referenced.
+ */
+ env = duk_hobjenv_alloc(thr,
+ DUK_HOBJECT_FLAG_EXTENSIBLE |
+ DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_OBJENV));
+ DUK_ASSERT(env != NULL);
+ DUK_ASSERT(DUK_HOBJECT_GET_PROTOTYPE(thr->heap, (duk_hobject *) env) == NULL);
+ env->target = target; /* always provideThis=true */
+ DUK_HOBJECT_INCREF(thr, target);
+ env->has_this = 1;
+ DUK_ASSERT_HOBJENV_VALID(env);
+ DUK_DDD(DUK_DDDPRINT("environment for with binding: %!iO", env));
+
+ DUK_ASSERT(act == thr->callstack_curr);
+ DUK_ASSERT(DUK_HOBJECT_GET_PROTOTYPE(thr->heap, (duk_hobject *) env) == NULL);
+ DUK_ASSERT(act->lex_env != NULL);
+ DUK_HOBJECT_SET_PROTOTYPE(thr->heap, (duk_hobject *) env, act->lex_env);
+ act->lex_env = (duk_hobject *) env; /* Now reachable. */
+ DUK_HOBJECT_INCREF(thr, (duk_hobject *) env);
+ /* Net refcount change to act->lex_env is 0: incref for env's
+ * prototype, decref for act->lex_env overwrite.
+ */
+
+ /* Set catcher lex_env active (affects unwind)
+ * only when the whole setup is complete.
+ */
+ cat = act->cat; /* XXX: better to relookup? not mandatory because 'cat' is stable */
+ cat->flags |= DUK_CAT_FLAG_LEXENV_ACTIVE;
+ } else {
+ ;
+ }
+
+ DUK_DDD(DUK_DDDPRINT("TRYCATCH catcher: flags=0x%08lx, pc_base=%ld, "
+ "idx_base=%ld, h_varname=%!O",
+ (unsigned long) cat->flags,
+ (long) cat->pc_base, (long) cat->idx_base, (duk_heaphdr *) cat->h_varname));
+
+ duk_pop_unsafe(thr);
+}
+
+DUK_LOCAL DUK__NOINLINE_PERF duk_instr_t *duk__handle_op_endtry(duk_hthread *thr, duk_uint_fast32_t ins) {
+ duk_activation *act;
+ duk_catcher *cat;
+ duk_tval *tv1;
+ duk_instr_t *pc_base;
+
+ DUK_UNREF(ins);
+
+ DUK_ASSERT(thr->callstack_top >= 1);
+ act = thr->callstack_curr;
+ DUK_ASSERT(act != NULL);
+ cat = act->cat;
+ DUK_ASSERT(cat != NULL);
+ DUK_ASSERT(DUK_CAT_GET_TYPE(act->cat) == DUK_CAT_TYPE_TCF);
+
+ DUK_DDD(DUK_DDDPRINT("ENDTRY: clearing catch active flag (regardless of whether it was set or not)"));
+ DUK_CAT_CLEAR_CATCH_ENABLED(cat);
+
+ pc_base = cat->pc_base;
+
+ if (DUK_CAT_HAS_FINALLY_ENABLED(cat)) {
+ DUK_DDD(DUK_DDDPRINT("ENDTRY: finally part is active, jump through 2nd jump slot with 'normal continuation'"));
+
+ tv1 = thr->valstack + cat->idx_base;
+ DUK_ASSERT(tv1 >= thr->valstack && tv1 < thr->valstack_top);
+ DUK_TVAL_SET_UNDEFINED_UPDREF(thr, tv1); /* side effects */
+ tv1 = NULL;
+
+ tv1 = thr->valstack + cat->idx_base + 1;
+ DUK_ASSERT(tv1 >= thr->valstack && tv1 < thr->valstack_top);
+ DUK_TVAL_SET_U32_UPDREF(thr, tv1, (duk_uint32_t) DUK_LJ_TYPE_NORMAL); /* side effects */
+ tv1 = NULL;
+
+ DUK_CAT_CLEAR_FINALLY_ENABLED(cat);
+ } else {
+ DUK_DDD(DUK_DDDPRINT("ENDTRY: no finally part, dismantle catcher, jump through 2nd jump slot (to end of statement)"));
+
+ duk_hthread_catcher_unwind_norz(thr, act); /* lexenv may be set for 'with' binding */
+ /* no need to unwind callstack */
+ }
+
+ return pc_base + 1; /* new curr_pc value */
+}
+
+DUK_LOCAL DUK__NOINLINE_PERF duk_instr_t *duk__handle_op_endcatch(duk_hthread *thr, duk_uint_fast32_t ins) {
+ duk_activation *act;
+ duk_catcher *cat;
+ duk_tval *tv1;
+ duk_instr_t *pc_base;
+
+ DUK_UNREF(ins);
+
+ DUK_ASSERT(thr->callstack_top >= 1);
+ act = thr->callstack_curr;
+ DUK_ASSERT(act != NULL);
+ cat = act->cat;
+ DUK_ASSERT(cat != NULL);
+ DUK_ASSERT(!DUK_CAT_HAS_CATCH_ENABLED(cat)); /* cleared before entering catch part */
+
+ if (DUK_CAT_HAS_LEXENV_ACTIVE(cat)) {
+ duk_hobject *prev_env;
+
+ /* 'with' binding has no catch clause, so can't be here unless a normal try-catch */
+ DUK_ASSERT(DUK_CAT_HAS_CATCH_BINDING_ENABLED(cat));
+ DUK_ASSERT(act->lex_env != NULL);
+
+ DUK_DDD(DUK_DDDPRINT("ENDCATCH: popping catcher part lexical environment"));
+
+ prev_env = act->lex_env;
+ DUK_ASSERT(prev_env != NULL);
+ act->lex_env = DUK_HOBJECT_GET_PROTOTYPE(thr->heap, prev_env);
+ DUK_CAT_CLEAR_LEXENV_ACTIVE(cat);
+ DUK_HOBJECT_INCREF(thr, act->lex_env);
+ DUK_HOBJECT_DECREF(thr, prev_env); /* side effects */
+
+ DUK_ASSERT(act == thr->callstack_curr);
+ DUK_ASSERT(act != NULL);
+ }
+
+ pc_base = cat->pc_base;
+
+ if (DUK_CAT_HAS_FINALLY_ENABLED(cat)) {
+ DUK_DDD(DUK_DDDPRINT("ENDCATCH: finally part is active, jump through 2nd jump slot with 'normal continuation'"));
+
+ tv1 = thr->valstack + cat->idx_base;
+ DUK_ASSERT(tv1 >= thr->valstack && tv1 < thr->valstack_top);
+ DUK_TVAL_SET_UNDEFINED_UPDREF(thr, tv1); /* side effects */
+ tv1 = NULL;
+
+ tv1 = thr->valstack + cat->idx_base + 1;
+ DUK_ASSERT(tv1 >= thr->valstack && tv1 < thr->valstack_top);
+ DUK_TVAL_SET_U32_UPDREF(thr, tv1, (duk_uint32_t) DUK_LJ_TYPE_NORMAL); /* side effects */
+ tv1 = NULL;
+
+ DUK_CAT_CLEAR_FINALLY_ENABLED(cat);
+ } else {
+ DUK_DDD(DUK_DDDPRINT("ENDCATCH: no finally part, dismantle catcher, jump through 2nd jump slot (to end of statement)"));
+
+ duk_hthread_catcher_unwind_norz(thr, act);
+ /* no need to unwind callstack */
+ }
+
+ return pc_base + 1; /* new curr_pc value */
+}
+
+DUK_LOCAL DUK__NOINLINE_PERF duk_small_uint_t duk__handle_op_endfin(duk_hthread *thr, duk_uint_fast32_t ins, duk_activation *entry_act) {
+ duk_activation *act;
+ duk_tval *tv1;
+ duk_uint_t reg_catch;
+ duk_small_uint_t cont_type;
+ duk_small_uint_t ret_result;
+
+ DUK_ASSERT(thr->ptr_curr_pc == NULL);
+ DUK_ASSERT(thr->callstack_top >= 1);
+ act = thr->callstack_curr;
+ DUK_ASSERT(act != NULL);
+ reg_catch = DUK_DEC_ABC(ins);
+
+ /* CATCH flag may be enabled or disabled here; it may be enabled if
+ * the statement has a catch block but the try block does not throw
+ * an error.
+ */
+
+ DUK_DDD(DUK_DDDPRINT("ENDFIN: completion value=%!T, type=%!T",
+ (duk_tval *) (thr->valstack_bottom + reg_catch + 0),
+ (duk_tval *) (thr->valstack_bottom + reg_catch + 1)));
+
+ tv1 = thr->valstack_bottom + reg_catch + 1; /* type */
+ DUK_ASSERT(DUK_TVAL_IS_NUMBER(tv1));
+#if defined(DUK_USE_FASTINT)
+ DUK_ASSERT(DUK_TVAL_IS_FASTINT(tv1));
+ cont_type = (duk_small_uint_t) DUK_TVAL_GET_FASTINT_U32(tv1);
+#else
+ cont_type = (duk_small_uint_t) DUK_TVAL_GET_NUMBER(tv1);
+#endif
+
+ tv1--; /* value */
+
+ switch (cont_type) {
+ case DUK_LJ_TYPE_NORMAL: {
+ DUK_DDD(DUK_DDDPRINT("ENDFIN: finally part finishing with 'normal' (non-abrupt) completion -> "
+ "dismantle catcher, resume execution after ENDFIN"));
+
+ duk_hthread_catcher_unwind_norz(thr, act);
+ /* no need to unwind callstack */
+ return 0; /* restart execution */
+ }
+ case DUK_LJ_TYPE_RETURN: {
+ DUK_DDD(DUK_DDDPRINT("ENDFIN: finally part finishing with 'return' complation -> dismantle "
+ "catcher, handle return, lj.value1=%!T", tv1));
+
+ /* Not necessary to unwind catch stack: return handling will
+ * do it. The finally flag of 'cat' is no longer set. The
+ * catch flag may be set, but it's not checked by return handling.
+ */
+
+ duk_push_tval(thr, tv1);
+ ret_result = duk__handle_return(thr, entry_act);
+ if (ret_result == DUK__RETHAND_RESTART) {
+ return 0; /* restart execution */
+ }
+ DUK_ASSERT(ret_result == DUK__RETHAND_FINISHED);
+
+ DUK_DDD(DUK_DDDPRINT("exiting executor after ENDFIN and RETURN (pseudo) longjmp type"));
+ return 1; /* exit executor */
+ }
+ case DUK_LJ_TYPE_BREAK:
+ case DUK_LJ_TYPE_CONTINUE: {
+ duk_uint_t label_id;
+ duk_small_uint_t lj_type;
+
+ /* Not necessary to unwind catch stack: break/continue
+ * handling will do it. The finally flag of 'cat' is
+ * no longer set. The catch flag may be set, but it's
+ * not checked by break/continue handling.
+ */
+
+ DUK_ASSERT(DUK_TVAL_IS_NUMBER(tv1));
+#if defined(DUK_USE_FASTINT)
+ DUK_ASSERT(DUK_TVAL_IS_FASTINT(tv1));
+ label_id = (duk_small_uint_t) DUK_TVAL_GET_FASTINT_U32(tv1);
+#else
+ label_id = (duk_small_uint_t) DUK_TVAL_GET_NUMBER(tv1);
+#endif
+ lj_type = cont_type;
+ duk__handle_break_or_continue(thr, label_id, lj_type);
+ return 0; /* restart execution */
+ }
+ default: {
+ DUK_DDD(DUK_DDDPRINT("ENDFIN: finally part finishing with abrupt completion, lj_type=%ld -> "
+ "dismantle catcher, re-throw error",
+ (long) cont_type));
+
+ duk_err_setup_ljstate1(thr, (duk_small_uint_t) cont_type, tv1);
+ /* No debugger Throw notify check on purpose (rethrow). */
+
+ DUK_ASSERT(thr->heap->lj.jmpbuf_ptr != NULL); /* always in executor */
+ duk_err_longjmp(thr);
+ DUK_UNREACHABLE();
+ }
+ }
+
+ DUK_UNREACHABLE();
+ return 0;
+}
+
+DUK_LOCAL DUK__NOINLINE_PERF void duk__handle_op_initenum(duk_hthread *thr, duk_uint_fast32_t ins) {
+ duk_small_uint_t b;
+ duk_small_uint_t c;
+
+ /*
+ * Enumeration semantics come from for-in statement, E5 Section 12.6.4.
+ * If called with 'null' or 'undefined', this opcode returns 'null' as
+ * the enumerator, which is special cased in NEXTENUM. This simplifies
+ * the compiler part
+ */
+
+ /* B -> register for writing enumerator object
+ * C -> value to be enumerated (register)
+ */
+ b = DUK_DEC_B(ins);
+ c = DUK_DEC_C(ins);
+
+ if (duk_is_null_or_undefined(thr, (duk_idx_t) c)) {
+ duk_push_null(thr);
+ duk_replace(thr, (duk_idx_t) b);
+ } else {
+ duk_dup(thr, (duk_idx_t) c);
+ duk_to_object(thr, -1);
+ duk_hobject_enumerator_create(thr, 0 /*enum_flags*/); /* [ ... val ] --> [ ... enum ] */
+ duk_replace(thr, (duk_idx_t) b);
+ }
+}
+
+DUK_LOCAL DUK__NOINLINE_PERF duk_small_uint_t duk__handle_op_nextenum(duk_hthread *thr, duk_uint_fast32_t ins) {
+ duk_small_uint_t b;
+ duk_small_uint_t c;
+ duk_small_uint_t pc_skip = 0;
+
+ /*
+ * NEXTENUM checks whether the enumerator still has unenumerated
+ * keys. If so, the next key is loaded to the target register
+ * and the next instruction is skipped. Otherwise the next instruction
+ * will be executed, jumping out of the enumeration loop.
+ */
+
+ /* B -> target register for next key
+ * C -> enum register
+ */
+ b = DUK_DEC_B(ins);
+ c = DUK_DEC_C(ins);
+
+ DUK_DDD(DUK_DDDPRINT("NEXTENUM: b->%!T, c->%!T",
+ (duk_tval *) duk_get_tval(thr, (duk_idx_t) b),
+ (duk_tval *) duk_get_tval(thr, (duk_idx_t) c)));
+
+ if (duk_is_object(thr, (duk_idx_t) c)) {
+ /* XXX: assert 'c' is an enumerator */
+ duk_dup(thr, (duk_idx_t) c);
+ if (duk_hobject_enumerator_next(thr, 0 /*get_value*/)) {
+ /* [ ... enum ] -> [ ... next_key ] */
+ DUK_DDD(DUK_DDDPRINT("enum active, next key is %!T, skip jump slot ",
+ (duk_tval *) duk_get_tval(thr, -1)));
+ pc_skip = 1;
+ } else {
+ /* [ ... enum ] -> [ ... ] */
+ DUK_DDD(DUK_DDDPRINT("enum finished, execute jump slot"));
+ DUK_ASSERT(DUK_TVAL_IS_UNDEFINED(thr->valstack_top)); /* valstack policy */
+ thr->valstack_top++;
+ }
+ duk_replace(thr, (duk_idx_t) b);
+ } else {
+ /* 'null' enumerator case -> behave as with an empty enumerator */
+ DUK_ASSERT(duk_is_null(thr, (duk_idx_t) c));
+ DUK_DDD(DUK_DDDPRINT("enum is null, execute jump slot"));
+ }
+
+ return pc_skip;
+}
+
+/*
+ * Call handling helpers.
+ */
+
+DUK_LOCAL duk_bool_t duk__executor_handle_call(duk_hthread *thr, duk_idx_t idx, duk_idx_t nargs, duk_small_uint_t call_flags) {
+ duk_bool_t rc;
+
+ duk_set_top_unsafe(thr, (duk_idx_t) (idx + nargs + 2)); /* [ ... func this arg1 ... argN ] */
+
+ /* Attempt an Ecma-to-Ecma call setup. If the call
+ * target is (directly or indirectly) Reflect.construct(),
+ * the call may change into a constructor call on the fly.
+ */
+ rc = (duk_bool_t) duk_handle_call_unprotected(thr, idx, call_flags);
+ if (rc != 0) {
+ /* Ecma-to-ecma call possible, may or may not
+ * be a tail call. Avoid C recursion by
+ * reusing current executor instance.
+ */
+ DUK_DDD(DUK_DDDPRINT("ecma-to-ecma call setup possible, restart execution"));
+ /* curr_pc synced by duk_handle_call_unprotected() */
+ DUK_ASSERT(thr->ptr_curr_pc == NULL);
+ return rc;
+ } else {
+ /* Call was handled inline. */
+ }
+ DUK_ASSERT(thr->ptr_curr_pc != NULL);
+ return rc;
+}
+
+/*
* Ecmascript bytecode executor.
*
* Resume execution for the current thread from its current activation.
@@ -72493,7 +74541,9 @@ DUK_LOCAL void duk__executor_recheck_debugger(duk_hthread *thr, duk_activation *
#else
#define DUK__FUN() ((duk_hcompfunc *) DUK_ACT_GET_FUNC((thr)->callstack_curr))
#endif
-#define DUK__STRICT() (DUK_HOBJECT_HAS_STRICT((duk_hobject *) DUK__FUN()))
+
+/* Strict flag. */
+#define DUK__STRICT() ((duk_small_uint_t) DUK_HOBJECT_HAS_STRICT((duk_hobject *) DUK__FUN()))
/* Reg/const access macros: these are very footprint and performance sensitive
* so modify with care. Arguments are sometimes evaluated multiple times which
@@ -72567,23 +74617,23 @@ DUK_LOCAL void duk__executor_recheck_debugger(duk_hthread *thr, duk_activation *
#endif
#define DUK__SYNC_CURR_PC() do { \
- duk_activation *act; \
- act = thr->callstack_curr; \
- act->curr_pc = curr_pc; \
+ duk_activation *duk__act; \
+ duk__act = thr->callstack_curr; \
+ duk__act->curr_pc = curr_pc; \
} while (0)
#define DUK__SYNC_AND_NULL_CURR_PC() do { \
- duk_activation *act; \
- act = thr->callstack_curr; \
- act->curr_pc = curr_pc; \
+ duk_activation *duk__act; \
+ duk__act = thr->callstack_curr; \
+ duk__act->curr_pc = curr_pc; \
thr->ptr_curr_pc = NULL; \
} while (0)
#if defined(DUK_USE_EXEC_PREFER_SIZE)
-#define DUK__LOOKUP_INDIRECT_INDEX(idx) do { \
- (idx) = (duk_uint_fast_t) duk_get_uint(ctx, (idx)); \
+#define DUK__LOOKUP_INDIRECT(idx) do { \
+ (idx) = (duk_uint_fast_t) duk_get_uint(thr, (duk_idx_t) (idx)); \
} while (0)
#elif defined(DUK_USE_FASTINT)
-#define DUK__LOOKUP_INDIRECT_INDEX(idx) do { \
+#define DUK__LOOKUP_INDIRECT(idx) do { \
duk_tval *tv_ind; \
tv_ind = DUK__REGP((idx)); \
DUK_ASSERT(DUK_TVAL_IS_NUMBER(tv_ind)); \
@@ -72591,7 +74641,7 @@ DUK_LOCAL void duk__executor_recheck_debugger(duk_hthread *thr, duk_activation *
(idx) = (duk_uint_fast_t) DUK_TVAL_GET_FASTINT_U32(tv_ind); \
} while (0)
#else
-#define DUK__LOOKUP_INDIRECT_INDEX(idx) do { \
+#define DUK__LOOKUP_INDIRECT(idx) do { \
duk_tval *tv_ind; \
tv_ind = DUK__REGP(idx); \
DUK_ASSERT(DUK_TVAL_IS_NUMBER(tv_ind)); \
@@ -72600,8 +74650,7 @@ DUK_LOCAL void duk__executor_recheck_debugger(duk_hthread *thr, duk_activation *
#endif
DUK_LOCAL void duk__handle_executor_error(duk_heap *heap,
- duk_hthread *entry_thread,
- duk_size_t entry_callstack_top,
+ duk_activation *entry_act,
duk_int_t entry_call_recursion_depth,
duk_jmpbuf *entry_jmpbuf_ptr) {
duk_small_uint_t lj_ret;
@@ -72623,7 +74672,7 @@ DUK_LOCAL void duk__handle_executor_error(duk_heap *heap,
*/
heap->lj.jmpbuf_ptr = (duk_jmpbuf *) entry_jmpbuf_ptr;
- lj_ret = duk__handle_longjmp(heap->curr_thread, entry_thread, entry_callstack_top);
+ lj_ret = duk__handle_longjmp(heap->curr_thread, entry_act);
/* Error handling complete, remove side effect protections.
*/
@@ -72657,7 +74706,7 @@ DUK_LOCAL void duk__handle_executor_error(duk_heap *heap,
DUK_INTERNAL void duk_js_execute_bytecode(duk_hthread *exec_thr) {
/* Entry level info. */
duk_hthread *entry_thread;
- duk_size_t entry_callstack_top;
+ duk_activation *entry_act;
duk_int_t entry_call_recursion_depth;
duk_jmpbuf *entry_jmpbuf_ptr;
duk_jmpbuf our_jmpbuf;
@@ -72668,6 +74717,7 @@ DUK_INTERNAL void duk_js_execute_bytecode(duk_hthread *exec_thr) {
DUK_ASSERT(exec_thr->heap->curr_thread != NULL);
DUK_ASSERT_REFCOUNT_NONZERO_HEAPHDR((duk_heaphdr *) exec_thr);
DUK_ASSERT(exec_thr->callstack_top >= 1); /* at least one activation, ours */
+ DUK_ASSERT(exec_thr->callstack_curr != NULL);
DUK_ASSERT(DUK_ACT_GET_FUNC(exec_thr->callstack_curr) != NULL);
DUK_ASSERT(DUK_HOBJECT_IS_COMPFUNC(DUK_ACT_GET_FUNC(exec_thr->callstack_curr)));
@@ -72675,7 +74725,8 @@ DUK_INTERNAL void duk_js_execute_bytecode(duk_hthread *exec_thr) {
entry_thread = exec_thr;
heap = entry_thread->heap;
- entry_callstack_top = entry_thread->callstack_top;
+ entry_act = entry_thread->callstack_curr;
+ DUK_ASSERT(entry_act != NULL);
entry_call_recursion_depth = entry_thread->heap->call_recursion_depth;
entry_jmpbuf_ptr = entry_thread->heap->lj.jmpbuf_ptr;
@@ -72699,7 +74750,7 @@ DUK_INTERNAL void duk_js_execute_bytecode(duk_hthread *exec_thr) {
if (DUK_SETJMP(our_jmpbuf.jb) == 0) {
#endif
/* Execute bytecode until returned or longjmp(). */
- duk__js_execute_bytecode_inner(entry_thread, entry_callstack_top);
+ duk__js_execute_bytecode_inner(entry_thread, entry_act);
/* Successful return: restore jmpbuf and return to caller. */
heap->lj.jmpbuf_ptr = entry_jmpbuf_ptr;
@@ -72714,10 +74765,10 @@ DUK_INTERNAL void duk_js_execute_bytecode(duk_hthread *exec_thr) {
DUK_UNREF(exc);
#endif
DUK_DDD(DUK_DDDPRINT("longjmp caught by bytecode executor"));
+ DUK_STATS_INC(exec_thr->heap, stats_exec_throw);
duk__handle_executor_error(heap,
- entry_thread,
- entry_callstack_top,
+ entry_act,
entry_call_recursion_depth,
entry_jmpbuf_ptr);
}
@@ -72728,6 +74779,7 @@ DUK_INTERNAL void duk_js_execute_bytecode(duk_hthread *exec_thr) {
what = "unknown";
}
DUK_D(DUK_DPRINT("unexpected c++ std::exception (perhaps thrown by user code)"));
+ DUK_STATS_INC(exec_thr->heap, stats_exec_throw);
try {
DUK_ASSERT(heap->curr_thread != NULL);
DUK_ERROR_FMT1(heap->curr_thread, DUK_ERR_TYPE_ERROR, "caught invalid c++ std::exception '%s' (perhaps thrown by user code)", what);
@@ -72735,13 +74787,13 @@ DUK_INTERNAL void duk_js_execute_bytecode(duk_hthread *exec_thr) {
DUK_D(DUK_DPRINT("caught api error thrown from unexpected c++ std::exception"));
DUK_UNREF(exc);
duk__handle_executor_error(heap,
- entry_thread,
- entry_callstack_top,
+ entry_act,
entry_call_recursion_depth,
entry_jmpbuf_ptr);
}
} catch (...) {
DUK_D(DUK_DPRINT("unexpected c++ exception (perhaps thrown by user code)"));
+ DUK_STATS_INC(exec_thr->heap, stats_exec_throw);
try {
DUK_ASSERT(heap->curr_thread != NULL);
DUK_ERROR_TYPE(heap->curr_thread, "caught invalid c++ exception (perhaps thrown by user code)");
@@ -72749,8 +74801,7 @@ DUK_INTERNAL void duk_js_execute_bytecode(duk_hthread *exec_thr) {
DUK_D(DUK_DPRINT("caught api error thrown from unexpected c++ exception"));
DUK_UNREF(exc);
duk__handle_executor_error(heap,
- entry_thread,
- entry_callstack_top,
+ entry_act,
entry_call_recursion_depth,
entry_jmpbuf_ptr);
}
@@ -72762,7 +74813,7 @@ DUK_INTERNAL void duk_js_execute_bytecode(duk_hthread *exec_thr) {
}
/* Inner executor, performance critical. */
-DUK_LOCAL DUK_NOINLINE DUK_HOT void duk__js_execute_bytecode_inner(duk_hthread *entry_thread, duk_size_t entry_callstack_top) {
+DUK_LOCAL DUK_NOINLINE DUK_HOT void duk__js_execute_bytecode_inner(duk_hthread *entry_thread, duk_activation *entry_act) {
/* Current PC, accessed by other functions through thr->ptr_to_curr_pc.
* Critical for performance. It would be safest to make this volatile,
* but that eliminates performance benefits; aliasing guarantees
@@ -72840,7 +74891,6 @@ DUK_LOCAL DUK_NOINLINE DUK_HOT void duk__js_execute_bytecode_inner(duk_hthread *
*
* The following are not assumed to have stable pointers at all:
* - the value stack (registers) of the current thread
- * - the catch stack of the current thread
*
* See execution.rst for discussion.
*/
@@ -72881,9 +74931,9 @@ DUK_LOCAL DUK_NOINLINE DUK_HOT void duk__js_execute_bytecode_inner(duk_hthread *
DUK_ASSERT(consts != NULL);
#if defined(DUK_USE_DEBUGGER_SUPPORT)
- if (duk_debug_is_attached(thr->heap) && !thr->heap->dbg_processing) {
+ if (DUK_UNLIKELY(duk_debug_is_attached(thr->heap) && !thr->heap->dbg_processing)) {
duk__executor_recheck_debugger(thr, act, fun);
- act = thr->callstack_curr; /* relookup after side effects (no side effects currently however) */
+ DUK_ASSERT(act == thr->callstack_curr);
DUK_ASSERT(act != NULL);
}
#endif /* DUK_USE_DEBUGGER_SUPPORT */
@@ -72897,7 +74947,7 @@ DUK_LOCAL DUK_NOINLINE DUK_HOT void duk__js_execute_bytecode_inner(duk_hthread *
}
DUK_DD(DUK_DDPRINT("restarting execution, thr %p, act idx %ld, fun %p,"
- "consts %p, funcs %p, lev %ld, regbot %ld, regtop %ld, catchstack_top=%ld, "
+ "consts %p, funcs %p, lev %ld, regbot %ld, regtop %ld, "
"preventcount=%ld",
(void *) thr,
(long) (thr->callstack_top - 1),
@@ -72907,7 +74957,6 @@ DUK_LOCAL DUK_NOINLINE DUK_HOT void duk__js_execute_bytecode_inner(duk_hthread *
(long) (thr->callstack_top - 1),
(long) (thr->valstack_bottom - thr->valstack),
(long) (thr->valstack_top - thr->valstack),
- (long) thr->catchstack_top,
(long) thr->callstack_preventcount));
/* Dispatch loop. */
@@ -72933,6 +74982,8 @@ DUK_LOCAL DUK_NOINLINE DUK_HOT void duk__js_execute_bytecode_inner(duk_hthread *
/* Trigger at zero or below */
duk_small_uint_t exec_int_ret;
+ DUK_STATS_INC(thr->heap, stats_exec_interrupt);
+
/* Write curr_pc back for the debugger. */
{
duk_activation *act;
@@ -72942,7 +74993,7 @@ DUK_LOCAL DUK_NOINLINE DUK_HOT void duk__js_execute_bytecode_inner(duk_hthread *
act->curr_pc = (duk_instr_t *) curr_pc;
}
- /* Force restart caused by a function return; must recheck
+ /* Forced restart caused by a function return; must recheck
* debugger breakpoints before checking line transitions,
* see GH-303. Restart and then handle interrupt_counter
* zero again.
@@ -73004,6 +75055,7 @@ DUK_LOCAL DUK_NOINLINE DUK_HOT void duk__js_execute_bytecode_inner(duk_hthread *
#endif
ins = *curr_pc++;
+ DUK_STATS_INC(thr->heap, stats_exec_opcodes);
/* Typing: use duk_small_(u)int_fast_t when decoding small
* opcode fields (op, A, B, C, BC) which fit into 16 bits
@@ -73031,7 +75083,7 @@ DUK_LOCAL DUK_NOINLINE DUK_HOT void duk__js_execute_bytecode_inner(duk_hthread *
duk_bool_t duk__bval; \
duk__bval = (bval); \
DUK_ASSERT(duk__bval == 0 || duk__bval == 1); \
- duk_push_boolean((duk_context *) thr, duk__bval); \
+ duk_push_boolean(thr, duk__bval); \
DUK__REPLACE_TOP_A_BREAK(); \
}
#else
@@ -73092,15 +75144,15 @@ DUK_LOCAL DUK_NOINLINE DUK_HOT void duk__js_execute_bytecode_inner(duk_hthread *
duk_int32_t val;
val = (duk_int32_t) DUK_DEC_BC(ins) - (duk_int32_t) DUK_BC_LDINT_BIAS;
- duk_push_int((duk_context *) thr, val);
+ duk_push_int(thr, val);
DUK__REPLACE_TOP_A_BREAK();
}
case DUK_OP_LDINTX: {
duk_int32_t val;
- val = (duk_int32_t) duk_get_int((duk_context *) thr, DUK_DEC_A(ins));
+ val = (duk_int32_t) duk_get_int(thr, DUK_DEC_A(ins));
val = (val << DUK_BC_LDINTX_SHIFT) + (duk_int32_t) DUK_DEC_BC(ins); /* no bias */
- duk_push_int((duk_context *) thr, val);
+ duk_push_int(thr, val);
DUK__REPLACE_TOP_A_BREAK();
}
#else /* DUK_USE_EXEC_PREFER_SIZE */
@@ -73134,23 +75186,23 @@ DUK_LOCAL DUK_NOINLINE DUK_HOT void duk__js_execute_bytecode_inner(duk_hthread *
#if defined(DUK_USE_EXEC_PREFER_SIZE)
case DUK_OP_LDTHIS: {
- duk_push_this((duk_context *) thr);
+ duk_push_this(thr);
DUK__REPLACE_TOP_BC_BREAK();
}
case DUK_OP_LDUNDEF: {
- duk_to_undefined((duk_context *) thr, (duk_idx_t) DUK_DEC_BC(ins));
+ duk_to_undefined(thr, (duk_idx_t) DUK_DEC_BC(ins));
break;
}
case DUK_OP_LDNULL: {
- duk_to_null((duk_context *) thr, (duk_idx_t) DUK_DEC_BC(ins));
+ duk_to_null(thr, (duk_idx_t) DUK_DEC_BC(ins));
break;
}
case DUK_OP_LDTRUE: {
- duk_push_true((duk_context *) thr);
+ duk_push_true(thr);
DUK__REPLACE_TOP_BC_BREAK();
}
case DUK_OP_LDFALSE: {
- duk_push_false((duk_context *) thr);
+ duk_push_false(thr);
DUK__REPLACE_TOP_BC_BREAK();
}
#else /* DUK_USE_EXEC_PREFER_SIZE */
@@ -73226,8 +75278,8 @@ DUK_LOCAL DUK_NOINLINE DUK_HOT void duk__js_execute_bytecode_inner(duk_hthread *
duk_small_uint_t stridx;
stridx = duk_js_typeof_stridx(DUK__REGP_BC(ins));
- DUK_ASSERT(stridx >= 0 && stridx < DUK_HEAP_NUM_STRINGS);
- duk_push_hstring_stridx((duk_context *) thr, stridx);
+ DUK_ASSERT_STRIDX_VALID(stridx);
+ duk_push_hstring_stridx(thr, stridx);
DUK__REPLACE_TOP_A_BREAK();
}
#else /* DUK_USE_EXEC_PREFER_SIZE */
@@ -73247,7 +75299,6 @@ DUK_LOCAL DUK_NOINLINE DUK_HOT void duk__js_execute_bytecode_inner(duk_hthread *
#endif /* DUK_USE_EXEC_PREFER_SIZE */
case DUK_OP_TYPEOFID: {
- duk_context *ctx = (duk_context *) thr;
duk_small_uint_t stridx;
#if !defined(DUK_USE_EXEC_PREFER_SIZE)
duk_hstring *h_str;
@@ -73267,17 +75318,17 @@ DUK_LOCAL DUK_NOINLINE DUK_HOT void duk__js_execute_bytecode_inner(duk_hthread *
act = thr->callstack_curr;
if (duk_js_getvar_activation(thr, act, name, 0 /*throw*/)) {
/* -> [... val this] */
- tv = DUK_GET_TVAL_NEGIDX(ctx, -2);
+ tv = DUK_GET_TVAL_NEGIDX(thr, -2);
stridx = duk_js_typeof_stridx(tv);
tv = NULL; /* no longer needed */
- duk_pop_2(ctx);
+ duk_pop_2_unsafe(thr);
} else {
/* unresolvable, no stack changes */
stridx = DUK_STRIDX_LC_UNDEFINED;
}
DUK_ASSERT_STRIDX_VALID(stridx);
#if defined(DUK_USE_EXEC_PREFER_SIZE)
- duk_push_hstring_stridx(ctx, stridx);
+ duk_push_hstring_stridx(thr, stridx);
DUK__REPLACE_TOP_A_BREAK();
#else /* DUK_USE_EXEC_PREFER_SIZE */
h_str = DUK_HTHREAD_GET_STRING(thr, stridx);
@@ -73844,7 +75895,6 @@ DUK_LOCAL DUK_NOINLINE DUK_HOT void duk__js_execute_bytecode_inner(duk_hthread *
case DUK_OP_POSTDECP_CR:
case DUK_OP_POSTDECP_RC:
case DUK_OP_POSTDECP_CC: {
- duk_context *ctx = (duk_context *) thr;
duk_tval *tv_obj;
duk_tval *tv_key;
duk_tval *tv_val;
@@ -73880,16 +75930,16 @@ DUK_LOCAL DUK_NOINLINE DUK_HOT void duk__js_execute_bytecode_inner(duk_hthread *
* not intuitive.
*/
- x = duk_to_number_m1(ctx);
- duk_pop(ctx);
+ x = duk_to_number_m1(thr);
+ duk_pop_unsafe(thr);
if (ins & DUK_BC_INCDECP_FLAG_DEC) {
y = x - 1.0;
} else {
y = x + 1.0;
}
- duk_push_number(ctx, y);
- tv_val = DUK_GET_TVAL_NEGIDX(ctx, -1);
+ duk_push_number(thr, y);
+ tv_val = DUK_GET_TVAL_NEGIDX(thr, -1);
DUK_ASSERT(tv_val != NULL);
tv_obj = DUK__REGCONSTP_B(ins);
tv_key = DUK__REGCONSTP_C(ins);
@@ -73897,11 +75947,11 @@ DUK_LOCAL DUK_NOINLINE DUK_HOT void duk__js_execute_bytecode_inner(duk_hthread *
DUK_UNREF(rc); /* ignore */
tv_obj = NULL; /* invalidated */
tv_key = NULL; /* invalidated */
- duk_pop(ctx);
+ duk_pop_unsafe(thr);
z = (ins & DUK_BC_INCDECP_FLAG_POST) ? x : y;
#if defined(DUK_USE_EXEC_PREFER_SIZE)
- duk_push_number(ctx, z);
+ duk_push_number(thr, z);
DUK__REPLACE_TOP_A_BREAK();
#else
tv_dst = DUK__REGP_A(ins);
@@ -73922,6 +75972,21 @@ DUK_LOCAL DUK_NOINLINE DUK_HOT void duk__js_execute_bytecode_inner(duk_hthread *
(void) duk_hobject_getprop(thr, (barg), (carg)); \
DUK__REPLACE_TOP_A_BREAK(); \
}
+#define DUK__GETPROPC_BODY(barg,carg) { \
+ /* Same as GETPROP but callability check for property-based calls. */ \
+ duk_tval *tv__targ; \
+ (void) duk_hobject_getprop(thr, (barg), (carg)); \
+ DUK_GC_TORTURE(thr->heap); \
+ tv__targ = DUK_GET_TVAL_NEGIDX(thr, -1); \
+ if (DUK_UNLIKELY(!duk_is_callable_tval(thr, tv__targ))) { \
+ /* Here we intentionally re-evaluate the macro \
+ * arguments to deal with potentially changed \
+ * valstack base pointer! \
+ */ \
+ duk_call_setup_propcall_error(thr, tv__targ, (barg), (carg)); \
+ } \
+ DUK__REPLACE_TOP_A_BREAK(); \
+ }
#define DUK__PUTPROP_BODY(aarg,barg,carg) { \
/* A -> object reg \
* B -> key reg/const \
@@ -73949,6 +76014,13 @@ DUK_LOCAL DUK_NOINLINE DUK_HOT void duk__js_execute_bytecode_inner(duk_hthread *
case DUK_OP_GETPROP_RC:
case DUK_OP_GETPROP_CC:
DUK__GETPROP_BODY(DUK__REGCONSTP_B(ins), DUK__REGCONSTP_C(ins));
+#if defined(DUK_USE_VERBOSE_ERRORS)
+ case DUK_OP_GETPROPC_RR:
+ case DUK_OP_GETPROPC_CR:
+ case DUK_OP_GETPROPC_RC:
+ case DUK_OP_GETPROPC_CC:
+ DUK__GETPROPC_BODY(DUK__REGCONSTP_B(ins), DUK__REGCONSTP_C(ins));
+#endif
case DUK_OP_PUTPROP_RR:
case DUK_OP_PUTPROP_CR:
case DUK_OP_PUTPROP_RC:
@@ -73966,6 +76038,16 @@ DUK_LOCAL DUK_NOINLINE DUK_HOT void duk__js_execute_bytecode_inner(duk_hthread *
DUK__GETPROP_BODY(DUK__REGP_B(ins), DUK__CONSTP_C(ins));
case DUK_OP_GETPROP_CC:
DUK__GETPROP_BODY(DUK__CONSTP_B(ins), DUK__CONSTP_C(ins));
+#if defined(DUK_USE_VERBOSE_ERRORS)
+ case DUK_OP_GETPROPC_RR:
+ DUK__GETPROPC_BODY(DUK__REGP_B(ins), DUK__REGP_C(ins));
+ case DUK_OP_GETPROPC_CR:
+ DUK__GETPROPC_BODY(DUK__CONSTP_B(ins), DUK__REGP_C(ins));
+ case DUK_OP_GETPROPC_RC:
+ DUK__GETPROPC_BODY(DUK__REGP_B(ins), DUK__CONSTP_C(ins));
+ case DUK_OP_GETPROPC_CC:
+ DUK__GETPROPC_BODY(DUK__CONSTP_B(ins), DUK__CONSTP_C(ins));
+#endif
case DUK_OP_PUTPROP_RR:
DUK__PUTPROP_BODY(DUK__REGP_A(ins), DUK__REGP_B(ins), DUK__REGP_C(ins));
case DUK_OP_PUTPROP_CR:
@@ -73986,7 +76068,6 @@ DUK_LOCAL DUK_NOINLINE DUK_HOT void duk__js_execute_bytecode_inner(duk_hthread *
case DUK_OP_DECLVAR_RC:
case DUK_OP_DECLVAR_CC: {
duk_activation *act;
- duk_context *ctx = (duk_context *) thr;
duk_small_uint_fast_t a = DUK_DEC_A(ins);
duk_tval *tv1;
duk_hstring *name;
@@ -74010,18 +76091,18 @@ DUK_LOCAL DUK_NOINLINE DUK_HOT void duk__js_execute_bytecode_inner(duk_hthread *
prop_flags = a & DUK_PROPDESC_FLAGS_MASK;
if (is_func_decl) {
- duk_push_tval(ctx, DUK__REGCONSTP_C(ins));
+ duk_push_tval(thr, DUK__REGCONSTP_C(ins));
} else {
DUK_ASSERT(DUK_TVAL_IS_UNDEFINED(thr->valstack_top)); /* valstack policy */
thr->valstack_top++;
}
- tv1 = DUK_GET_TVAL_NEGIDX(ctx, -1);
+ tv1 = DUK_GET_TVAL_NEGIDX(thr, -1);
act = thr->callstack_curr;
if (duk_js_declvar_activation(thr, act, name, tv1, prop_flags, is_func_decl)) {
if (is_func_decl) {
/* Already declared, update value. */
- tv1 = DUK_GET_TVAL_NEGIDX(ctx, -1);
+ tv1 = DUK_GET_TVAL_NEGIDX(thr, -1);
duk_js_putvar_activation(thr, act, name, tv1, DUK__STRICT());
} else {
/* Already declared but no initializer value
@@ -74030,7 +76111,7 @@ DUK_LOCAL DUK_NOINLINE DUK_HOT void duk__js_execute_bytecode_inner(duk_hthread *
}
}
- duk_pop(ctx);
+ duk_pop_unsafe(thr);
break;
}
@@ -74047,8 +76128,8 @@ DUK_LOCAL DUK_NOINLINE DUK_HOT void duk__js_execute_bytecode_inner(duk_hthread *
* C -> escaped source
*/
- duk_push_tval((duk_context *) thr, DUK__REGCONSTP_C(ins));
- duk_push_tval((duk_context *) thr, DUK__REGCONSTP_B(ins)); /* -> [ ... escaped_source bytecode ] */
+ duk_push_tval(thr, DUK__REGCONSTP_C(ins));
+ duk_push_tval(thr, DUK__REGCONSTP_B(ins)); /* -> [ ... escaped_source bytecode ] */
duk_regexp_create_instance(thr); /* -> [ ... regexp_instance ] */
DUK__REPLACE_TOP_A_BREAK();
}
@@ -74067,7 +76148,6 @@ DUK_LOCAL DUK_NOINLINE DUK_HOT void duk__js_execute_bytecode_inner(duk_hthread *
* (2) that object environment record is a 'with' block.
*/
- duk_context *ctx = (duk_context *) thr;
duk_activation *act;
duk_uint_fast_t idx;
duk_tval *tv1;
@@ -74087,8 +76167,8 @@ DUK_LOCAL DUK_NOINLINE DUK_HOT void duk__js_execute_bytecode_inner(duk_hthread *
idx = (duk_uint_fast_t) DUK_DEC_A(ins);
/* Could add direct value stack handling. */
- duk_replace(ctx, (duk_idx_t) (idx + 1)); /* 'this' binding */
- duk_replace(ctx, (duk_idx_t) idx); /* variable value (function, we hope, not checked here) */
+ duk_replace(thr, (duk_idx_t) (idx + 1)); /* 'this' binding */
+ duk_replace(thr, (duk_idx_t) idx); /* variable value (function, we hope, not checked here) */
break;
}
@@ -74138,7 +76218,6 @@ DUK_LOCAL DUK_NOINLINE DUK_HOT void duk__js_execute_bytecode_inner(duk_hthread *
}
case DUK_OP_GETVAR: {
- duk_context *ctx = (duk_context *) thr;
duk_activation *act;
duk_tval *tv1;
duk_hstring *name;
@@ -74148,8 +76227,9 @@ DUK_LOCAL DUK_NOINLINE DUK_HOT void duk__js_execute_bytecode_inner(duk_hthread *
name = DUK_TVAL_GET_STRING(tv1);
DUK_ASSERT(name != NULL);
act = thr->callstack_curr;
+ DUK_ASSERT(act != NULL);
(void) duk_js_getvar_activation(thr, act, name, 1 /*throw*/); /* -> [... val this] */
- duk_pop(ctx); /* 'this' binding is not needed here */
+ duk_pop_unsafe(thr); /* 'this' binding is not needed here */
DUK__REPLACE_TOP_A_BREAK();
}
@@ -74203,9 +76283,8 @@ DUK_LOCAL DUK_NOINLINE DUK_HOT void duk__js_execute_bytecode_inner(duk_hthread *
* for potential out-of-memory situations which will then \
* propagate out of the executor longjmp handler. \
*/ \
- ret_result = duk__handle_return(thr, \
- entry_thread, \
- entry_callstack_top); \
+ DUK_ASSERT(thr->ptr_curr_pc == NULL); \
+ ret_result = duk__handle_return(thr, entry_act); \
if (ret_result == DUK__RETHAND_RESTART) { \
goto restart_execution; \
} \
@@ -74222,13 +76301,13 @@ DUK_LOCAL DUK_NOINLINE DUK_HOT void duk__js_execute_bytecode_inner(duk_hthread *
DUK__SYNC_AND_NULL_CURR_PC();
if (op == DUK_OP_RETREG) {
- duk_push_tval((duk_context *) thr, DUK__REGP_BC(ins));
+ duk_push_tval(thr, DUK__REGP_BC(ins));
} else if (op == DUK_OP_RETUNDEF) {
DUK_ASSERT(DUK_TVAL_IS_UNDEFINED(thr->valstack_top)); /* valstack policy */
thr->valstack_top++;
} else {
DUK_ASSERT(op == DUK_OP_RETCONST || op == DUK_OP_RETCONSTN);
- duk_push_tval((duk_context *) thr, DUK__CONSTP_BC(ins));
+ duk_push_tval(thr, DUK__CONSTP_BC(ins));
}
DUK__RETURN_SHARED();
@@ -74277,24 +76356,28 @@ DUK_LOCAL DUK_NOINLINE DUK_HOT void duk__js_execute_bytecode_inner(duk_hthread *
#endif /* DUK_USE_EXEC_PREFER_SIZE */
case DUK_OP_LABEL: {
+ duk_activation *act;
duk_catcher *cat;
duk_small_uint_fast_t bc = DUK_DEC_BC(ins);
- /* allocate catcher and populate it (should be atomic) */
+ /* Allocate catcher and populate it (must be atomic). */
- duk_hthread_catchstack_grow(thr);
- cat = thr->catchstack + thr->catchstack_top;
- thr->catchstack_top++;
+ cat = duk_hthread_catcher_alloc(thr);
+ DUK_ASSERT(cat != NULL);
- cat->flags = DUK_CAT_TYPE_LABEL | (bc << DUK_CAT_LABEL_SHIFT);
- cat->callstack_index = thr->callstack_top - 1;
+ cat->flags = (duk_uint32_t) (DUK_CAT_TYPE_LABEL | (bc << DUK_CAT_LABEL_SHIFT));
cat->pc_base = (duk_instr_t *) curr_pc; /* pre-incremented, points to first jump slot */
cat->idx_base = 0; /* unused for label */
cat->h_varname = NULL;
- DUK_DDD(DUK_DDDPRINT("LABEL catcher: flags=0x%08lx, callstack_index=%ld, pc_base=%ld, "
+ act = thr->callstack_curr;
+ DUK_ASSERT(act != NULL);
+ cat->parent = act->cat;
+ act->cat = cat;
+
+ DUK_DDD(DUK_DDDPRINT("LABEL catcher: flags=0x%08lx, pc_base=%ld, "
"idx_base=%ld, h_varname=%!O, label_id=%ld",
- (long) cat->flags, (long) cat->callstack_index, (long) cat->pc_base,
+ (long) cat->flags, (long) cat->pc_base,
(long) cat->idx_base, (duk_heaphdr *) cat->h_varname, (long) DUK_CAT_GET_LABEL(cat)));
curr_pc += 2; /* skip jump slots */
@@ -74302,7 +76385,7 @@ DUK_LOCAL DUK_NOINLINE DUK_HOT void duk__js_execute_bytecode_inner(duk_hthread *
}
case DUK_OP_ENDLABEL: {
- duk_catcher *cat;
+ duk_activation *act;
#if (defined(DUK_USE_DEBUG_LEVEL) && (DUK_USE_DEBUG_LEVEL >= 2)) || defined(DUK_USE_ASSERTIONS)
duk_small_uint_fast_t bc = DUK_DEC_BC(ins);
#endif
@@ -74310,14 +76393,12 @@ DUK_LOCAL DUK_NOINLINE DUK_HOT void duk__js_execute_bytecode_inner(duk_hthread *
DUK_DDD(DUK_DDDPRINT("ENDLABEL %ld", (long) bc));
#endif
- DUK_ASSERT(thr->catchstack_top >= 1);
-
- cat = thr->catchstack + thr->catchstack_top - 1;
- DUK_UNREF(cat);
- DUK_ASSERT(DUK_CAT_GET_TYPE(cat) == DUK_CAT_TYPE_LABEL);
- DUK_ASSERT((duk_uint_fast_t) DUK_CAT_GET_LABEL(cat) == bc);
+ act = thr->callstack_curr;
+ DUK_ASSERT(act->cat != NULL);
+ DUK_ASSERT(DUK_CAT_GET_TYPE(act->cat) == DUK_CAT_TYPE_LABEL);
+ DUK_ASSERT((duk_uint_fast_t) DUK_CAT_GET_LABEL(act->cat) == bc);
+ duk_hthread_catcher_unwind_nolexenv_norz(thr, act);
- duk_hthread_catchstack_unwind(thr, thr->catchstack_top - 1);
/* no need to unwind callstack */
break;
}
@@ -74340,384 +76421,34 @@ DUK_LOCAL DUK_NOINLINE DUK_HOT void duk__js_execute_bytecode_inner(duk_hthread *
/* XXX: move to helper, too large to be inline here */
case DUK_OP_TRYCATCH: {
- duk_context *ctx = (duk_context *) thr;
- duk_activation *act;
- duk_catcher *cat;
- duk_tval *tv1;
- duk_small_uint_fast_t a;
- duk_small_uint_fast_t bc;
-
- /* A -> flags
- * BC -> reg_catch; base register for two registers used both during
- * trycatch setup and when catch is triggered
- *
- * If DUK_BC_TRYCATCH_FLAG_CATCH_BINDING set:
- * reg_catch + 0: catch binding variable name (string).
- * Automatic declarative environment is established for
- * the duration of the 'catch' clause.
- *
- * If DUK_BC_TRYCATCH_FLAG_WITH_BINDING set:
- * reg_catch + 0: with 'target value', which is coerced to
- * an object and then used as a bindind object for an
- * environment record. The binding is initialized here, for
- * the 'try' clause.
- *
- * Note that a TRYCATCH generated for a 'with' statement has no
- * catch or finally parts.
- */
-
- /* XXX: TRYCATCH handling should be reworked to avoid creating
- * an explicit scope unless it is actually needed (e.g. function
- * instances or eval is executed inside the catch block). This
- * rework is not trivial because the compiler doesn't have an
- * intermediate representation. When the rework is done, the
- * opcode format can also be made more straightforward.
- */
-
- /* XXX: side effect handling is quite awkward here */
-
- DUK_DDD(DUK_DDDPRINT("TRYCATCH: reg_catch=%ld, have_catch=%ld, "
- "have_finally=%ld, catch_binding=%ld, with_binding=%ld (flags=0x%02lx)",
- (long) DUK_DEC_BC(ins),
- (long) (DUK_DEC_A(ins) & DUK_BC_TRYCATCH_FLAG_HAVE_CATCH ? 1 : 0),
- (long) (DUK_DEC_A(ins) & DUK_BC_TRYCATCH_FLAG_HAVE_FINALLY ? 1 : 0),
- (long) (DUK_DEC_A(ins) & DUK_BC_TRYCATCH_FLAG_CATCH_BINDING ? 1 : 0),
- (long) (DUK_DEC_A(ins) & DUK_BC_TRYCATCH_FLAG_WITH_BINDING ? 1 : 0),
- (unsigned long) DUK_DEC_A(ins)));
-
- a = DUK_DEC_A(ins);
- bc = DUK_DEC_BC(ins);
-
- /* Registers 'bc' and 'bc + 1' are written in longjmp handling
- * and if their previous values (which are temporaries) become
- * unreachable -and- have a finalizer, there'll be a function
- * call during error handling which is not supported now (GH-287).
- * Ensure that both 'bc' and 'bc + 1' have primitive values to
- * guarantee no finalizer calls in error handling. Scrubbing also
- * ensures finalizers for the previous values run here rather than
- * later. Error handling related values are also written to 'bc'
- * and 'bc + 1' but those values never become unreachable during
- * error handling, so there's no side effect problem even if the
- * error value has a finalizer.
- */
- duk_dup(ctx, bc); /* Stabilize value. */
- duk_to_undefined(ctx, bc);
- duk_to_undefined(ctx, bc + 1);
-
- /* Ensure a catchstack entry is available. One entry
- * is guaranteed even if side effects cause function
- * calls and the catchstack is shrunk because some
- * spare room is left behind by a shrink operation.
- */
- duk_hthread_catchstack_grow(thr);
-
- /* Allocate catcher and populate it. Doesn't have to
- * be fully atomic, but the catcher must be in a
- * consistent state if side effects (such as finalizer
- * calls) occur.
- */
-
- DUK_ASSERT(thr->catchstack_top + 1 <= thr->catchstack_size);
- cat = thr->catchstack + thr->catchstack_top;
- thr->catchstack_top++;
-
- cat->flags = DUK_CAT_TYPE_TCF;
- cat->h_varname = NULL;
- cat->callstack_index = thr->callstack_top - 1;
- cat->pc_base = (duk_instr_t *) curr_pc; /* pre-incremented, points to first jump slot */
- cat->idx_base = (duk_size_t) (thr->valstack_bottom - thr->valstack) + bc;
-
- if (a & DUK_BC_TRYCATCH_FLAG_HAVE_CATCH) {
- cat->flags |= DUK_CAT_FLAG_CATCH_ENABLED;
- }
- if (a & DUK_BC_TRYCATCH_FLAG_HAVE_FINALLY) {
- cat->flags |= DUK_CAT_FLAG_FINALLY_ENABLED;
- }
- if (a & DUK_BC_TRYCATCH_FLAG_CATCH_BINDING) {
- DUK_DDD(DUK_DDDPRINT("catch binding flag set to catcher"));
- cat->flags |= DUK_CAT_FLAG_CATCH_BINDING_ENABLED;
- tv1 = DUK_GET_TVAL_NEGIDX(thr, -1);
- DUK_ASSERT(DUK_TVAL_IS_STRING(tv1));
-
- /* borrowed reference; although 'tv1' comes from a register,
- * its value was loaded using LDCONST so the constant will
- * also exist and be reachable.
- */
- cat->h_varname = DUK_TVAL_GET_STRING(tv1);
- } else if (a & DUK_BC_TRYCATCH_FLAG_WITH_BINDING) {
- duk_hobjenv *env;
- duk_hobject *target;
-
- /* Delayed env initialization for activation (if needed). */
- DUK_ASSERT(thr->callstack_top >= 1);
- act = thr->callstack_curr;
- DUK_ASSERT(act != NULL);
- if (act->lex_env == NULL) {
- DUK_DDD(DUK_DDDPRINT("delayed environment initialization"));
- DUK_ASSERT(act->var_env == NULL);
-
- duk_js_init_activation_environment_records_delayed(thr, act);
- act = thr->callstack_curr; /* relookup, side effects */
- DUK_UNREF(act); /* 'act' is no longer accessed, scanbuild fix */
- }
- DUK_ASSERT(act->lex_env != NULL);
- DUK_ASSERT(act->var_env != NULL);
-
- /* Coerce 'with' target. */
- target = duk_to_hobject(ctx, -1);
- DUK_ASSERT(target != NULL);
-
- /* Create an object environment; it is not pushed
- * so avoid side effects very carefully until it is
- * referenced.
- */
- env = duk_hobjenv_alloc(thr,
- DUK_HOBJECT_FLAG_EXTENSIBLE |
- DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_OBJENV));
- DUK_ASSERT(env != NULL);
- DUK_ASSERT(DUK_HOBJECT_GET_PROTOTYPE(thr->heap, (duk_hobject *) env) == NULL);
- env->target = target; /* always provideThis=true */
- DUK_HOBJECT_INCREF(thr, target);
- env->has_this = 1;
- DUK_ASSERT_HOBJENV_VALID(env);
- DUK_DDD(DUK_DDDPRINT("environment for with binding: %!iO", env));
-
- act = thr->callstack_curr; /* relookup (side effects) */
- DUK_ASSERT(DUK_HOBJECT_GET_PROTOTYPE(thr->heap, (duk_hobject *) env) == NULL);
- DUK_ASSERT(act->lex_env != NULL);
- DUK_HOBJECT_SET_PROTOTYPE(thr->heap, (duk_hobject *) env, act->lex_env);
- act->lex_env = (duk_hobject *) env; /* Now reachable. */
- DUK_HOBJECT_INCREF(thr, (duk_hobject *) env);
- /* Net refcount change to act->lex_env is 0: incref for env's
- * prototype, decref for act->lex_env overwrite.
- */
-
- /* Set catcher lex_env active (affects unwind)
- * only when the whole setup is complete.
- */
- cat = thr->catchstack + thr->catchstack_top - 1;
- cat->flags |= DUK_CAT_FLAG_LEXENV_ACTIVE;
- } else {
- ;
- }
-
- DUK_DDD(DUK_DDDPRINT("TRYCATCH catcher: flags=0x%08lx, callstack_index=%ld, pc_base=%ld, "
- "idx_base=%ld, h_varname=%!O",
- (unsigned long) cat->flags, (long) cat->callstack_index,
- (long) cat->pc_base, (long) cat->idx_base, (duk_heaphdr *) cat->h_varname));
-
- duk_pop(ctx);
-
+ duk__handle_op_trycatch(thr, ins, curr_pc);
curr_pc += 2; /* skip jump slots */
break;
}
case DUK_OP_ENDTRY: {
- duk_catcher *cat;
- duk_tval *tv1;
-
- DUK_ASSERT(thr->catchstack_top >= 1);
- DUK_ASSERT(thr->callstack_top >= 1);
- DUK_ASSERT(thr->catchstack[thr->catchstack_top - 1].callstack_index == thr->callstack_top - 1);
-
- cat = thr->catchstack + thr->catchstack_top - 1;
-
- DUK_DDD(DUK_DDDPRINT("ENDTRY: clearing catch active flag (regardless of whether it was set or not)"));
- DUK_CAT_CLEAR_CATCH_ENABLED(cat);
-
- if (DUK_CAT_HAS_FINALLY_ENABLED(cat)) {
- DUK_DDD(DUK_DDDPRINT("ENDTRY: finally part is active, jump through 2nd jump slot with 'normal continuation'"));
-
- tv1 = thr->valstack + cat->idx_base;
- DUK_ASSERT(tv1 >= thr->valstack && tv1 < thr->valstack_top);
- DUK_TVAL_SET_UNDEFINED_UPDREF(thr, tv1); /* side effects */
- tv1 = NULL;
-
- tv1 = thr->valstack + cat->idx_base + 1;
- DUK_ASSERT(tv1 >= thr->valstack && tv1 < thr->valstack_top);
- DUK_TVAL_SET_U32_UPDREF(thr, tv1, (duk_uint32_t) DUK_LJ_TYPE_NORMAL); /* side effects */
- tv1 = NULL;
-
- DUK_CAT_CLEAR_FINALLY_ENABLED(cat);
- } else {
- DUK_DDD(DUK_DDDPRINT("ENDTRY: no finally part, dismantle catcher, jump through 2nd jump slot (to end of statement)"));
- duk_hthread_catchstack_unwind(thr, thr->catchstack_top - 1);
- /* no need to unwind callstack */
- }
-
- curr_pc = cat->pc_base + 1;
+ curr_pc = duk__handle_op_endtry(thr, ins);
break;
}
case DUK_OP_ENDCATCH: {
- duk_activation *act;
- duk_catcher *cat;
- duk_tval *tv1;
-
- DUK_ASSERT(thr->catchstack_top >= 1);
- DUK_ASSERT(thr->callstack_top >= 1);
- DUK_ASSERT(thr->catchstack[thr->catchstack_top - 1].callstack_index == thr->callstack_top - 1);
-
- cat = thr->catchstack + thr->catchstack_top - 1;
- DUK_ASSERT(!DUK_CAT_HAS_CATCH_ENABLED(cat)); /* cleared before entering catch part */
-
- act = thr->callstack_curr;
- DUK_ASSERT(act != NULL);
-
- if (DUK_CAT_HAS_LEXENV_ACTIVE(cat)) {
- duk_hobject *prev_env;
-
- /* 'with' binding has no catch clause, so can't be here unless a normal try-catch */
- DUK_ASSERT(DUK_CAT_HAS_CATCH_BINDING_ENABLED(cat));
- DUK_ASSERT(act->lex_env != NULL);
-
- DUK_DDD(DUK_DDDPRINT("ENDCATCH: popping catcher part lexical environment"));
-
- prev_env = act->lex_env;
- DUK_ASSERT(prev_env != NULL);
- act->lex_env = DUK_HOBJECT_GET_PROTOTYPE(thr->heap, prev_env);
- DUK_CAT_CLEAR_LEXENV_ACTIVE(cat);
- DUK_HOBJECT_INCREF(thr, act->lex_env);
- DUK_HOBJECT_DECREF(thr, prev_env); /* side effects */
- }
-
- if (DUK_CAT_HAS_FINALLY_ENABLED(cat)) {
- DUK_DDD(DUK_DDDPRINT("ENDCATCH: finally part is active, jump through 2nd jump slot with 'normal continuation'"));
-
- tv1 = thr->valstack + cat->idx_base;
- DUK_ASSERT(tv1 >= thr->valstack && tv1 < thr->valstack_top);
- DUK_TVAL_SET_UNDEFINED_UPDREF(thr, tv1); /* side effects */
- tv1 = NULL;
-
- tv1 = thr->valstack + cat->idx_base + 1;
- DUK_ASSERT(tv1 >= thr->valstack && tv1 < thr->valstack_top);
- DUK_TVAL_SET_U32_UPDREF(thr, tv1, (duk_uint32_t) DUK_LJ_TYPE_NORMAL); /* side effects */
- tv1 = NULL;
-
- DUK_CAT_CLEAR_FINALLY_ENABLED(cat);
- } else {
- DUK_DDD(DUK_DDDPRINT("ENDCATCH: no finally part, dismantle catcher, jump through 2nd jump slot (to end of statement)"));
- duk_hthread_catchstack_unwind(thr, thr->catchstack_top - 1);
- /* no need to unwind callstack */
- }
-
- curr_pc = cat->pc_base + 1;
+ duk__handle_op_endcatch(thr, ins);
break;
}
case DUK_OP_ENDFIN: {
- duk_context *ctx = (duk_context *) thr;
- duk_catcher *cat;
- duk_tval *tv1;
- duk_small_uint_t cont_type;
- duk_small_uint_t ret_result;
-
/* Sync and NULL early. */
DUK__SYNC_AND_NULL_CURR_PC();
- DUK_ASSERT(thr->catchstack_top >= 1);
- DUK_ASSERT(thr->callstack_top >= 1);
- DUK_ASSERT(thr->catchstack[thr->catchstack_top - 1].callstack_index == thr->callstack_top - 1);
-
- cat = thr->catchstack + thr->catchstack_top - 1;
-
- /* CATCH flag may be enabled or disabled here; it may be enabled if
- * the statement has a catch block but the try block does not throw
- * an error.
- */
- DUK_ASSERT(!DUK_CAT_HAS_FINALLY_ENABLED(cat)); /* cleared before entering finally */
- /* XXX: assert idx_base */
-
- DUK_DDD(DUK_DDDPRINT("ENDFIN: completion value=%!T, type=%!T",
- (duk_tval *) (thr->valstack + cat->idx_base + 0),
- (duk_tval *) (thr->valstack + cat->idx_base + 1)));
-
- tv1 = thr->valstack + cat->idx_base + 1; /* type */
- DUK_ASSERT(DUK_TVAL_IS_NUMBER(tv1));
- cont_type = (duk_small_uint_t) DUK_TVAL_GET_NUMBER(tv1);
-
- switch (cont_type) {
- case DUK_LJ_TYPE_NORMAL: {
- DUK_DDD(DUK_DDDPRINT("ENDFIN: finally part finishing with 'normal' (non-abrupt) completion -> "
- "dismantle catcher, resume execution after ENDFIN"));
- duk_hthread_catchstack_unwind(thr, thr->catchstack_top - 1);
- /* no need to unwind callstack */
- goto restart_execution;
- }
- case DUK_LJ_TYPE_RETURN: {
- DUK_DDD(DUK_DDDPRINT("ENDFIN: finally part finishing with 'return' complation -> dismantle "
- "catcher, handle return, lj.value1=%!T", thr->valstack + cat->idx_base));
-
- /* Not necessary to unwind catchstack: return handling will
- * do it. The finally flag of 'cat' is no longer set. The
- * catch flag may be set, but it's not checked by return handling.
- */
- DUK_ASSERT(!DUK_CAT_HAS_FINALLY_ENABLED(cat)); /* cleared before entering finally */
-#if 0
- duk_hthread_catchstack_unwind(thr, thr->catchstack_top - 1);
-#endif
-
- duk_push_tval(ctx, thr->valstack + cat->idx_base);
- ret_result = duk__handle_return(thr,
- entry_thread,
- entry_callstack_top);
- if (ret_result == DUK__RETHAND_RESTART) {
- goto restart_execution;
- }
- DUK_ASSERT(ret_result == DUK__RETHAND_FINISHED);
-
- DUK_DDD(DUK_DDDPRINT("exiting executor after ENDFIN and RETURN (pseudo) longjmp type"));
+ if (duk__handle_op_endfin(thr, ins, entry_act) != 0) {
return;
}
- case DUK_LJ_TYPE_BREAK:
- case DUK_LJ_TYPE_CONTINUE: {
- duk_uint_t label_id;
- duk_small_uint_t lj_type;
-
- /* Not necessary to unwind catchstack: break/continue
- * handling will do it. The finally flag of 'cat' is
- * no longer set. The catch flag may be set, but it's
- * not checked by break/continue handling.
- */
-#if 0
- duk_hthread_catchstack_unwind(thr, thr->catchstack_top - 1);
-#endif
-
- tv1 = thr->valstack + cat->idx_base;
- DUK_ASSERT(DUK_TVAL_IS_NUMBER(tv1));
-#if defined(DUK_USE_FASTINT)
- DUK_ASSERT(DUK_TVAL_IS_FASTINT(tv1));
- label_id = (duk_small_uint_t) DUK_TVAL_GET_FASTINT_U32(tv1);
-#else
- label_id = (duk_small_uint_t) DUK_TVAL_GET_NUMBER(tv1);
-#endif
- lj_type = cont_type;
- duk__handle_break_or_continue(thr, label_id, lj_type);
- goto restart_execution;
- }
- default: {
- DUK_DDD(DUK_DDDPRINT("ENDFIN: finally part finishing with abrupt completion, lj_type=%ld -> "
- "dismantle catcher, re-throw error",
- (long) cont_type));
-
- duk_push_tval(ctx, thr->valstack + cat->idx_base);
-
- duk_err_setup_ljstate1(thr, (duk_small_int_t) cont_type, thr->valstack + cat->idx_base);
- /* No debugger Throw notify check on purpose (rethrow). */
-
- DUK_ASSERT(thr->heap->lj.jmpbuf_ptr != NULL); /* always in executor */
- duk_err_longjmp(thr);
- DUK_UNREACHABLE();
- }
- }
- /* Must restart in all cases because we NULLed thr->ptr_curr_pc. */
- DUK_UNREACHABLE();
- break;
+ /* Must restart because we NULLed out curr_pc. */
+ goto restart_execution;
}
case DUK_OP_THROW: {
- duk_context *ctx = (duk_context *) thr;
duk_small_uint_fast_t bc = DUK_DEC_BC(ins);
/* Note: errors are augmented when they are created, not
@@ -74731,16 +76462,16 @@ DUK_LOCAL DUK_NOINLINE DUK_HOT void duk__js_execute_bytecode_inner(duk_hthread *
*/
DUK__SYNC_AND_NULL_CURR_PC();
- duk_dup(ctx, (duk_idx_t) bc);
+ duk_dup(thr, (duk_idx_t) bc);
DUK_DDD(DUK_DDDPRINT("THROW ERROR (BYTECODE): %!dT (before throw augment)",
- (duk_tval *) duk_get_tval(ctx, -1)));
+ (duk_tval *) duk_get_tval(thr, -1)));
#if defined(DUK_USE_AUGMENT_ERROR_THROW)
duk_err_augment_error_throw(thr);
DUK_DDD(DUK_DDDPRINT("THROW ERROR (BYTECODE): %!dT (after throw augment)",
- (duk_tval *) duk_get_tval(ctx, -1)));
+ (duk_tval *) duk_get_tval(thr, -1)));
#endif
- duk_err_setup_ljstate1(thr, DUK_LJ_TYPE_THROW, DUK_GET_TVAL_NEGIDX(ctx, -1));
+ duk_err_setup_ljstate1(thr, DUK_LJ_TYPE_THROW, DUK_GET_TVAL_NEGIDX(thr, -1));
#if defined(DUK_USE_DEBUGGER_SUPPORT)
duk_err_check_debugger_integration(thr);
#endif
@@ -74766,9 +76497,9 @@ DUK_LOCAL DUK_NOINLINE DUK_HOT void duk__js_execute_bytecode_inner(duk_hthread *
*/
#if defined(DUK_USE_PREFER_SIZE)
- duk_dup((duk_context *) thr, a);
- duk_replace((duk_context *) thr, bc);
- duk_to_undefined((duk_context *) thr, bc + 1);
+ duk_dup(thr, (duk_idx_t) a);
+ duk_replace(thr, (duk_idx_t) bc);
+ duk_to_undefined(thr, (duk_idx_t) (bc + 1));
#else
duk_tval *tv1;
duk_tval *tv2;
@@ -74790,129 +76521,48 @@ DUK_LOCAL DUK_NOINLINE DUK_HOT void duk__js_execute_bytecode_inner(duk_hthread *
break;
}
- case DUK_OP_EVALCALL: {
- /* Eval call or a normal call made using the identifier 'eval'.
- * Eval calls are never handled as tail calls for simplicity.
- */
- duk_context *ctx = (duk_context *) thr;
- duk_small_uint_fast_t nargs;
- duk_uint_fast_t idx;
- duk_idx_t num_stack_args;
- duk_small_uint_t call_flags;
- duk_tval *tv_func;
- duk_hobject *obj_func;
-#if !defined(DUK_USE_EXEC_FUN_LOCAL)
- duk_hcompfunc *fun;
-#endif
-
- /* Technically we should also check for the possibility of
- * a pure Ecmascript-to-Ecmascript call: while built-in eval()
- * is native, it's possible for the 'eval' identifier to be
- * shadowed. In practice that would be rare and optimizing the
- * C call stack for that case is a bit pointless.
- */
- nargs = (duk_small_uint_fast_t) DUK_DEC_A(ins);
- idx = (duk_uint_fast_t) DUK_DEC_BC(ins);
- duk_set_top(ctx, (duk_idx_t) (idx + nargs + 2)); /* [ ... func this arg1 ... argN ] */
-
- call_flags = 0;
- tv_func = DUK_GET_TVAL_POSIDX(ctx, idx);
- if (DUK_TVAL_IS_OBJECT(tv_func)) {
- obj_func = DUK_TVAL_GET_OBJECT(tv_func);
- DUK_ASSERT(obj_func != NULL);
- if (DUK_HOBJECT_IS_NATFUNC(obj_func) &&
- ((duk_hnatfunc *) obj_func)->func == duk_bi_global_object_eval) {
- DUK_DDD(DUK_DDDPRINT("call target is eval, call identifier was 'eval' -> direct eval"));
- call_flags |= DUK_CALL_FLAG_DIRECT_EVAL;
- }
- }
- num_stack_args = nargs;
- duk_handle_call_unprotected(thr, num_stack_args, call_flags);
-
-#if !defined(DUK_USE_EXEC_FUN_LOCAL)
- fun = DUK__FUN();
-#endif
- duk_set_top(ctx, (duk_idx_t) fun->nregs);
- break;
- }
-
- case DUK_OP_CALL:
- case DUK_OP_TAILCALL: {
- /* DUK_OP_CALL: plain call, not tailcall compatible.
- *
- * DUK_OP_TAILCALL: plain call which is tailcall
- * compatible. Tail call may not be possible due
- * to e.g. target not being an Ecmascript function.
- *
- * Not a direct eval call. Indirect eval calls don't
- * need special handling here.
- */
+ /* XXX: in some cases it's faster NOT to reuse the value
+ * stack but rather copy the arguments on top of the stack
+ * (mainly when the calling value stack is large and the value
+ * stack resize would be large).
+ */
- /* To determine whether to use an optimized Ecmascript-to-Ecmascript
- * call, we need to know whether the final, non-bound function is an
- * Ecmascript function. Current implementation is to first try an
- * Ecma-to-Ecma call setup which also resolves the bound function
- * chain. The setup attempt overwrites call target at DUK__REGP(idx)
- * and may also fudge the argument list. However, it won't resolve
- * the effective 'this' binding if the setup fails. This is somewhat
- * awkward, and the two call setup code paths should be merged.
+ case DUK_OP_CALL0:
+ case DUK_OP_CALL1:
+ case DUK_OP_CALL2:
+ case DUK_OP_CALL3:
+ case DUK_OP_CALL4:
+ case DUK_OP_CALL5:
+ case DUK_OP_CALL6:
+ case DUK_OP_CALL7: {
+ /* Opcode packs 4 flag bits: 1 for indirect, 3 map
+ * 1:1 to three lowest call handling flags.
*
- * If an Ecma-to-Ecma call is not possible, the actual call handling
- * will do another (unnecessary) attempt to resolve the bound function.
+ * A -> nargs or register with nargs (indirect)
+ * BC -> base register for call (base -> func, base+1 -> this, base+2 -> arg1 ... base+2+N-1 -> argN)
*/
- duk_context *ctx = (duk_context *) thr;
- duk_small_uint_fast_t nargs;
- duk_uint_fast_t idx;
- duk_idx_t num_stack_args;
+ duk_idx_t nargs;
+ duk_idx_t idx;
duk_small_uint_t call_flags;
#if !defined(DUK_USE_EXEC_FUN_LOCAL)
duk_hcompfunc *fun;
#endif
- /* A -> nargs
- * BC -> base register for call (base -> func, base+1 -> this, base+2 -> arg1 ... base+2+N-1 -> argN)
- */
+ DUK_ASSERT((DUK_OP_CALL0 & 0x0fU) == 0);
+ DUK_ASSERT((ins & DUK_BC_CALL_FLAG_INDIRECT) == 0);
- /* XXX: in some cases it's faster NOT to reuse the value
- * stack but rather copy the arguments on top of the stack
- * (mainly when the calling value stack is large and the value
- * stack resize would be large). See DUK_OP_NEW.
- */
+ nargs = (duk_idx_t) DUK_DEC_A(ins);
+ call_flags = (ins & 0x07U) | DUK_CALL_FLAG_ALLOW_ECMATOECMA;
+ idx = (duk_idx_t) DUK_DEC_BC(ins);
- nargs = (duk_small_uint_fast_t) DUK_DEC_A(ins);
- idx = (duk_uint_fast_t) DUK_DEC_BC(ins);
- duk_set_top(ctx, (duk_idx_t) (idx + nargs + 2)); /* [ ... func this arg1 ... argN ] */
-
- /* DUK_OP_CALL and DUK_OP_TAILCALL are consecutive
- * which allows a simple bit test.
- */
- DUK_ASSERT((DUK_OP_CALL & 0x01) == 0);
- DUK_ASSERT((DUK_OP_TAILCALL & 0x01) == 1);
- call_flags = (ins & (1UL << DUK_BC_SHIFT_OP)) ? DUK_CALL_FLAG_IS_TAILCALL : 0;
-
- num_stack_args = nargs;
- if (duk_handle_ecma_call_setup(thr, num_stack_args, call_flags)) {
- /* Ecma-to-ecma call possible, may or may not be a tail call.
- * Avoid C recursion by being clever.
- */
- DUK_DDD(DUK_DDDPRINT("ecma-to-ecma call setup possible, restart execution"));
- /* curr_pc synced by duk_handle_ecma_call_setup() */
+ if (duk__executor_handle_call(thr, idx, nargs, call_flags)) {
+ /* curr_pc synced by duk_handle_call_unprotected() */
+ DUK_ASSERT(thr->ptr_curr_pc == NULL);
goto restart_execution;
}
-
- /* Recompute argument count: bound function handling may have shifted. */
- num_stack_args = duk_get_top(ctx) - (idx + 2);
- DUK_DDD(DUK_DDDPRINT("recomputed arg count: %ld\n", (long) num_stack_args));
-
- /* Target is either a lightfunc or a function object.
- * We don't need to check for eval handling here: the
- * call may be an indirect eval ('myEval("something")')
- * but that requires no special handling.
- */
-
- duk_handle_call_unprotected(thr, num_stack_args, 0 /*call_flags*/);
+ DUK_ASSERT(thr->ptr_curr_pc != NULL);
/* duk_js_call.c is required to restore the stack reserve
* so we only need to reset the top.
@@ -74920,97 +76570,103 @@ DUK_LOCAL DUK_NOINLINE DUK_HOT void duk__js_execute_bytecode_inner(duk_hthread *
#if !defined(DUK_USE_EXEC_FUN_LOCAL)
fun = DUK__FUN();
#endif
- duk_set_top(ctx, (duk_idx_t) fun->nregs);
+ duk_set_top_unsafe(thr, (duk_idx_t) fun->nregs);
/* No need to reinit setjmp() catchpoint, as call handling
* will store and restore our state.
- */
-
- /* When debugger is enabled, we need to recheck the activation
+ *
+ * When debugger is enabled, we need to recheck the activation
* status after returning. This is now handled by call handling
* and heap->dbg_force_restart.
*/
break;
}
- case DUK_OP_NEW: {
- duk_context *ctx = (duk_context *) thr;
- duk_small_uint_fast_t a = DUK_DEC_A(ins);
- duk_small_uint_fast_t bc = DUK_DEC_BC(ins);
-#if defined(DUK_USE_EXEC_PREFER_SIZE)
+ case DUK_OP_CALL8:
+ case DUK_OP_CALL9:
+ case DUK_OP_CALL10:
+ case DUK_OP_CALL11:
+ case DUK_OP_CALL12:
+ case DUK_OP_CALL13:
+ case DUK_OP_CALL14:
+ case DUK_OP_CALL15: {
+ /* Indirect variant. */
+ duk_uint_fast_t nargs;
+ duk_idx_t idx;
+ duk_small_uint_t call_flags;
#if !defined(DUK_USE_EXEC_FUN_LOCAL)
duk_hcompfunc *fun;
#endif
-#else
- duk_small_uint_fast_t count;
- duk_tval *tv_src;
-#endif
-
- /* A -> num args (N)
- * BC -> target register and start reg: constructor, arg1, ..., argN
- */
-
- /* duk_new() will call the constuctor using duk_handle_call().
- * A constructor call prevents a yield from inside the constructor,
- * even if the constructor is an Ecmascript function.
- */
- /* Don't need to sync curr_pc here; duk_new() will do that
- * when it augments the created error.
- */
+ DUK_ASSERT((DUK_OP_CALL0 & 0x0fU) == 0);
+ DUK_ASSERT((ins & DUK_BC_CALL_FLAG_INDIRECT) != 0);
-#if defined(DUK_USE_EXEC_PREFER_SIZE)
- /* This alternative relies on our being allowed to trash anything
- * above 'bc' so we can just reuse the argument registers which
- * means smaller value stack use. Footprint is a bit smaller.
- */
- duk_set_top(ctx, (duk_idx_t) (bc + a + 1));
- duk_new(ctx, (duk_idx_t) a); /* [... constructor arg1 ... argN] -> [retval] */
+ nargs = (duk_uint_fast_t) DUK_DEC_A(ins);
+ DUK__LOOKUP_INDIRECT(nargs);
+ call_flags = (ins & 0x07U) | DUK_CALL_FLAG_ALLOW_ECMATOECMA;
+ idx = (duk_idx_t) DUK_DEC_BC(ins);
- /* The return value is already in its correct place at the stack,
- * i.e. it has replaced the 'constructor' at index bc. Just reset
- * top and we're done.
- */
+ if (duk__executor_handle_call(thr, idx, (duk_idx_t) nargs, call_flags)) {
+ DUK_ASSERT(thr->ptr_curr_pc == NULL);
+ goto restart_execution;
+ }
+ DUK_ASSERT(thr->ptr_curr_pc != NULL);
#if !defined(DUK_USE_EXEC_FUN_LOCAL)
fun = DUK__FUN();
#endif
- duk_set_top(ctx, (duk_idx_t) fun->nregs);
-#else /* DUK_USE_EXEC_PREFER_SIZE */
- /* Faster alternative is to duplicate the values to avoid a resize.
- * This depends on the relative size between the value stack and
- * the argument count, though.
- */
- count = a + 1;
- duk_require_stack(ctx, count);
- tv_src = DUK_GET_TVAL_POSIDX(ctx, bc);
- duk__push_tvals_incref_only(thr, tv_src, count);
- duk_new(ctx, (duk_idx_t) a); /* [... constructor arg1 ... argN] -> [retval] */
- duk_replace(ctx, bc);
-#endif /* DUK_USE_EXEC_PREFER_SIZE */
-
- /* When debugger is enabled, we need to recheck the activation
- * status after returning. This is now handled by call handling
- * and heap->dbg_force_restart.
- */
+ duk_set_top_unsafe(thr, (duk_idx_t) fun->nregs);
break;
}
case DUK_OP_NEWOBJ: {
- duk_context *ctx = (duk_context *) thr;
- duk_push_object(ctx);
+ duk_push_object(thr);
+#if defined(DUK_USE_ASSERTIONS)
+ {
+ duk_hobject *h;
+ h = duk_require_hobject(thr, -1);
+ DUK_ASSERT(DUK_HOBJECT_GET_ESIZE(h) == 0);
+ DUK_ASSERT(DUK_HOBJECT_GET_ENEXT(h) == 0);
+ DUK_ASSERT(DUK_HOBJECT_GET_ASIZE(h) == 0);
+ DUK_ASSERT(DUK_HOBJECT_GET_HSIZE(h) == 0);
+ }
+#endif
+#if !defined(DUK_USE_PREFER_SIZE)
+ /* XXX: could do a direct props realloc, but need hash size */
+ duk_hobject_resize_entrypart(thr, duk_known_hobject(thr, -1), DUK_DEC_A(ins));
+#endif
DUK__REPLACE_TOP_BC_BREAK();
}
case DUK_OP_NEWARR: {
- duk_context *ctx = (duk_context *) thr;
- duk_push_array(ctx);
+ duk_push_array(thr);
+#if defined(DUK_USE_ASSERTIONS)
+ {
+ duk_hobject *h;
+ h = duk_require_hobject(thr, -1);
+ DUK_ASSERT(DUK_HOBJECT_GET_ESIZE(h) == 0);
+ DUK_ASSERT(DUK_HOBJECT_GET_ENEXT(h) == 0);
+ DUK_ASSERT(DUK_HOBJECT_GET_ASIZE(h) == 0);
+ DUK_ASSERT(DUK_HOBJECT_GET_HSIZE(h) == 0);
+ DUK_ASSERT(DUK_HOBJECT_HAS_ARRAY_PART(h));
+ }
+#endif
+#if !defined(DUK_USE_PREFER_SIZE)
+ duk_hobject_realloc_props(thr,
+ duk_known_hobject(thr, -1),
+ 0 /*new_e_size*/,
+ DUK_DEC_A(ins) /*new_a_size*/,
+ 0 /*new_h_size*/,
+ 0 /*abandon_array*/);
+#if 0
+ duk_hobject_resize_arraypart(thr, duk_known_hobject(thr, -1), DUK_DEC_A(ins));
+#endif
+#endif
DUK__REPLACE_TOP_BC_BREAK();
}
case DUK_OP_MPUTOBJ:
case DUK_OP_MPUTOBJI: {
- duk_context *ctx = (duk_context *) thr;
duk_idx_t obj_idx;
duk_uint_fast_t idx, idx_end;
duk_small_uint_fast_t count;
@@ -75023,11 +76679,11 @@ DUK_LOCAL DUK_NOINLINE DUK_HOT void duk__js_execute_bytecode_inner(duk_hthread *
*/
obj_idx = DUK_DEC_A(ins);
- DUK_ASSERT(duk_is_object(ctx, obj_idx));
+ DUK_ASSERT(duk_is_object(thr, obj_idx));
idx = (duk_uint_fast_t) DUK_DEC_B(ins);
if (DUK_DEC_OP(ins) == DUK_OP_MPUTOBJI) {
- DUK__LOOKUP_INDIRECT_INDEX(idx);
+ DUK__LOOKUP_INDIRECT(idx);
}
count = (duk_small_uint_fast_t) DUK_DEC_C(ins);
@@ -75035,7 +76691,7 @@ DUK_LOCAL DUK_NOINLINE DUK_HOT void duk__js_execute_bytecode_inner(duk_hthread *
idx_end = idx + count;
#if defined(DUK_USE_EXEC_INDIRECT_BOUND_CHECK)
- if (DUK_UNLIKELY(idx_end > (duk_uint_fast_t) duk_get_top(ctx))) {
+ if (DUK_UNLIKELY(idx_end > (duk_uint_fast_t) duk_get_top(thr))) {
/* XXX: use duk_is_valid_index() instead? */
/* XXX: improve check; check against nregs, not against top */
DUK__INTERNAL_ERROR("MPUTOBJ out of bounds");
@@ -75053,9 +76709,9 @@ DUK_LOCAL DUK_NOINLINE DUK_HOT void duk__js_execute_bytecode_inner(duk_hthread *
*/
do {
/* XXX: faster initialization (direct access or better primitives) */
- duk_dup(ctx, idx);
- duk_dup(ctx, idx + 1);
- duk_def_prop(ctx, obj_idx, DUK_DEFPROP_HAVE_VALUE |
+ duk_dup(thr, (duk_idx_t) idx);
+ duk_dup(thr, (duk_idx_t) (idx + 1));
+ duk_def_prop(thr, obj_idx, DUK_DEFPROP_HAVE_VALUE |
DUK_DEFPROP_FORCE |
DUK_DEFPROP_SET_WRITABLE |
DUK_DEFPROP_SET_ENUMERABLE |
@@ -75067,43 +76723,12 @@ DUK_LOCAL DUK_NOINLINE DUK_HOT void duk__js_execute_bytecode_inner(duk_hthread *
case DUK_OP_INITSET:
case DUK_OP_INITGET: {
- duk_context *ctx = (duk_context *) thr;
- duk_bool_t is_set = (op == DUK_OP_INITSET);
- duk_uint_fast_t idx;
- duk_uint_t defprop_flags;
-
- /* A -> object register (acts as a source)
- * BC -> BC+0 contains key, BC+1 closure (value)
- */
-
- /* INITSET/INITGET are only used to initialize object literal keys.
- * There may be a previous propery in ES2015 because duplicate property
- * names are allowed.
- */
-
- /* This could be made more optimal by accessing internals directly. */
-
- idx = (duk_uint_fast_t) DUK_DEC_BC(ins);
- duk_dup(ctx, (duk_idx_t) (idx + 0)); /* key */
- duk_dup(ctx, (duk_idx_t) (idx + 1)); /* getter/setter */
- if (is_set) {
- defprop_flags = DUK_DEFPROP_HAVE_SETTER |
- DUK_DEFPROP_FORCE |
- DUK_DEFPROP_SET_ENUMERABLE |
- DUK_DEFPROP_SET_CONFIGURABLE;
- } else {
- defprop_flags = DUK_DEFPROP_HAVE_GETTER |
- DUK_DEFPROP_FORCE |
- DUK_DEFPROP_SET_ENUMERABLE |
- DUK_DEFPROP_SET_CONFIGURABLE;
- }
- duk_def_prop(ctx, (duk_idx_t) DUK_DEC_A(ins), defprop_flags);
+ duk__handle_op_initset_initget(thr, ins);
break;
}
case DUK_OP_MPUTARR:
case DUK_OP_MPUTARRI: {
- duk_context *ctx = (duk_context *) thr;
duk_idx_t obj_idx;
duk_uint_fast_t idx, idx_end;
duk_small_uint_fast_t count;
@@ -75117,11 +76742,11 @@ DUK_LOCAL DUK_NOINLINE DUK_HOT void duk__js_execute_bytecode_inner(duk_hthread *
*/
obj_idx = DUK_DEC_A(ins);
- DUK_ASSERT(duk_is_object(ctx, obj_idx));
+ DUK_ASSERT(duk_is_object(thr, obj_idx));
idx = (duk_uint_fast_t) DUK_DEC_B(ins);
if (DUK_DEC_OP(ins) == DUK_OP_MPUTARRI) {
- DUK__LOOKUP_INDIRECT_INDEX(idx);
+ DUK__LOOKUP_INDIRECT(idx);
}
count = (duk_small_uint_fast_t) DUK_DEC_C(ins);
@@ -75129,7 +76754,7 @@ DUK_LOCAL DUK_NOINLINE DUK_HOT void duk__js_execute_bytecode_inner(duk_hthread *
idx_end = idx + count;
#if defined(DUK_USE_EXEC_INDIRECT_BOUND_CHECK)
- if (idx_end > (duk_uint_fast_t) duk_get_top(ctx)) {
+ if (idx_end > (duk_uint_fast_t) duk_get_top(thr)) {
/* XXX: use duk_is_valid_index() instead? */
/* XXX: improve check; check against nregs, not against top */
DUK__INTERNAL_ERROR("MPUTARR out of bounds");
@@ -75159,8 +76784,8 @@ DUK_LOCAL DUK_NOINLINE DUK_HOT void duk__js_execute_bytecode_inner(duk_hthread *
* and finally set 'length' manually in the end (as already happens now).
*/
- duk_dup(ctx, idx);
- duk_xdef_prop_index_wec(ctx, obj_idx, arr_idx);
+ duk_dup(thr, (duk_idx_t) idx);
+ duk_xdef_prop_index_wec(thr, obj_idx, arr_idx);
idx++;
arr_idx++;
@@ -75197,73 +76822,12 @@ DUK_LOCAL DUK_NOINLINE DUK_HOT void duk__js_execute_bytecode_inner(duk_hthread *
}
case DUK_OP_INITENUM: {
- duk_context *ctx = (duk_context *) thr;
- duk_small_uint_fast_t b = DUK_DEC_B(ins);
- duk_small_uint_fast_t c = DUK_DEC_C(ins);
-
- /*
- * Enumeration semantics come from for-in statement, E5 Section 12.6.4.
- * If called with 'null' or 'undefined', this opcode returns 'null' as
- * the enumerator, which is special cased in NEXTENUM. This simplifies
- * the compiler part
- */
-
- /* B -> register for writing enumerator object
- * C -> value to be enumerated (register)
- */
-
- if (duk_is_null_or_undefined(ctx, (duk_idx_t) c)) {
- duk_push_null(ctx);
- duk_replace(ctx, (duk_idx_t) b);
- } else {
- duk_dup(ctx, (duk_idx_t) c);
- duk_to_object(ctx, -1);
- duk_hobject_enumerator_create(ctx, 0 /*enum_flags*/); /* [ ... val ] --> [ ... enum ] */
- duk_replace(ctx, (duk_idx_t) b);
- }
+ duk__handle_op_initenum(thr, ins);
break;
}
case DUK_OP_NEXTENUM: {
- duk_context *ctx = (duk_context *) thr;
- duk_small_uint_fast_t b = DUK_DEC_B(ins);
- duk_small_uint_fast_t c = DUK_DEC_C(ins);
-
- /*
- * NEXTENUM checks whether the enumerator still has unenumerated
- * keys. If so, the next key is loaded to the target register
- * and the next instruction is skipped. Otherwise the next instruction
- * will be executed, jumping out of the enumeration loop.
- */
-
- /* B -> target register for next key
- * C -> enum register
- */
-
- DUK_DDD(DUK_DDDPRINT("NEXTENUM: b->%!T, c->%!T",
- (duk_tval *) duk_get_tval(ctx, (duk_idx_t) b),
- (duk_tval *) duk_get_tval(ctx, (duk_idx_t) c)));
-
- if (duk_is_object(ctx, (duk_idx_t) c)) {
- /* XXX: assert 'c' is an enumerator */
- duk_dup(ctx, (duk_idx_t) c);
- if (duk_hobject_enumerator_next(ctx, 0 /*get_value*/)) {
- /* [ ... enum ] -> [ ... next_key ] */
- DUK_DDD(DUK_DDDPRINT("enum active, next key is %!T, skip jump slot ",
- (duk_tval *) duk_get_tval(ctx, -1)));
- curr_pc++;
- } else {
- /* [ ... enum ] -> [ ... ] */
- DUK_DDD(DUK_DDDPRINT("enum finished, execute jump slot"));
- DUK_ASSERT(DUK_TVAL_IS_UNDEFINED(thr->valstack_top)); /* valstack policy */
- thr->valstack_top++;
- }
- duk_replace(ctx, (duk_idx_t) b);
- } else {
- /* 'null' enumerator case -> behave as with an empty enumerator */
- DUK_ASSERT(duk_is_null(ctx, (duk_idx_t) c));
- DUK_DDD(DUK_DDDPRINT("enum is null, execute jump slot"));
- }
+ curr_pc += duk__handle_op_nextenum(thr, ins);
break;
}
@@ -75296,7 +76860,9 @@ DUK_LOCAL DUK_NOINLINE DUK_HOT void duk__js_execute_bytecode_inner(duk_hthread *
}
case DUK_OP_NOP: {
- /* nop */
+ /* Nop, ignored, but ABC fields may carry a value e.g.
+ * for indirect opcode handling.
+ */
break;
}
@@ -75305,6 +76871,46 @@ DUK_LOCAL DUK_NOINLINE DUK_HOT void duk__js_execute_bytecode_inner(duk_hthread *
break;
}
+#if defined(DUK_USE_ES6)
+ case DUK_OP_NEWTARGET: {
+ /* https://www.ecma-international.org/ecma-262/6.0/#sec-meta-properties-runtime-semantics-evaluation
+ * https://www.ecma-international.org/ecma-262/6.0/#sec-getnewtarget
+ *
+ * No newTarget support now, so as a first approximation
+ * use the resolved (non-bound) target function.
+ */
+ /* XXX: C API: push_new_target()? */
+ duk_activation *act;
+
+ act = thr->callstack_curr;
+ DUK_ASSERT(act != NULL);
+
+ /* Check CONSTRUCT flag from current function, or if running
+ * direct eval, from a non-direct-eval parent (with possibly
+ * more than one nested direct eval). An alternative to this
+ * would be to store [[NewTarget]] as a hidden symbol of the
+ * lexical scope, and then just look up that variable.
+ */
+ for (;;) {
+ if (act == NULL) {
+ duk_push_undefined(thr);
+ break;
+ }
+ if (act->flags & DUK_ACT_FLAG_CONSTRUCT) {
+ duk_push_tval(thr, &act->tv_func);
+ break;
+ } else if (act->flags & DUK_ACT_FLAG_DIRECT_EVAL) {
+ act = act->parent;
+ } else {
+ duk_push_undefined(thr);
+ break;
+ }
+ }
+
+ DUK__REPLACE_TOP_BC_BREAK();
+ }
+#endif /* DUK_USE_ES6 */
+
#if !defined(DUK_USE_EXEC_PREFER_SIZE)
#if !defined(DUK_USE_ES7_EXP_OPERATOR)
case DUK_OP_EXP_RR:
@@ -75312,24 +76918,16 @@ DUK_LOCAL DUK_NOINLINE DUK_HOT void duk__js_execute_bytecode_inner(duk_hthread *
case DUK_OP_EXP_RC:
case DUK_OP_EXP_CC:
#endif
- case DUK_OP_UNUSED194:
- case DUK_OP_UNUSED195:
- case DUK_OP_UNUSED196:
- case DUK_OP_UNUSED197:
- case DUK_OP_UNUSED198:
- case DUK_OP_UNUSED199:
- case DUK_OP_UNUSED200:
- case DUK_OP_UNUSED201:
- case DUK_OP_UNUSED202:
- case DUK_OP_UNUSED203:
- case DUK_OP_UNUSED204:
- case DUK_OP_UNUSED205:
- case DUK_OP_UNUSED206:
+#if !defined(DUK_USE_ES6)
+ case DUK_OP_NEWTARGET:
+#endif
+#if !defined(DUK_USE_VERBOSE_ERRORS)
+ case DUK_OP_GETPROPC_RR:
+ case DUK_OP_GETPROPC_CR:
+ case DUK_OP_GETPROPC_RC:
+ case DUK_OP_GETPROPC_CC:
+#endif
case DUK_OP_UNUSED207:
- case DUK_OP_UNUSED208:
- case DUK_OP_UNUSED209:
- case DUK_OP_UNUSED210:
- case DUK_OP_UNUSED211:
case DUK_OP_UNUSED212:
case DUK_OP_UNUSED213:
case DUK_OP_UNUSED214:
@@ -75381,7 +76979,7 @@ DUK_LOCAL DUK_NOINLINE DUK_HOT void duk__js_execute_bytecode_inner(duk_hthread *
* a small detail and obviously compiler dependent.
*/
/* default: clause omitted on purpose */
-#else
+#else /* DUK_USE_EXEC_PREFER_SIZE */
default:
#endif /* DUK_USE_EXEC_PREFER_SIZE */
{
@@ -75433,6 +77031,7 @@ DUK_LOCAL DUK_NOINLINE DUK_HOT void duk__js_execute_bytecode_inner(duk_hthread *
#undef DUK__DELPROP_BODY
#undef DUK__EQ_BODY
#undef DUK__FUN
+#undef DUK__GETPROPC_BODY
#undef DUK__GETPROP_BODY
#undef DUK__GE_BODY
#undef DUK__GT_BODY
@@ -75445,13 +77044,14 @@ DUK_LOCAL DUK_NOINLINE DUK_HOT void duk__js_execute_bytecode_inner(duk_hthread *
#undef DUK__LE_BODY
#undef DUK__LONGJMP_RESTART
#undef DUK__LONGJMP_RETHROW
-#undef DUK__LOOKUP_INDIRECT_INDEX
+#undef DUK__LOOKUP_INDIRECT
#undef DUK__LT_BODY
#undef DUK__MASK_A
#undef DUK__MASK_B
#undef DUK__MASK_BC
#undef DUK__MASK_C
#undef DUK__NEQ_BODY
+#undef DUK__NOINLINE_PERF
#undef DUK__PUTPROP_BODY
#undef DUK__RCBIT_B
#undef DUK__RCBIT_C
@@ -75633,11 +77233,10 @@ DUK_INTERNAL duk_bool_t duk_js_toboolean(duk_tval *tv) {
/* E5 Section 9.3.1 */
DUK_LOCAL duk_double_t duk__tonumber_string_raw(duk_hthread *thr) {
- duk_context *ctx = (duk_context *) thr;
duk_small_uint_t s2n_flags;
duk_double_t d;
- DUK_ASSERT(duk_is_string(ctx, -1));
+ DUK_ASSERT(duk_is_string(thr, -1));
/* Quite lenient, e.g. allow empty as zero, but don't allow trailing
* garbage.
@@ -75656,11 +77255,11 @@ DUK_LOCAL duk_double_t duk__tonumber_string_raw(duk_hthread *thr) {
DUK_S2N_FLAG_ALLOW_AUTO_OCT_INT |
DUK_S2N_FLAG_ALLOW_AUTO_BIN_INT;
- duk_numconv_parse(ctx, 10 /*radix*/, s2n_flags);
+ duk_numconv_parse(thr, 10 /*radix*/, s2n_flags);
#if defined(DUK_USE_PREFER_SIZE)
- d = duk_get_number(ctx, -1);
- duk_pop(ctx);
+ d = duk_get_number(thr, -1);
+ duk_pop_unsafe(thr);
#else
thr->valstack_top--;
DUK_ASSERT(DUK_TVAL_IS_NUMBER(thr->valstack_top));
@@ -75674,8 +77273,6 @@ DUK_LOCAL duk_double_t duk__tonumber_string_raw(duk_hthread *thr) {
}
DUK_INTERNAL duk_double_t duk_js_tonumber(duk_hthread *thr, duk_tval *tv) {
- duk_context *ctx = (duk_hthread *) thr;
-
DUK_ASSERT(thr != NULL);
DUK_ASSERT(tv != NULL);
@@ -75703,22 +77300,22 @@ DUK_INTERNAL duk_double_t duk_js_tonumber(duk_hthread *thr, duk_tval *tv) {
if (DUK_UNLIKELY(DUK_HSTRING_HAS_SYMBOL(h))) {
DUK_ERROR_TYPE(thr, DUK_STR_CANNOT_NUMBER_COERCE_SYMBOL);
}
- duk_push_hstring(ctx, h);
+ duk_push_hstring(thr, h);
return duk__tonumber_string_raw(thr);
}
case DUK_TAG_BUFFER: /* plain buffer treated like object */
case DUK_TAG_OBJECT: {
duk_double_t d;
- duk_push_tval(ctx, tv);
- duk_to_primitive(ctx, -1, DUK_HINT_NUMBER); /* 'tv' becomes invalid */
+ duk_push_tval(thr, tv);
+ duk_to_primitive(thr, -1, DUK_HINT_NUMBER); /* 'tv' becomes invalid */
/* recursive call for a primitive value (guaranteed not to cause second
* recursion).
*/
- DUK_ASSERT(duk_get_tval(ctx, -1) != NULL);
- d = duk_js_tonumber(thr, duk_get_tval(ctx, -1));
+ DUK_ASSERT(duk_get_tval(thr, -1) != NULL);
+ d = duk_js_tonumber(thr, duk_get_tval(thr, -1));
- duk_pop(ctx);
+ duk_pop_unsafe(thr);
return d;
}
case DUK_TAG_POINTER: {
@@ -75768,7 +77365,7 @@ DUK_INTERNAL duk_double_t duk_js_tointeger_number(duk_double_t x) {
/* NaN and Infinity have the same exponent so it's a cheap
* initial check for the rare path.
*/
- if (DUK_UNLIKELY(duk_double_is_nan_or_inf(x))) {
+ if (DUK_UNLIKELY(duk_double_is_nan_or_inf(x) != 0U)) {
if (duk_double_is_nan(x)) {
return 0.0;
} else {
@@ -76003,8 +77600,7 @@ DUK_LOCAL duk_bool_t duk__js_samevalue_number(duk_double_t x, duk_double_t y) {
#endif /* DUK_USE_PARANOID_MATH */
}
-DUK_INTERNAL duk_bool_t duk_js_equals_helper(duk_hthread *thr, duk_tval *tv_x, duk_tval *tv_y, duk_small_int_t flags) {
- duk_context *ctx = (duk_context *) thr;
+DUK_INTERNAL duk_bool_t duk_js_equals_helper(duk_hthread *thr, duk_tval *tv_x, duk_tval *tv_y, duk_small_uint_t flags) {
duk_uint_t type_mask_x;
duk_uint_t type_mask_y;
@@ -76127,7 +77723,7 @@ DUK_INTERNAL duk_bool_t duk_js_equals_helper(duk_hthread *thr, duk_tval *tv_x, d
if (!DUK_TVAL_STRING_IS_SYMBOL(tv_y)) {
duk_double_t d1, d2;
d1 = DUK_TVAL_GET_NUMBER(tv_x);
- d2 = duk_to_number_tval(ctx, tv_y);
+ d2 = duk_to_number_tval(thr, tv_y);
return duk__js_equals_number(d1, d2);
}
}
@@ -76135,7 +77731,7 @@ DUK_INTERNAL duk_bool_t duk_js_equals_helper(duk_hthread *thr, duk_tval *tv_x, d
if (!DUK_TVAL_STRING_IS_SYMBOL(tv_x)) {
duk_double_t d1, d2;
d1 = DUK_TVAL_GET_NUMBER(tv_y);
- d2 = duk_to_number_tval(ctx, tv_x);
+ d2 = duk_to_number_tval(thr, tv_x);
return duk__js_equals_number(d1, d2);
}
}
@@ -76149,14 +77745,14 @@ DUK_INTERNAL duk_bool_t duk_js_equals_helper(duk_hthread *thr, duk_tval *tv_x, d
*/
if (type_mask_x & DUK_TYPE_MASK_BOOLEAN) {
DUK_ASSERT(DUK_TVAL_GET_BOOLEAN(tv_x) == 0 || DUK_TVAL_GET_BOOLEAN(tv_x) == 1);
- duk_push_int(ctx, DUK_TVAL_GET_BOOLEAN(tv_x));
- duk_push_tval(ctx, tv_y);
+ duk_push_uint(thr, DUK_TVAL_GET_BOOLEAN(tv_x));
+ duk_push_tval(thr, tv_y);
goto recursive_call;
}
if (type_mask_y & DUK_TYPE_MASK_BOOLEAN) {
DUK_ASSERT(DUK_TVAL_GET_BOOLEAN(tv_y) == 0 || DUK_TVAL_GET_BOOLEAN(tv_y) == 1);
- duk_push_tval(ctx, tv_x);
- duk_push_int(ctx, DUK_TVAL_GET_BOOLEAN(tv_y));
+ duk_push_tval(thr, tv_x);
+ duk_push_uint(thr, DUK_TVAL_GET_BOOLEAN(tv_y));
goto recursive_call;
}
@@ -76164,17 +77760,17 @@ DUK_INTERNAL duk_bool_t duk_js_equals_helper(duk_hthread *thr, duk_tval *tv_x, d
if ((type_mask_x & (DUK_TYPE_MASK_STRING | DUK_TYPE_MASK_NUMBER)) &&
(type_mask_y & DUK_TYPE_MASK_OBJECT)) {
/* No symbol check needed because symbols and strings are accepted. */
- duk_push_tval(ctx, tv_x);
- duk_push_tval(ctx, tv_y);
- duk_to_primitive(ctx, -1, DUK_HINT_NONE); /* apparently no hint? */
+ duk_push_tval(thr, tv_x);
+ duk_push_tval(thr, tv_y);
+ duk_to_primitive(thr, -1, DUK_HINT_NONE); /* apparently no hint? */
goto recursive_call;
}
if ((type_mask_x & DUK_TYPE_MASK_OBJECT) &&
(type_mask_y & (DUK_TYPE_MASK_STRING | DUK_TYPE_MASK_NUMBER))) {
/* No symbol check needed because symbols and strings are accepted. */
- duk_push_tval(ctx, tv_x);
- duk_push_tval(ctx, tv_y);
- duk_to_primitive(ctx, -2, DUK_HINT_NONE); /* apparently no hint? */
+ duk_push_tval(thr, tv_x);
+ duk_push_tval(thr, tv_y);
+ duk_to_primitive(thr, -2, DUK_HINT_NONE); /* apparently no hint? */
goto recursive_call;
}
@@ -76186,10 +77782,10 @@ DUK_INTERNAL duk_bool_t duk_js_equals_helper(duk_hthread *thr, duk_tval *tv_x, d
{
duk_bool_t rc;
rc = duk_js_equals_helper(thr,
- DUK_GET_TVAL_NEGIDX(ctx, -2),
- DUK_GET_TVAL_NEGIDX(ctx, -1),
+ DUK_GET_TVAL_NEGIDX(thr, -2),
+ DUK_GET_TVAL_NEGIDX(thr, -1),
0 /*flags:nonstrict*/);
- duk_pop_2(ctx);
+ duk_pop_2_unsafe(thr);
return rc;
}
}
@@ -76381,8 +77977,7 @@ DUK_LOCAL duk_bool_t duk__compare_number(duk_bool_t retval, duk_double_t d1, duk
}
#endif /* DUK_USE_PARANOID_MATH */
-DUK_INTERNAL duk_bool_t duk_js_compare_helper(duk_hthread *thr, duk_tval *tv_x, duk_tval *tv_y, duk_small_int_t flags) {
- duk_context *ctx = (duk_context *) thr;
+DUK_INTERNAL duk_bool_t duk_js_compare_helper(duk_hthread *thr, duk_tval *tv_x, duk_tval *tv_y, duk_small_uint_t flags) {
duk_double_t d1, d2;
duk_small_int_t rc;
duk_bool_t retval;
@@ -76411,20 +78006,20 @@ DUK_INTERNAL duk_bool_t duk_js_compare_helper(duk_hthread *thr, duk_tval *tv_x,
/* Slow path */
- duk_push_tval(ctx, tv_x);
- duk_push_tval(ctx, tv_y);
+ duk_push_tval(thr, tv_x);
+ duk_push_tval(thr, tv_y);
if (flags & DUK_COMPARE_FLAG_EVAL_LEFT_FIRST) {
- duk_to_primitive(ctx, -2, DUK_HINT_NUMBER);
- duk_to_primitive(ctx, -1, DUK_HINT_NUMBER);
+ duk_to_primitive(thr, -2, DUK_HINT_NUMBER);
+ duk_to_primitive(thr, -1, DUK_HINT_NUMBER);
} else {
- duk_to_primitive(ctx, -1, DUK_HINT_NUMBER);
- duk_to_primitive(ctx, -2, DUK_HINT_NUMBER);
+ duk_to_primitive(thr, -1, DUK_HINT_NUMBER);
+ duk_to_primitive(thr, -2, DUK_HINT_NUMBER);
}
/* Note: reuse variables */
- tv_x = DUK_GET_TVAL_NEGIDX(ctx, -2);
- tv_y = DUK_GET_TVAL_NEGIDX(ctx, -1);
+ tv_x = DUK_GET_TVAL_NEGIDX(thr, -2);
+ tv_y = DUK_GET_TVAL_NEGIDX(thr, -1);
if (DUK_TVAL_IS_STRING(tv_x) && DUK_TVAL_IS_STRING(tv_y)) {
duk_hstring *h1 = DUK_TVAL_GET_STRING(tv_x);
@@ -76434,7 +78029,7 @@ DUK_INTERNAL duk_bool_t duk_js_compare_helper(duk_hthread *thr, duk_tval *tv_x,
if (DUK_LIKELY(!DUK_HSTRING_HAS_SYMBOL(h1) && !DUK_HSTRING_HAS_SYMBOL(h2))) {
rc = duk_js_string_compare(h1, h2);
- duk_pop_2(ctx);
+ duk_pop_2_unsafe(thr);
if (rc < 0) {
return retval ^ 1;
} else {
@@ -76450,27 +78045,27 @@ DUK_INTERNAL duk_bool_t duk_js_compare_helper(duk_hthread *thr, duk_tval *tv_x,
/* Ordering should not matter (E5 Section 11.8.5, step 3.a). */
#if 0
if (flags & DUK_COMPARE_FLAG_EVAL_LEFT_FIRST) {
- d1 = duk_to_number_m2(ctx);
- d2 = duk_to_number_m1(ctx);
+ d1 = duk_to_number_m2(thr);
+ d2 = duk_to_number_m1(thr);
} else {
- d2 = duk_to_number_m1(ctx);
- d1 = duk_to_number_m2(ctx);
+ d2 = duk_to_number_m1(thr);
+ d1 = duk_to_number_m2(thr);
}
#endif
- d1 = duk_to_number_m2(ctx);
- d2 = duk_to_number_m1(ctx);
+ d1 = duk_to_number_m2(thr);
+ d2 = duk_to_number_m1(thr);
- /* We want to duk_pop_2(ctx); because the values are numbers
+ /* We want to duk_pop_2_unsafe(thr); because the values are numbers
* no decref check is needed.
*/
#if defined(DUK_USE_PREFER_SIZE)
- duk_pop_2(ctx);
+ duk_pop_2_nodecref_unsafe(thr);
#else
- DUK_ASSERT(!DUK_TVAL_NEEDS_REFCOUNT_UPDATE(duk_get_tval(ctx, -2)));
- DUK_ASSERT(!DUK_TVAL_NEEDS_REFCOUNT_UPDATE(duk_get_tval(ctx, -1)));
- DUK_ASSERT(duk_get_top(ctx) >= 2);
- ((duk_hthread *) ctx)->valstack_top -= 2;
- tv_x = ((duk_hthread *) ctx)->valstack_top;
+ DUK_ASSERT(!DUK_TVAL_NEEDS_REFCOUNT_UPDATE(duk_get_tval(thr, -2)));
+ DUK_ASSERT(!DUK_TVAL_NEEDS_REFCOUNT_UPDATE(duk_get_tval(thr, -1)));
+ DUK_ASSERT(duk_get_top(thr) >= 2);
+ thr->valstack_top -= 2;
+ tv_x = thr->valstack_top;
tv_y = tv_x + 1;
DUK_TVAL_SET_UNDEFINED(tv_x); /* Value stack policy */
DUK_TVAL_SET_UNDEFINED(tv_y);
@@ -76500,13 +78095,12 @@ DUK_INTERNAL duk_bool_t duk_js_compare_helper(duk_hthread *thr, duk_tval *tv_x,
*/
DUK_INTERNAL duk_bool_t duk_js_instanceof(duk_hthread *thr, duk_tval *tv_x, duk_tval *tv_y) {
- duk_context *ctx = (duk_context *) thr;
duk_hobject *func;
duk_hobject *val;
duk_hobject *proto;
duk_tval *tv;
- duk_uint_t sanity;
duk_bool_t skip_first;
+ duk_uint_t sanity;
/*
* Get the values onto the stack first. It would be possible to cover
@@ -76518,52 +78112,41 @@ DUK_INTERNAL duk_bool_t duk_js_instanceof(duk_hthread *thr, duk_tval *tv_x, duk_
* Using duk_require_hobject() is thus correct (except for error msg).
*/
- duk_push_tval(ctx, tv_x);
- duk_push_tval(ctx, tv_y);
- func = duk_require_hobject(ctx, -1);
+ duk_push_tval(thr, tv_x);
+ duk_push_tval(thr, tv_y);
+ func = duk_require_hobject(thr, -1);
+ DUK_ASSERT(func != NULL);
/*
* For bound objects, [[HasInstance]] just calls the target function
* [[HasInstance]]. If that is again a bound object, repeat until
* we find a non-bound Function object.
+ *
+ * The bound function chain is now "collapsed" so there can be only
+ * one bound function in the chain.
*/
- /* XXX: this bound function resolution also happens elsewhere,
- * move into a shared helper.
- */
-
- sanity = DUK_HOBJECT_BOUND_CHAIN_SANITY;
- do {
- /* check func supports [[HasInstance]] (this is checked for every function
- * in the bound chain, including the final one)
+ if (!DUK_HOBJECT_IS_CALLABLE(func)) {
+ /*
+ * Note: of native Ecmascript objects, only Function instances
+ * have a [[HasInstance]] internal property. Custom objects might
+ * also have it, but not in current implementation.
+ *
+ * XXX: add a separate flag, DUK_HOBJECT_FLAG_ALLOW_INSTANCEOF?
*/
+ goto error_invalid_rval;
+ }
- if (!DUK_HOBJECT_IS_CALLABLE(func)) {
- /*
- * Note: of native Ecmascript objects, only Function instances
- * have a [[HasInstance]] internal property. Custom objects might
- * also have it, but not in current implementation.
- *
- * XXX: add a separate flag, DUK_HOBJECT_FLAG_ALLOW_INSTANCEOF?
- */
- DUK_ERROR_TYPE(thr, "invalid instanceof rval");
- }
-
- if (!DUK_HOBJECT_HAS_BOUNDFUNC(func)) {
- break;
- }
-
- /* [ ... lval rval ] */
-
- duk_get_prop_stridx_short(ctx, -1, DUK_STRIDX_INT_TARGET); /* -> [ ... lval rval new_rval ] */
- duk_replace(ctx, -1); /* -> [ ... lval new_rval ] */
- func = duk_require_hobject(ctx, -1);
-
- /* func support for [[HasInstance]] checked in the beginning of the loop */
- } while (--sanity > 0);
+ if (DUK_HOBJECT_HAS_BOUNDFUNC(func)) {
+ duk_push_tval(thr, &((duk_hboundfunc *) func)->target);
+ duk_replace(thr, -2);
+ func = duk_require_hobject(thr, -1); /* lightfunc throws */
- if (DUK_UNLIKELY(sanity == 0)) {
- DUK_ERROR_RANGE(thr, DUK_STR_BOUND_CHAIN_LIMIT);
+ /* Rely on Function.prototype.bind() never creating bound
+ * functions whose target is not proper.
+ */
+ DUK_ASSERT(func != NULL);
+ DUK_ASSERT(DUK_HOBJECT_IS_CALLABLE(func));
}
/*
@@ -76572,6 +78155,7 @@ DUK_INTERNAL duk_bool_t duk_js_instanceof(duk_hthread *thr, duk_tval *tv_x, duk_
* to execute E5 Section 15.3.5.3.
*/
+ DUK_ASSERT(func != NULL);
DUK_ASSERT(!DUK_HOBJECT_HAS_BOUNDFUNC(func));
DUK_ASSERT(DUK_HOBJECT_IS_CALLABLE(func));
@@ -76581,7 +78165,7 @@ DUK_INTERNAL duk_bool_t duk_js_instanceof(duk_hthread *thr, duk_tval *tv_x, duk_
* from the virtual prototype object.
*/
skip_first = 0;
- tv = DUK_GET_TVAL_NEGIDX(ctx, -2);
+ tv = DUK_GET_TVAL_NEGIDX(thr, -2);
switch (DUK_TVAL_GET_TAG(tv)) {
case DUK_TAG_LIGHTFUNC:
val = thr->builtins[DUK_BIDX_FUNCTION_PROTOTYPE];
@@ -76601,13 +78185,22 @@ DUK_INTERNAL duk_bool_t duk_js_instanceof(duk_hthread *thr, duk_tval *tv_x, duk_
DUK_ASSERT(val != NULL);
break;
default:
- goto pop_and_false;
+ goto pop2_and_false;
}
DUK_ASSERT(val != NULL); /* Loop doesn't actually rely on this. */
- duk_get_prop_stridx_short(ctx, -1, DUK_STRIDX_PROTOTYPE); /* -> [ ... lval rval rval.prototype ] */
- proto = duk_require_hobject(ctx, -1);
- duk_pop(ctx); /* -> [ ... lval rval ] */
+ /* Look up .prototype of rval. Leave it on the value stack in case it
+ * has been virtualized (e.g. getter, Proxy trap).
+ */
+ duk_get_prop_stridx_short(thr, -1, DUK_STRIDX_PROTOTYPE); /* -> [ ... lval rval rval.prototype ] */
+#if defined(DUK_USE_VERBOSE_ERRORS)
+ proto = duk_get_hobject(thr, -1);
+ if (proto == NULL) {
+ goto error_invalid_rval_noproto;
+ }
+#else
+ proto = duk_require_hobject(thr, -1);
+#endif
sanity = DUK_HOBJECT_PROTOTYPE_CHAIN_SANITY;
do {
@@ -76630,18 +78223,18 @@ DUK_INTERNAL duk_bool_t duk_js_instanceof(duk_hthread *thr, duk_tval *tv_x, duk_
*/
if (!val) {
- goto pop_and_false;
+ goto pop3_and_false;
}
DUK_ASSERT(val != NULL);
#if defined(DUK_USE_ES6_PROXY)
- val = duk_hobject_resolve_proxy_target(thr, val);
+ val = duk_hobject_resolve_proxy_target(val);
#endif
if (skip_first) {
skip_first = 0;
} else if (val == proto) {
- goto pop_and_true;
+ goto pop3_and_true;
}
DUK_ASSERT(val != NULL);
@@ -76653,13 +78246,27 @@ DUK_INTERNAL duk_bool_t duk_js_instanceof(duk_hthread *thr, duk_tval *tv_x, duk_
}
DUK_UNREACHABLE();
- pop_and_false:
- duk_pop_2(ctx);
+ pop2_and_false:
+ duk_pop_2_unsafe(thr);
+ return 0;
+
+ pop3_and_false:
+ duk_pop_3_unsafe(thr);
return 0;
- pop_and_true:
- duk_pop_2(ctx);
+ pop3_and_true:
+ duk_pop_3_unsafe(thr);
return 1;
+
+ error_invalid_rval:
+ DUK_ERROR_TYPE(thr, DUK_STR_INVALID_INSTANCEOF_RVAL);
+ return 0;
+
+#if defined(DUK_USE_VERBOSE_ERRORS)
+ error_invalid_rval_noproto:
+ DUK_ERROR_TYPE(thr, DUK_STR_INVALID_INSTANCEOF_RVAL_NOPROTO);
+ return 0;
+#endif
}
/*
@@ -76673,7 +78280,6 @@ DUK_INTERNAL duk_bool_t duk_js_instanceof(duk_hthread *thr, duk_tval *tv_x, duk_
*/
DUK_INTERNAL duk_bool_t duk_js_in(duk_hthread *thr, duk_tval *tv_x, duk_tval *tv_y) {
- duk_context *ctx = (duk_context *) thr;
duk_bool_t retval;
/*
@@ -76693,17 +78299,17 @@ DUK_INTERNAL duk_bool_t duk_js_in(duk_hthread *thr, duk_tval *tv_x, duk_tval *tv
/* TypeError if rval is not an object or object like (e.g. lightfunc
* or plain buffer).
*/
- duk_push_tval(ctx, tv_x);
- duk_push_tval(ctx, tv_y);
- duk_require_type_mask(ctx, -1, DUK_TYPE_MASK_OBJECT | DUK_TYPE_MASK_LIGHTFUNC | DUK_TYPE_MASK_BUFFER);
+ duk_push_tval(thr, tv_x);
+ duk_push_tval(thr, tv_y);
+ duk_require_type_mask(thr, -1, DUK_TYPE_MASK_OBJECT | DUK_TYPE_MASK_LIGHTFUNC | DUK_TYPE_MASK_BUFFER);
- (void) duk_to_property_key_hstring(ctx, -2);
+ (void) duk_to_property_key_hstring(thr, -2);
retval = duk_hobject_hasprop(thr,
- DUK_GET_TVAL_NEGIDX(ctx, -1),
- DUK_GET_TVAL_NEGIDX(ctx, -2));
+ DUK_GET_TVAL_NEGIDX(thr, -1),
+ DUK_GET_TVAL_NEGIDX(thr, -2));
- duk_pop_2(ctx);
+ duk_pop_2_unsafe(thr);
return retval;
}
@@ -76891,8 +78497,8 @@ DUK_INTERNAL duk_uarridx_t duk_js_to_arrayindex_hstring_fast_known(duk_hstring *
/* Scanning to NUL is always safe for interned strings. */
break;
}
- DUK_ASSERT(t >= DUK_ASC_0 && t <= DUK_ASC_9);
- res = res * 10U + (t - DUK_ASC_0);
+ DUK_ASSERT(t >= (duk_uint8_t) DUK_ASC_0 && t <= (duk_uint8_t) DUK_ASC_9);
+ res = res * 10U + (duk_uarridx_t) t - (duk_uarridx_t) DUK_ASC_0;
}
return res;
}
@@ -76947,7 +78553,7 @@ typedef struct {
duk_hobject *env;
duk_hobject *holder; /* for object-bound identifiers */
duk_tval *value; /* for register-bound and declarative env identifiers */
- duk_int_t attrs; /* property attributes for identifier (relevant if value != NULL) */
+ duk_uint_t attrs; /* property attributes for identifier (relevant if value != NULL) */
duk_bool_t has_this; /* for object-bound identifiers: provide 'this' binding */
} duk__id_lookup_result;
@@ -77033,7 +78639,6 @@ void duk_js_push_closure(duk_hthread *thr,
duk_hobject *outer_var_env,
duk_hobject *outer_lex_env,
duk_bool_t add_auto_proto) {
- duk_context *ctx = (duk_context *) thr;
duk_hcompfunc *fun_clos;
duk_small_uint_t i;
duk_uint_t len_value;
@@ -77046,11 +78651,11 @@ void duk_js_push_closure(duk_hthread *thr,
DUK_ASSERT(outer_lex_env != NULL);
DUK_UNREF(len_value);
- fun_clos = duk_push_hcompfunc(ctx);
+ fun_clos = duk_push_hcompfunc(thr);
DUK_ASSERT(fun_clos != NULL);
DUK_ASSERT(DUK_HOBJECT_GET_PROTOTYPE(thr->heap, (duk_hobject *) fun_clos) == thr->builtins[DUK_BIDX_FUNCTION_PROTOTYPE]);
- duk_push_hobject(ctx, &fun_temp->obj); /* -> [ ... closure template ] */
+ duk_push_hobject(thr, &fun_temp->obj); /* -> [ ... closure template ] */
DUK_ASSERT(DUK_HOBJECT_IS_COMPFUNC((duk_hobject *) fun_clos));
DUK_ASSERT(DUK_HCOMPFUNC_GET_DATA(thr->heap, fun_clos) == NULL);
@@ -77080,10 +78685,14 @@ void duk_js_push_closure(duk_hthread *thr,
DUK_ASSERT(DUK_HCOMPFUNC_GET_FUNCS(thr->heap, fun_clos) != NULL);
DUK_ASSERT(DUK_HCOMPFUNC_GET_BYTECODE(thr->heap, fun_clos) != NULL);
- /* XXX: could also copy from template, but there's no way to have any
+ /* XXX: Could also copy from template, but there's no way to have any
* other value here now (used code has no access to the template).
+ * Prototype is set by duk_push_hcompfunc().
*/
+ DUK_ASSERT(DUK_HOBJECT_GET_PROTOTYPE(thr->heap, &fun_clos->obj) == thr->builtins[DUK_BIDX_FUNCTION_PROTOTYPE]);
+#if 0
DUK_HOBJECT_SET_PROTOTYPE_UPDREF(thr, &fun_clos->obj, thr->builtins[DUK_BIDX_FUNCTION_PROTOTYPE]);
+#endif
/* Copy duk_hobject flags as is from the template using a mask.
* Leave out duk_heaphdr owned flags just in case (e.g. if there's
@@ -77158,7 +78767,7 @@ void duk_js_push_closure(duk_hthread *thr,
DUK_HOBJECT_FLAG_EXTENSIBLE |
DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_DECENV));
DUK_ASSERT(new_env != NULL);
- duk_push_hobject(ctx, (duk_hobject *) new_env);
+ duk_push_hobject(thr, (duk_hobject *) new_env);
DUK_ASSERT(DUK_HOBJECT_GET_PROTOTYPE(thr->heap, (duk_hobject *) new_env) == NULL);
DUK_HOBJECT_SET_PROTOTYPE(thr->heap, (duk_hobject *) new_env, proto);
@@ -77176,10 +78785,10 @@ void duk_js_push_closure(duk_hthread *thr,
* the name 'undefined' gets bound and maps to the closure (which is
* a bit odd, but safe).
*/
- (void) duk_get_prop_stridx_short(ctx, -2, DUK_STRIDX_NAME);
+ (void) duk_get_prop_stridx_short(thr, -2, DUK_STRIDX_NAME);
/* -> [ ... closure template env funcname ] */
- duk_dup_m4(ctx); /* -> [ ... closure template env funcname closure ] */
- duk_xdef_prop(ctx, -3, DUK_PROPDESC_FLAGS_NONE); /* -> [ ... closure template env ] */
+ duk_dup_m4(thr); /* -> [ ... closure template env funcname closure ] */
+ duk_xdef_prop(thr, -3, DUK_PROPDESC_FLAGS_NONE); /* -> [ ... closure template env ] */
/* env[funcname] = closure */
/* [ ... closure template env ] */
@@ -77188,7 +78797,7 @@ void duk_js_push_closure(duk_hthread *thr,
DUK_HCOMPFUNC_SET_VARENV(thr->heap, fun_clos, (duk_hobject *) new_env);
DUK_HOBJECT_INCREF(thr, (duk_hobject *) new_env);
DUK_HOBJECT_INCREF(thr, (duk_hobject *) new_env);
- duk_pop(ctx);
+ duk_pop_unsafe(thr);
/* [ ... closure template ] */
}
@@ -77242,18 +78851,18 @@ void duk_js_push_closure(duk_hthread *thr,
/* [ ... closure template ] */
DUK_DDD(DUK_DDDPRINT("copying properties: closure=%!iT, template=%!iT",
- (duk_tval *) duk_get_tval(ctx, -2),
- (duk_tval *) duk_get_tval(ctx, -1)));
+ (duk_tval *) duk_get_tval(thr, -2),
+ (duk_tval *) duk_get_tval(thr, -1)));
for (i = 0; i < (duk_small_uint_t) (sizeof(duk__closure_copy_proplist) / sizeof(duk_uint16_t)); i++) {
duk_small_int_t stridx = (duk_small_int_t) duk__closure_copy_proplist[i];
- if (duk_get_prop_stridx_short(ctx, -1, stridx)) {
+ if (duk_get_prop_stridx_short(thr, -1, stridx)) {
/* [ ... closure template val ] */
DUK_DDD(DUK_DDDPRINT("copying property, stridx=%ld -> found", (long) stridx));
- duk_xdef_prop_stridx_short(ctx, -3, stridx, DUK_PROPDESC_FLAGS_C);
+ duk_xdef_prop_stridx_short(thr, -3, stridx, DUK_PROPDESC_FLAGS_C);
} else {
DUK_DDD(DUK_DDDPRINT("copying property, stridx=%ld -> not found", (long) stridx));
- duk_pop(ctx);
+ duk_pop_unsafe(thr);
}
}
@@ -77269,18 +78878,18 @@ void duk_js_push_closure(duk_hthread *thr,
/* XXX: these lookups should be just own property lookups instead of
* looking up the inheritance chain.
*/
- if (duk_get_prop_stridx_short(ctx, -1, DUK_STRIDX_INT_FORMALS)) {
+ if (duk_get_prop_stridx_short(thr, -1, DUK_STRIDX_INT_FORMALS)) {
/* [ ... closure template formals ] */
- len_value = (duk_uint_t) duk_get_length(ctx, -1); /* could access duk_harray directly, not important */
+ len_value = (duk_uint_t) duk_get_length(thr, -1); /* could access duk_harray directly, not important */
DUK_DD(DUK_DDPRINT("closure length from _Formals -> %ld", (long) len_value));
} else {
len_value = fun_temp->nargs;
DUK_DD(DUK_DDPRINT("closure length defaulted from nargs -> %ld", (long) len_value));
}
- duk_pop(ctx);
+ duk_pop_unsafe(thr);
- duk_push_uint(ctx, len_value); /* [ ... closure template len_value ] */
- duk_xdef_prop_stridx_short(ctx, -3, DUK_STRIDX_LENGTH, DUK_PROPDESC_FLAGS_C);
+ duk_push_uint(thr, len_value); /* [ ... closure template len_value ] */
+ duk_xdef_prop_stridx_short(thr, -3, DUK_STRIDX_LENGTH, DUK_PROPDESC_FLAGS_C);
/*
* "prototype" is, by default, a fresh object with the "constructor"
@@ -77299,11 +78908,11 @@ void duk_js_push_closure(duk_hthread *thr,
/* [ ... closure template ] */
if (add_auto_proto) {
- duk_push_object(ctx); /* -> [ ... closure template newobj ] */
- duk_dup_m3(ctx); /* -> [ ... closure template newobj closure ] */
- duk_xdef_prop_stridx_short(ctx, -2, DUK_STRIDX_CONSTRUCTOR, DUK_PROPDESC_FLAGS_WC); /* -> [ ... closure template newobj ] */
- duk_compact(ctx, -1); /* compact the prototype */
- duk_xdef_prop_stridx_short(ctx, -3, DUK_STRIDX_PROTOTYPE, DUK_PROPDESC_FLAGS_W); /* -> [ ... closure template ] */
+ duk_push_object(thr); /* -> [ ... closure template newobj ] */
+ duk_dup_m3(thr); /* -> [ ... closure template newobj closure ] */
+ duk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_CONSTRUCTOR, DUK_PROPDESC_FLAGS_WC); /* -> [ ... closure template newobj ] */
+ duk_compact(thr, -1); /* compact the prototype */
+ duk_xdef_prop_stridx_short(thr, -3, DUK_STRIDX_PROTOTYPE, DUK_PROPDESC_FLAGS_W); /* -> [ ... closure template ] */
}
/*
@@ -77317,13 +78926,13 @@ void duk_js_push_closure(duk_hthread *thr,
/* [ ... closure template ] */
if (DUK_HOBJECT_HAS_STRICT(&fun_clos->obj)) {
- duk_xdef_prop_stridx_thrower(ctx, -2, DUK_STRIDX_CALLER);
- duk_xdef_prop_stridx_thrower(ctx, -2, DUK_STRIDX_LC_ARGUMENTS);
+ duk_xdef_prop_stridx_thrower(thr, -2, DUK_STRIDX_CALLER);
+ duk_xdef_prop_stridx_thrower(thr, -2, DUK_STRIDX_LC_ARGUMENTS);
} else {
#if defined(DUK_USE_NONSTD_FUNC_CALLER_PROPERTY)
DUK_DDD(DUK_DDDPRINT("function is non-strict and non-standard 'caller' property in use, add initial 'null' value"));
- duk_push_null(ctx);
- duk_xdef_prop_stridx_short(ctx, -3, DUK_STRIDX_CALLER, DUK_PROPDESC_FLAGS_NONE);
+ duk_push_null(thr);
+ duk_xdef_prop_stridx_short(thr, -3, DUK_STRIDX_CALLER, DUK_PROPDESC_FLAGS_NONE);
#else
DUK_DDD(DUK_DDDPRINT("function is non-strict and non-standard 'caller' property not used"));
#endif
@@ -77340,18 +78949,18 @@ void duk_js_push_closure(duk_hthread *thr,
/* XXX: Look for own property only; doesn't matter much because
* templates are bare objects.
*/
- if (duk_get_prop_stridx_short(ctx, -1, DUK_STRIDX_NAME)) {
+ if (duk_get_prop_stridx_short(thr, -1, DUK_STRIDX_NAME)) {
/* [ ... closure template name ] */
- DUK_ASSERT(duk_is_string(ctx, -1));
- DUK_DD(DUK_DDPRINT("setting function instance name to %!T", duk_get_tval(ctx, -1)));
- duk_xdef_prop_stridx_short(ctx, -3, DUK_STRIDX_NAME, DUK_PROPDESC_FLAGS_C); /* -> [ ... closure template ] */
+ DUK_ASSERT(duk_is_string(thr, -1));
+ DUK_DD(DUK_DDPRINT("setting function instance name to %!T", duk_get_tval(thr, -1)));
+ duk_xdef_prop_stridx_short(thr, -3, DUK_STRIDX_NAME, DUK_PROPDESC_FLAGS_C); /* -> [ ... closure template ] */
} else {
/* Anonymous functions don't have a .name in ES2015, so don't set
* it on the instance either. The instance will then inherit
* it from Function.prototype.name.
*/
DUK_DD(DUK_DDPRINT("not setting function instance .name"));
- duk_pop(ctx);
+ duk_pop_unsafe(thr);
}
#endif
@@ -77364,7 +78973,7 @@ void duk_js_push_closure(duk_hthread *thr,
* through the API).
*/
- duk_compact(ctx, -2);
+ duk_compact(thr, -2);
/*
* Some assertions (E5 Section 13.2).
@@ -77373,13 +78982,13 @@ void duk_js_push_closure(duk_hthread *thr,
DUK_ASSERT(DUK_HOBJECT_GET_CLASS_NUMBER(&fun_clos->obj) == DUK_HOBJECT_CLASS_FUNCTION);
DUK_ASSERT(DUK_HOBJECT_GET_PROTOTYPE(thr->heap, &fun_clos->obj) == thr->builtins[DUK_BIDX_FUNCTION_PROTOTYPE]);
DUK_ASSERT(DUK_HOBJECT_HAS_EXTENSIBLE(&fun_clos->obj));
- DUK_ASSERT(duk_has_prop_stridx(ctx, -2, DUK_STRIDX_LENGTH) != 0);
- DUK_ASSERT(add_auto_proto == 0 || duk_has_prop_stridx(ctx, -2, DUK_STRIDX_PROTOTYPE) != 0);
+ DUK_ASSERT(duk_has_prop_stridx(thr, -2, DUK_STRIDX_LENGTH) != 0);
+ DUK_ASSERT(add_auto_proto == 0 || duk_has_prop_stridx(thr, -2, DUK_STRIDX_PROTOTYPE) != 0);
/* May be missing .name */
DUK_ASSERT(!DUK_HOBJECT_HAS_STRICT(&fun_clos->obj) ||
- duk_has_prop_stridx(ctx, -2, DUK_STRIDX_CALLER) != 0);
+ duk_has_prop_stridx(thr, -2, DUK_STRIDX_CALLER) != 0);
DUK_ASSERT(!DUK_HOBJECT_HAS_STRICT(&fun_clos->obj) ||
- duk_has_prop_stridx(ctx, -2, DUK_STRIDX_LC_ARGUMENTS) != 0);
+ duk_has_prop_stridx(thr, -2, DUK_STRIDX_LC_ARGUMENTS) != 0);
/*
* Finish
@@ -77388,10 +78997,10 @@ void duk_js_push_closure(duk_hthread *thr,
/* [ ... closure template ] */
DUK_DDD(DUK_DDDPRINT("created function instance: template=%!iT -> closure=%!iT",
- (duk_tval *) duk_get_tval(ctx, -1),
- (duk_tval *) duk_get_tval(ctx, -2)));
+ (duk_tval *) duk_get_tval(thr, -1),
+ (duk_tval *) duk_get_tval(thr, -2)));
- duk_pop(ctx);
+ duk_pop_unsafe(thr);
/* [ ... closure ] */
}
@@ -77407,13 +79016,11 @@ void duk_js_push_closure(duk_hthread *thr,
DUK_INTERNAL
duk_hobject *duk_create_activation_environment_record(duk_hthread *thr,
duk_hobject *func,
- duk_size_t idx_bottom) {
- duk_context *ctx = (duk_context *) thr;
+ duk_size_t bottom_byteoff) {
duk_hdecenv *env;
duk_hobject *parent;
duk_hcompfunc *f;
- DUK_ASSERT(ctx != NULL);
DUK_ASSERT(thr != NULL);
DUK_ASSERT(func != NULL);
@@ -77427,7 +79034,7 @@ duk_hobject *duk_create_activation_environment_record(duk_hthread *thr,
DUK_HOBJECT_FLAG_EXTENSIBLE |
DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_DECENV));
DUK_ASSERT(env != NULL);
- duk_push_hobject(ctx, (duk_hobject *) env);
+ duk_push_hobject(thr, (duk_hobject *) env);
DUK_ASSERT(DUK_HOBJECT_GET_PROTOTYPE(thr->heap, (duk_hobject *) env) == NULL);
DUK_HOBJECT_SET_PROTOTYPE(thr->heap, (duk_hobject *) env, parent);
@@ -77437,7 +79044,7 @@ duk_hobject *duk_create_activation_environment_record(duk_hthread *thr,
DUK_ASSERT(env->thread == NULL);
DUK_ASSERT(env->varmap == NULL);
- DUK_ASSERT(env->regbase == 0);
+ DUK_ASSERT(env->regbase_byteoff == 0);
if (DUK_HOBJECT_IS_COMPFUNC(func)) {
duk_hobject *varmap;
duk_tval *tv;
@@ -77451,12 +79058,12 @@ duk_hobject *duk_create_activation_environment_record(duk_hthread *thr,
DUK_HOBJECT_INCREF(thr, varmap);
env->thread = thr;
DUK_HTHREAD_INCREF(thr, thr);
- env->regbase = idx_bottom;
+ env->regbase_byteoff = bottom_byteoff;
} else {
/* If function has no _Varmap, leave the environment closed. */
DUK_ASSERT(env->thread == NULL);
DUK_ASSERT(env->varmap == NULL);
- DUK_ASSERT(env->regbase == 0);
+ DUK_ASSERT(env->regbase_byteoff == 0);
}
}
@@ -77466,13 +79073,10 @@ duk_hobject *duk_create_activation_environment_record(duk_hthread *thr,
DUK_INTERNAL
void duk_js_init_activation_environment_records_delayed(duk_hthread *thr,
duk_activation *act) {
- duk_context *ctx = (duk_context *) thr;
duk_hobject *func;
duk_hobject *env;
- duk_size_t act_off;
- DUK_ASSERT(act != NULL);
- act_off = (duk_size_t) ((duk_uint8_t *) act - (duk_uint8_t *) thr->callstack);
+ DUK_ASSERT(thr != NULL);
func = DUK_ACT_GET_FUNC(act);
DUK_ASSERT(func != NULL);
DUK_ASSERT(!DUK_HOBJECT_HAS_BOUNDFUNC(func)); /* bound functions are never in act 'func' */
@@ -77485,9 +79089,9 @@ void duk_js_init_activation_environment_records_delayed(duk_hthread *thr,
DUK_ASSERT(act->lex_env == NULL);
DUK_ASSERT(act->var_env == NULL);
- env = duk_create_activation_environment_record(thr, func, act->idx_bottom);
+ env = duk_create_activation_environment_record(thr, func, act->bottom_byteoff);
DUK_ASSERT(env != NULL);
- act = (duk_activation *) (void *) ((duk_uint8_t *) thr->callstack + act_off);
+ /* 'act' is a stable pointer, so still OK. */
DUK_DDD(DUK_DDDPRINT("created delayed fresh env: %!ipO", (duk_heaphdr *) env));
#if defined(DUK_USE_DEBUG_LEVEL) && (DUK_USE_DEBUG_LEVEL >= 2)
@@ -77505,7 +79109,7 @@ void duk_js_init_activation_environment_records_delayed(duk_hthread *thr,
DUK_HOBJECT_INCREF(thr, env); /* XXX: incref by count (here 2 times) */
DUK_HOBJECT_INCREF(thr, env);
- duk_pop(ctx);
+ duk_pop_unsafe(thr);
}
/*
@@ -77517,7 +79121,6 @@ void duk_js_init_activation_environment_records_delayed(duk_hthread *thr,
*/
DUK_INTERNAL void duk_js_close_environment_record(duk_hthread *thr, duk_hobject *env) {
- duk_context *ctx = (duk_context *) thr;
duk_uint_fast32_t i;
duk_hobject *varmap;
duk_hstring *key;
@@ -77570,7 +79173,7 @@ DUK_INTERNAL void duk_js_close_environment_record(duk_hthread *thr, duk_hobject
* then realloc with hash part if large enough).
*/
for (i = 0; i < (duk_uint_fast32_t) DUK_HOBJECT_GET_ENEXT(varmap); i++) {
- duk_size_t regbase;
+ duk_size_t regbase_byteoff;
key = DUK_HOBJECT_E_GET_KEY(thr->heap, varmap, i);
DUK_ASSERT(key != NULL); /* assume keys are compact in _Varmap */
@@ -77586,19 +79189,19 @@ DUK_INTERNAL void duk_js_close_environment_record(duk_hthread *thr, duk_hobject
regnum = (duk_uint_t) DUK_TVAL_GET_NUMBER(tv);
#endif
- regbase = ((duk_hdecenv *) env)->regbase;
- DUK_ASSERT(thr->valstack + regbase + regnum >= thr->valstack);
- DUK_ASSERT(thr->valstack + regbase + regnum < thr->valstack_top);
+ regbase_byteoff = ((duk_hdecenv *) env)->regbase_byteoff;
+ DUK_ASSERT((duk_uint8_t *) thr->valstack + regbase_byteoff + sizeof(duk_tval) * regnum >= (duk_uint8_t *) thr->valstack);
+ DUK_ASSERT((duk_uint8_t *) thr->valstack + regbase_byteoff + sizeof(duk_tval) * regnum < (duk_uint8_t *) thr->valstack_top);
/* If property already exists, overwrites silently.
* Property is writable, but not deletable (not configurable
* in terms of property attributes).
*/
- duk_push_tval(ctx, thr->valstack + regbase + regnum);
+ duk_push_tval(thr, (duk_tval *) (void *) ((duk_uint8_t *) thr->valstack + regbase_byteoff + sizeof(duk_tval) * regnum));
DUK_DDD(DUK_DDDPRINT("closing identifier %!O -> reg %ld, value %!T",
(duk_heaphdr *) key,
(long) regnum,
- (duk_tval *) duk_get_tval(ctx, -1)));
+ (duk_tval *) duk_get_tval(thr, -1)));
duk_hobject_define_property_internal(thr, env, key, DUK_PROPDESC_FLAGS_WE);
}
@@ -77642,7 +79245,6 @@ duk_bool_t duk__getid_open_decl_env_regs(duk_hthread *thr,
duk__id_lookup_result *out) {
duk_tval *tv;
duk_size_t reg_rel;
- duk_size_t idx;
DUK_ASSERT(thr != NULL);
DUK_ASSERT(name != NULL);
@@ -77673,8 +79275,7 @@ duk_bool_t duk__getid_open_decl_env_regs(duk_hthread *thr,
#endif
DUK_ASSERT_DISABLE(reg_rel >= 0); /* unsigned */
- idx = env->regbase + reg_rel;
- tv = env->thread->valstack + idx;
+ tv = (duk_tval *) (void *) ((duk_uint8_t *) env->thread->valstack + env->regbase_byteoff + sizeof(duk_tval) * reg_rel);
DUK_ASSERT(tv >= env->thread->valstack && tv < env->thread->valstack_end); /* XXX: more accurate? */
out->value = tv;
@@ -77695,7 +79296,6 @@ duk_bool_t duk__getid_activation_regs(duk_hthread *thr,
duk_hobject *func;
duk_hobject *varmap;
duk_size_t reg_rel;
- duk_size_t idx;
DUK_ASSERT(thr != NULL);
DUK_ASSERT(name != NULL);
@@ -77728,9 +79328,8 @@ duk_bool_t duk__getid_activation_regs(duk_hthread *thr,
DUK_ASSERT_DISABLE(reg_rel >= 0);
DUK_ASSERT(reg_rel < ((duk_hcompfunc *) func)->nregs);
- idx = act->idx_bottom + reg_rel;
- DUK_ASSERT(idx >= act->idx_bottom);
- tv = thr->valstack + idx;
+ tv = (duk_tval *) (void *) ((duk_uint8_t *) thr->valstack + act->bottom_byteoff);
+ tv += reg_rel;
out->value = tv;
out->attrs = DUK_PROPDESC_FLAGS_W; /* registers are mutable, non-deletable */
@@ -77748,7 +79347,6 @@ duk_bool_t duk__get_identifier_reference(duk_hthread *thr,
duk_bool_t parents,
duk__id_lookup_result *out) {
duk_tval *tv;
- duk_tval tv_name;
duk_uint_t sanity;
DUK_ASSERT(thr != NULL);
@@ -77841,8 +79439,8 @@ duk_bool_t duk__get_identifier_reference(duk_hthread *thr,
sanity = DUK_HOBJECT_PROTOTYPE_CHAIN_SANITY;
while (env != NULL) {
- duk_small_int_t cl;
- duk_int_t attrs;
+ duk_small_uint_t cl;
+ duk_uint_t attrs;
DUK_DDD(DUK_DDDPRINT("duk__get_identifier_reference, name=%!O, considering env=%p -> %!iO",
(duk_heaphdr *) name,
@@ -77926,7 +79524,9 @@ duk_bool_t duk__get_identifier_reference(duk_hthread *thr,
* property is found, but rather the object binding target object.
*/
- if (DUK_HOBJECT_HAS_EXOTIC_PROXYOBJ(target)) {
+#if defined(DUK_USE_ES6_PROXY)
+ if (DUK_UNLIKELY(DUK_HOBJECT_IS_PROXY(target))) {
+ duk_tval tv_name;
duk_tval tv_target_tmp;
DUK_ASSERT(name != NULL);
@@ -77934,7 +79534,9 @@ duk_bool_t duk__get_identifier_reference(duk_hthread *thr,
DUK_TVAL_SET_OBJECT(&tv_target_tmp, target);
found = duk_hobject_hasprop(thr, &tv_target_tmp, &tv_name);
- } else {
+ } else
+#endif /* DUK_USE_ES6_PROXY */
+ {
/* XXX: duk_hobject_hasprop() would be correct for
* non-Proxy objects too, but it is about ~20-25%
* slower at present so separate code paths for
@@ -78056,7 +79658,6 @@ duk_bool_t duk__getvar_helper(duk_hthread *thr,
duk_activation *act,
duk_hstring *name,
duk_bool_t throw_flag) {
- duk_context *ctx = (duk_context *) thr;
duk__id_lookup_result ref;
duk_tval tv_tmp_obj;
duk_tval tv_tmp_key;
@@ -78071,14 +79672,16 @@ duk_bool_t duk__getvar_helper(duk_hthread *thr,
DUK_ASSERT(name != NULL);
/* env and act may be NULL */
+ DUK_STATS_INC(thr->heap, stats_getvar_all);
+
DUK_ASSERT_REFCOUNT_NONZERO_HEAPHDR(env);
DUK_ASSERT_REFCOUNT_NONZERO_HEAPHDR(name);
parents = 1; /* follow parent chain */
if (duk__get_identifier_reference(thr, env, name, act, parents, &ref)) {
if (ref.value) {
- duk_push_tval(ctx, ref.value);
- duk_push_undefined(ctx);
+ duk_push_tval(thr, ref.value);
+ duk_push_undefined(thr);
} else {
DUK_ASSERT(ref.holder != NULL);
@@ -78092,9 +79695,9 @@ duk_bool_t duk__getvar_helper(duk_hthread *thr,
(void) duk_hobject_getprop(thr, &tv_tmp_obj, &tv_tmp_key); /* [value] */
if (ref.has_this) {
- duk_push_hobject(ctx, ref.holder);
+ duk_push_hobject(thr, ref.holder);
} else {
- duk_push_undefined(ctx);
+ duk_push_undefined(thr);
}
/* [value this] */
@@ -78156,6 +79759,8 @@ void duk__putvar_helper(duk_hthread *thr,
duk_tval tv_tmp_key;
duk_bool_t parents;
+ DUK_STATS_INC(thr->heap, stats_putvar_all);
+
DUK_DDD(DUK_DDDPRINT("putvar: thr=%p, env=%p, act=%p, name=%!O, val=%p, strict=%ld "
"(env -> %!dO, val -> %!T)",
(void *) thr, (void *) env, (void *) act,
@@ -78398,9 +80003,8 @@ duk_bool_t duk__declvar_helper(duk_hthread *thr,
duk_hobject *env,
duk_hstring *name,
duk_tval *val,
- duk_small_int_t prop_flags,
+ duk_small_uint_t prop_flags,
duk_bool_t is_func_decl) {
- duk_context *ctx = (duk_context *) thr;
duk_hobject *holder;
duk_bool_t parents;
duk__id_lookup_result ref;
@@ -78441,7 +80045,7 @@ duk_bool_t duk__declvar_helper(duk_hthread *thr,
if (duk__get_identifier_reference(thr, env, name, NULL, parents, &ref)) {
duk_int_t e_idx;
duk_int_t h_idx;
- duk_small_int_t flags;
+ duk_small_uint_t flags;
/*
* Variable already declared, ignore re-declaration.
@@ -78488,8 +80092,8 @@ duk_bool_t duk__declvar_helper(duk_hthread *thr,
/* must be found: was found earlier, and cannot be inherited */
for (;;) {
DUK_ASSERT(holder != NULL);
- duk_hobject_find_existing_entry(thr->heap, holder, name, &e_idx, &h_idx);
- if (e_idx >= 0) {
+ if (duk_hobject_find_existing_entry(thr->heap, holder, name, &e_idx, &h_idx)) {
+ DUK_ASSERT(e_idx >= 0);
break;
}
/* SCANBUILD: NULL pointer dereference, doesn't actually trigger,
@@ -78568,7 +80172,7 @@ duk_bool_t duk__declvar_helper(duk_hthread *thr,
DUK_DDD(DUK_DDDPRINT("redefine, offending property in ancestor"));
DUK_ASSERT(ref.holder == thr->builtins[DUK_BIDX_GLOBAL]);
- duk_push_tval(ctx, val);
+ duk_push_tval(thr, val);
duk_hobject_define_property_internal(thr, ref.holder, name, prop_flags);
}
@@ -78608,11 +80212,11 @@ duk_bool_t duk__declvar_helper(duk_hthread *thr,
goto fail_not_extensible;
}
- duk_push_hobject(ctx, holder);
- duk_push_hstring(ctx, name);
- duk_push_tval(ctx, val);
- duk_xdef_prop(ctx, -3, prop_flags); /* [holder name val] -> [holder] */
- duk_pop(ctx);
+ duk_push_hobject(thr, holder);
+ duk_push_hstring(thr, name);
+ duk_push_tval(thr, val);
+ duk_xdef_prop(thr, -3, prop_flags); /* [holder name val] -> [holder] */
+ duk_pop_unsafe(thr);
return 0;
@@ -78627,14 +80231,12 @@ duk_bool_t duk_js_declvar_activation(duk_hthread *thr,
duk_activation *act,
duk_hstring *name,
duk_tval *val,
- duk_small_int_t prop_flags,
+ duk_small_uint_t prop_flags,
duk_bool_t is_func_decl) {
duk_hobject *env;
duk_tval tv_val_copy;
- duk_size_t act_off;
DUK_ASSERT(act != NULL);
- act_off = (duk_size_t) ((duk_uint8_t *) act - (duk_uint8_t *) thr->callstack);
/*
* Make a value copy of the input val. This ensures that
@@ -78651,7 +80253,7 @@ duk_bool_t duk_js_declvar_activation(duk_hthread *thr,
if (!act->var_env) {
DUK_ASSERT(act->lex_env == NULL);
duk_js_init_activation_environment_records_delayed(thr, act);
- act = (duk_activation *) (void *) ((duk_uint8_t *) thr->callstack + act_off);
+ /* 'act' is a stable pointer, so still OK. */
}
DUK_ASSERT(act->lex_env != NULL);
DUK_ASSERT(act->var_env != NULL);
@@ -78976,7 +80578,7 @@ DUK_LOCAL void duk__fill_lexer_buffer(duk_lexer_ctx *lex_ctx, duk_small_uint_t s
lex_ctx->input_offset = (duk_size_t) (p - lex_ctx->input);
lex_ctx->input_line = input_line;
- DUK_ERROR_SYNTAX(lex_ctx->thr, DUK_STR_DECODE_FAILED);
+ DUK_ERROR_SYNTAX(lex_ctx->thr, DUK_STR_SOURCE_DECODE_FAILED);
}
DUK_LOCAL void duk__advance_bytes(duk_lexer_ctx *lex_ctx, duk_small_uint_t count_bytes) {
@@ -79136,7 +80738,7 @@ DUK_LOCAL duk_codepoint_t duk__read_char(duk_lexer_ctx *lex_ctx) {
error_clipped: /* clipped codepoint */
error_encoding: /* invalid codepoint encoding or codepoint */
- DUK_ERROR_SYNTAX(lex_ctx->thr, DUK_STR_DECODE_FAILED);
+ DUK_ERROR_SYNTAX(lex_ctx->thr, DUK_STR_SOURCE_DECODE_FAILED);
return 0;
}
@@ -79225,13 +80827,11 @@ DUK_LOCAL void duk__appendbuffer_ascii(duk_lexer_ctx *lex_ctx, duk_codepoint_t x
*/
DUK_LOCAL duk_hstring *duk__internbuffer(duk_lexer_ctx *lex_ctx, duk_idx_t valstack_idx) {
- duk_context *ctx = (duk_context *) lex_ctx->thr;
-
DUK_ASSERT(valstack_idx == lex_ctx->slot1_idx || valstack_idx == lex_ctx->slot2_idx);
DUK_BW_PUSH_AS_STRING(lex_ctx->thr, &lex_ctx->bw);
- duk_replace(ctx, valstack_idx);
- return duk_known_hstring(ctx, valstack_idx);
+ duk_replace(lex_ctx->thr, valstack_idx);
+ return duk_known_hstring(lex_ctx->thr, valstack_idx);
}
/*
@@ -79319,7 +80919,7 @@ DUK_LOCAL duk_codepoint_t duk__lexer_parse_escape(duk_lexer_ctx *lex_ctx, duk_bo
duk_small_int_t digits; /* Initial value 2 or 4 for fixed length escapes, 0 for ES2015 \u{H+}. */
duk_codepoint_t escval;
duk_codepoint_t x;
- duk_small_int_t adv;
+ duk_small_uint_t adv;
DUK_ASSERT(DUK__L0() == DUK_ASC_BACKSLASH); /* caller responsibilities */
DUK_ASSERT(DUK__L1() == DUK_ASC_LC_X || DUK__L1() == DUK_ASC_LC_U);
@@ -79413,10 +81013,10 @@ DUK_LOCAL duk_codepoint_t duk__lexer_parse_escape(duk_lexer_ctx *lex_ctx, duk_bo
* RegExp octal escape parsing. Window[0] must be the slash '\' and the first
* digit must already be validated to be in [0-9] by the caller.
*/
-DUK_LOCAL duk_codepoint_t duk__lexer_parse_legacy_octal(duk_lexer_ctx *lex_ctx, duk_small_int_t *out_adv, duk_bool_t reject_annex_b) {
+DUK_LOCAL duk_codepoint_t duk__lexer_parse_legacy_octal(duk_lexer_ctx *lex_ctx, duk_small_uint_t *out_adv, duk_bool_t reject_annex_b) {
duk_codepoint_t cp;
duk_small_uint_t lookup_idx;
- duk_small_int_t adv;
+ duk_small_uint_t adv;
duk_codepoint_t tmp;
DUK_ASSERT(out_adv != NULL);
@@ -79424,6 +81024,7 @@ DUK_LOCAL duk_codepoint_t duk__lexer_parse_legacy_octal(duk_lexer_ctx *lex_ctx,
DUK_ASSERT(DUK__LOOKUP(lex_ctx, 1) >= DUK_ASC_0 && DUK__LOOKUP(lex_ctx, 1) <= DUK_ASC_9);
cp = 0;
+ tmp = 0;
for (lookup_idx = 1; lookup_idx <= 3; lookup_idx++) {
DUK_DDD(DUK_DDDPRINT("lookup_idx=%ld, cp=%ld", (long) lookup_idx, (long) cp));
tmp = DUK__LOOKUP(lex_ctx, lookup_idx);
@@ -79472,7 +81073,7 @@ DUK_LOCAL duk_codepoint_t duk__lexer_parse_legacy_octal(duk_lexer_ctx *lex_ctx,
/* XXX: move strict mode to lex_ctx? */
DUK_LOCAL void duk__lexer_parse_string_literal(duk_lexer_ctx *lex_ctx, duk_token *out_token, duk_small_int_t quote, duk_bool_t strict_mode) {
- duk_small_int_t adv;
+ duk_small_uint_t adv;
for (adv = 1 /* initial quote */ ;;) {
duk_codepoint_t x;
@@ -79701,7 +81302,7 @@ void duk_lexer_parse_js_input_element(duk_lexer_ctx *lex_ctx,
}
out_token->t = DUK_TOK_EOF;
- out_token->t_nores = -1; /* marker: copy t if not changed */
+ out_token->t_nores = DUK_TOK_INVALID; /* marker: copy t if not changed */
#if 0 /* not necessary to init, disabled for faster parsing */
out_token->num = DUK_DOUBLE_NAN;
out_token->str1 = NULL;
@@ -79716,8 +81317,8 @@ void duk_lexer_parse_js_input_element(duk_lexer_ctx *lex_ctx,
* freed normally.
*/
#if 0
- duk_to_undefined((duk_context *) lex_ctx->thr, lex_ctx->slot1_idx);
- duk_to_undefined((duk_context *) lex_ctx->thr, lex_ctx->slot2_idx);
+ duk_to_undefined(lex_ctx->thr, lex_ctx->slot1_idx);
+ duk_to_undefined(lex_ctx->thr, lex_ctx->slot2_idx);
#endif
/* 'advtok' indicates how much to advance and which token id to assign
@@ -79966,7 +81567,7 @@ void duk_lexer_parse_js_input_element(duk_lexer_ctx *lex_ctx,
#if defined(DUK_USE_HTML_COMMENTS)
if (DUK__L1() == DUK_ASC_EXCLAMATION && DUK__L2() == DUK_ASC_MINUS && DUK__L3() == DUK_ASC_MINUS) {
/*
- * ES6: B.1.3, handle "<!--" SingleLineHTMLOpenComment
+ * ES2015: B.1.3, handle "<!--" SingleLineHTMLOpenComment
*/
/* DUK__ADVANCECHARS(lex_ctx, 4) would be correct here, but not necessary */
@@ -80031,7 +81632,7 @@ void duk_lexer_parse_js_input_element(duk_lexer_ctx *lex_ctx,
#if defined(DUK_USE_HTML_COMMENTS)
if (got_lineterm && DUK__L1() == DUK_ASC_MINUS && DUK__L2() == DUK_ASC_RANGLE) {
/*
- * ES6: B.1.3, handle "-->" SingleLineHTMLCloseComment
+ * ES2015: B.1.3, handle "-->" SingleLineHTMLCloseComment
* Only allowed:
* - on new line
* - preceded only by whitespace
@@ -80115,7 +81716,7 @@ void duk_lexer_parse_js_input_element(duk_lexer_ctx *lex_ctx,
DUK__INITBUFFER(lex_ctx);
duk__lexer_parse_string_literal(lex_ctx, out_token, x /*quote*/, strict_mode);
duk__internbuffer(lex_ctx, lex_ctx->slot1_idx);
- out_token->str1 = duk_known_hstring((duk_context *) lex_ctx->thr, lex_ctx->slot1_idx);
+ out_token->str1 = duk_known_hstring(lex_ctx->thr, lex_ctx->slot1_idx);
DUK__INITBUFFER(lex_ctx); /* free some memory */
@@ -80174,7 +81775,7 @@ void duk_lexer_parse_js_input_element(duk_lexer_ctx *lex_ctx,
* parsing the identifier. This has little practical impact.
*/
- duk_small_int_t i, i_end;
+ duk_small_uint_t i, i_end;
duk_bool_t first = 1;
duk_hstring *str;
@@ -80246,7 +81847,8 @@ void duk_lexer_parse_js_input_element(duk_lexer_ctx *lex_ctx,
advtok = DUK__ADVTOK(0, DUK_TOK_IDENTIFIER);
if (out_token->num_escapes == 0) {
for (i = DUK_STRIDX_START_RESERVED; i < i_end; i++) {
- DUK_ASSERT(i >= 0 && i < DUK_HEAP_NUM_STRINGS);
+ DUK_ASSERT_DISABLE(i >= 0); /* unsigned */
+ DUK_ASSERT(i < DUK_HEAP_NUM_STRINGS);
if (DUK_HTHREAD_GET_STRING(lex_ctx->thr, i) == str) {
advtok = DUK__ADVTOK(0, DUK_STRIDX_TO_TOK(i));
break;
@@ -80287,7 +81889,7 @@ void duk_lexer_parse_js_input_element(duk_lexer_ctx *lex_ctx,
*/
duk_small_uint_t s2n_flags;
duk_codepoint_t y, z;
- duk_small_uint_t s2n_radix = 10;
+ duk_small_int_t s2n_radix = 10;
duk_small_uint_t pre_adv = 0;
DUK__INITBUFFER(lex_ctx);
@@ -80393,13 +81995,13 @@ void duk_lexer_parse_js_input_element(duk_lexer_ctx *lex_ctx,
DUK_S2N_FLAG_ALLOW_LEADING_ZERO;
}
- duk_dup((duk_context *) lex_ctx->thr, lex_ctx->slot1_idx);
- duk_numconv_parse((duk_context *) lex_ctx->thr, s2n_radix, s2n_flags);
- val = duk_to_number_m1((duk_context *) lex_ctx->thr);
+ duk_dup(lex_ctx->thr, lex_ctx->slot1_idx);
+ duk_numconv_parse(lex_ctx->thr, s2n_radix, s2n_flags);
+ val = duk_to_number_m1(lex_ctx->thr);
if (DUK_ISNAN(val)) {
goto fail_number_literal;
}
- duk_replace((duk_context *) lex_ctx->thr, lex_ctx->slot1_idx); /* could also just pop? */
+ duk_replace(lex_ctx->thr, lex_ctx->slot1_idx); /* could also just pop? */
DUK__INITBUFFER(lex_ctx); /* free some memory */
@@ -80429,7 +82031,7 @@ void duk_lexer_parse_js_input_element(duk_lexer_ctx *lex_ctx,
DUK__ADVANCEBYTES(lex_ctx, advtok >> 8);
out_token->t = advtok & 0xff;
- if (out_token->t_nores < 0) {
+ if (out_token->t_nores == DUK_TOK_INVALID) {
out_token->t_nores = out_token->t;
}
out_token->lineterm = got_lineterm;
@@ -80489,7 +82091,7 @@ void duk_lexer_parse_js_input_element(duk_lexer_ctx *lex_ctx,
*/
DUK_INTERNAL void duk_lexer_parse_re_token(duk_lexer_ctx *lex_ctx, duk_re_token *out_token) {
- duk_small_int_t advtok = 0; /* init is unnecessary but suppresses "may be used uninitialized" warnings */
+ duk_small_uint_t advtok = 0; /* init is unnecessary but suppresses "may be used uninitialized" warnings */
duk_codepoint_t x, y;
if (++lex_ctx->token_count >= lex_ctx->token_limit) {
@@ -80554,8 +82156,8 @@ DUK_INTERNAL void duk_lexer_parse_re_token(duk_lexer_ctx *lex_ctx, duk_re_token
}
case DUK_ASC_LCURLY: {
/* Production allows 'DecimalDigits', including leading zeroes */
- duk_uint_fast32_t val1 = 0;
- duk_uint_fast32_t val2 = DUK_RE_QUANTIFIER_INFINITE;
+ duk_uint32_t val1 = 0;
+ duk_uint32_t val2 = DUK_RE_QUANTIFIER_INFINITE;
duk_small_int_t digits = 0;
#if defined(DUK_USE_ES6_REGEXP_SYNTAX)
duk_lexer_point lex_pt;
@@ -80571,7 +82173,7 @@ DUK_INTERNAL void duk_lexer_parse_re_token(duk_lexer_ctx *lex_ctx, duk_re_token
x = DUK__L0();
if (DUK__ISDIGIT(x)) {
digits++;
- val1 = val1 * 10 + (duk_uint_fast32_t) duk__hexval(x);
+ val1 = val1 * 10 + (duk_uint32_t) duk__hexval(x);
} else if (x == DUK_ASC_COMMA) {
if (digits > DUK__MAX_RE_QUANT_DIGITS) {
goto invalid_quantifier;
@@ -80667,7 +82269,7 @@ DUK_INTERNAL void duk_lexer_parse_re_token(duk_lexer_ctx *lex_ctx, duk_re_token
x = DUK__L2();
if ((x >= DUK_ASC_LC_A && x <= DUK_ASC_LC_Z) ||
(x >= DUK_ASC_UC_A && x <= DUK_ASC_UC_Z)) {
- out_token->num = (x % 32);
+ out_token->num = (duk_uint32_t) (x % 32);
advtok = DUK__ADVTOK(3, DUK_RETOK_ATOM_CHAR);
} else {
goto fail_escape;
@@ -80678,7 +82280,7 @@ DUK_INTERNAL void duk_lexer_parse_re_token(duk_lexer_ctx *lex_ctx, duk_re_token
* here. The \u{H+} is only allowed in Unicode mode
* which we don't support yet.
*/
- out_token->num = duk__lexer_parse_escape(lex_ctx, 0 /*allow_es6*/);
+ out_token->num = (duk_uint32_t) duk__lexer_parse_escape(lex_ctx, 0 /*allow_es6*/);
advtok = DUK__ADVTOK(0, DUK_RETOK_ATOM_CHAR);
} else if (y == DUK_ASC_LC_D) {
advtok = DUK__ADVTOK(2, DUK_RETOK_ATOM_DIGIT);
@@ -80702,7 +82304,7 @@ DUK_INTERNAL void duk_lexer_parse_re_token(duk_lexer_ctx *lex_ctx, duk_re_token
advtok = DUK__ADVTOK(2, DUK_RETOK_ATOM_CHAR);
} else {
/* XXX: shared parsing? */
- duk_uint_fast32_t val = 0;
+ duk_uint32_t val = 0;
duk_small_int_t i;
for (i = 0; ; i++) {
if (i >= DUK__MAX_RE_DECESC_DIGITS) {
@@ -80713,7 +82315,7 @@ DUK_INTERNAL void duk_lexer_parse_re_token(duk_lexer_ctx *lex_ctx, duk_re_token
if (!DUK__ISDIGIT(x)) {
break;
}
- val = val * 10 + (duk_uint_fast32_t) duk__hexval(x);
+ val = val * 10 + (duk_uint32_t) duk__hexval(x);
}
/* DUK__L0() cannot be a digit, because the loop doesn't terminate if it is */
advtok = DUK__ADVTOK(0, DUK_RETOK_ATOM_BACKREFERENCE);
@@ -80739,7 +82341,7 @@ DUK_INTERNAL void duk_lexer_parse_re_token(duk_lexer_ctx *lex_ctx, duk_re_token
* test-regexp-identity-escape-dollar.js.
*/
#endif /* DUK_USE_ES6_REGEXP_SYNTAX */
- out_token->num = y;
+ out_token->num = (duk_uint32_t) y;
} else {
goto fail_escape;
}
@@ -80806,7 +82408,7 @@ DUK_INTERNAL void duk_lexer_parse_re_token(duk_lexer_ctx *lex_ctx, duk_re_token
default: {
/* PatternCharacter, all excluded characters are matched by cases above */
advtok = DUK__ADVTOK(1, DUK_RETOK_ATOM_CHAR);
- out_token->num = x;
+ out_token->num = (duk_uint32_t) x;
break;
}
}
@@ -80885,7 +82487,7 @@ DUK_INTERNAL void duk_lexer_parse_re_ranges(duk_lexer_ctx *lex_ctx, duk_re_range
duk_codepoint_t ch;
duk_codepoint_t x;
duk_bool_t dash = 0;
- duk_small_int_t adv = 0;
+ duk_small_uint_t adv = 0;
DUK_DD(DUK_DDPRINT("parsing regexp ranges"));
@@ -80907,7 +82509,7 @@ DUK_INTERNAL void duk_lexer_parse_re_ranges(duk_lexer_ctx *lex_ctx, duk_re_range
DUK__ADVANCECHARS(lex_ctx, 1); /* eat ']' before finishing */
break;
} else if (x == DUK_ASC_MINUS) {
- if (start >= 0 && !dash && DUK__L0() != DUK_ASC_RBRACKET) {
+ if (start >= 0 && !dash && DUK__L1() != DUK_ASC_RBRACKET) {
/* '-' as a range indicator */
dash = 1;
continue;
@@ -81259,7 +82861,7 @@ DUK_LOCAL void duk__bi_copy(duk__bigint *x, duk__bigint *y) {
if (n == 0) {
return;
}
- DUK_MEMCPY((void *) x->v, (const void *) y->v, (size_t) (sizeof(duk_uint32_t) * n));
+ DUK_MEMCPY((void *) x->v, (const void *) y->v, (size_t) (sizeof(duk_uint32_t) * (size_t) n));
}
DUK_LOCAL void duk__bi_set_small(duk__bigint *x, duk_uint32_t v) {
@@ -81444,7 +83046,7 @@ DUK_LOCAL void duk__bi_sub(duk__bigint *x, duk__bigint *y, duk__bigint *z) {
tz = 0;
}
tmp = (duk_int64_t) ty - (duk_int64_t) tz + tmp;
- x->v[i] = (duk_uint32_t) (tmp & 0xffffffffUL);
+ x->v[i] = (duk_uint32_t) ((duk_uint64_t) tmp & 0xffffffffUL);
tmp = tmp >> 32; /* 0 or -1 */
}
DUK_ASSERT(tmp == 0);
@@ -81535,7 +83137,7 @@ DUK_LOCAL void duk__bi_mul(duk__bigint *x, duk__bigint *y, duk__bigint *z) {
return;
}
- DUK_MEMZERO((void *) x->v, (size_t) (sizeof(duk_uint32_t) * nx));
+ DUK_MEMZERO((void *) x->v, (size_t) (sizeof(duk_uint32_t) * (size_t) nx));
x->n = nx;
nz = z->n;
@@ -81685,7 +83287,7 @@ DUK_LOCAL void duk__bi_twoexp(duk__bigint *x, duk_small_int_t y) {
n = (y / 32) + 1;
DUK_ASSERT(n > 0);
r = y % 32;
- DUK_MEMZERO((void *) x->v, sizeof(duk_uint32_t) * n);
+ DUK_MEMZERO((void *) x->v, sizeof(duk_uint32_t) * (size_t) n);
x->n = n;
x->v[n - 1] = (((duk_uint32_t) 1) << r);
}
@@ -81708,7 +83310,7 @@ DUK_LOCAL void duk__bi_exp_small(duk__bigint *x, duk_small_int_t b, duk_small_in
DUK_DDD(DUK_DDDPRINT("exp_small: b=%ld, y=%ld", (long) b, (long) y));
duk__bi_set_small(x, 1);
- duk__bi_set_small(t1, b);
+ duk__bi_set_small(t1, (duk_uint32_t) b);
for (;;) {
/* Loop structure ensures that we don't compute t1^2 unnecessarily
* on the final round, as that might create a bignum exceeding the
@@ -81749,10 +83351,10 @@ DUK_LOCAL void duk__bi_exp_small(duk__bigint *x, duk_small_int_t b, duk_small_in
*/
/* Maximum number of digits generated. */
-#define DUK__MAX_OUTPUT_DIGITS 1040 /* (Number.MAX_VALUE).toString(2).length == 1024, + spare */
+#define DUK__MAX_OUTPUT_DIGITS 1040 /* (Number.MAX_VALUE).toString(2).length == 1024, + slack */
/* Maximum number of characters in formatted value. */
-#define DUK__MAX_FORMATTED_LENGTH 1040 /* (-Number.MAX_VALUE).toString(2).length == 1025, + spare */
+#define DUK__MAX_FORMATTED_LENGTH 1040 /* (-Number.MAX_VALUE).toString(2).length == 1025, + slack */
/* Number and (minimum) size of bigints in the nc_ctx structure. */
#define DUK__NUMCONV_CTX_NUM_BIGINTS 7
@@ -81797,7 +83399,7 @@ DUK_LOCAL duk_size_t duk__dragon4_format_uint32(duk_uint8_t *buf, duk_uint32_t x
duk_uint8_t *p;
duk_size_t len;
duk_small_int_t dig;
- duk_small_int_t t;
+ duk_uint32_t t;
DUK_ASSERT(radix >= 2 && radix <= 36);
@@ -81808,8 +83410,8 @@ DUK_LOCAL duk_size_t duk__dragon4_format_uint32(duk_uint8_t *buf, duk_uint32_t x
p = buf + 32;
for (;;) {
- t = x / radix;
- dig = x - t * radix;
+ t = x / (duk_uint32_t) radix;
+ dig = (duk_small_int_t) (x - t * (duk_uint32_t) radix);
x = t;
DUK_ASSERT(dig >= 0 && dig < 36);
@@ -81889,10 +83491,10 @@ DUK_LOCAL void duk__dragon4_prepare(duk__numconv_stringify_ctx *nc_ctx) {
"unequal gaps"));
duk__bi_exp_small(&nc_ctx->mm, nc_ctx->b, nc_ctx->e, &nc_ctx->t1, &nc_ctx->t2); /* mm <- b^e */
- duk__bi_mul_small(&nc_ctx->mp, &nc_ctx->mm, nc_ctx->b); /* mp <- b^(e+1) */
+ duk__bi_mul_small(&nc_ctx->mp, &nc_ctx->mm, (duk_uint32_t) nc_ctx->b); /* mp <- b^(e+1) */
duk__bi_mul_small(&nc_ctx->t1, &nc_ctx->f, 2);
- duk__bi_mul(&nc_ctx->r, &nc_ctx->t1, &nc_ctx->mp); /* r <- (2 * f) * b^(e+1) */
- duk__bi_set_small(&nc_ctx->s, nc_ctx->b * 2); /* s <- 2 * b */
+ duk__bi_mul(&nc_ctx->r, &nc_ctx->t1, &nc_ctx->mp); /* r <- (2 * f) * b^(e+1) */
+ duk__bi_set_small(&nc_ctx->s, (duk_uint32_t) (nc_ctx->b * 2)); /* s <- 2 * b */
nc_ctx->unequal_gaps = 1;
} else {
/* (>= e 0) AND (not (= f (expt b (- p 1))))
@@ -81938,7 +83540,7 @@ DUK_LOCAL void duk__dragon4_prepare(duk__numconv_stringify_ctx *nc_ctx) {
"lowest mantissa for this exponent -> "
"unequal gaps"));
- duk__bi_mul_small(&nc_ctx->r, &nc_ctx->f, nc_ctx->b * 2); /* r <- (2 * b) * f */
+ duk__bi_mul_small(&nc_ctx->r, &nc_ctx->f, (duk_uint32_t) (nc_ctx->b * 2)); /* r <- (2 * b) * f */
duk__bi_exp_small(&nc_ctx->t1, nc_ctx->b, 1 - nc_ctx->e, &nc_ctx->s, &nc_ctx->t2); /* NB: use 's' as temp on purpose */
duk__bi_mul_small(&nc_ctx->s, &nc_ctx->t1, 2); /* s <- b^(1-e) * 2 */
duk__bi_set_small(&nc_ctx->mp, 2);
@@ -82017,7 +83619,7 @@ DUK_LOCAL void duk__dragon4_scale(duk__numconv_stringify_ctx *nc_ctx) {
* k <- (+ k 1)
*/
- duk__bi_mul_small_copy(&nc_ctx->s, nc_ctx->B, &nc_ctx->t1);
+ duk__bi_mul_small_copy(&nc_ctx->s, (duk_uint32_t) nc_ctx->B, &nc_ctx->t1);
k++;
} else {
break;
@@ -82037,7 +83639,7 @@ DUK_LOCAL void duk__dragon4_scale(duk__numconv_stringify_ctx *nc_ctx) {
DUK__BI_PRINT("m-", &nc_ctx->mm);
duk__bi_add(&nc_ctx->t1, &nc_ctx->r, &nc_ctx->mp); /* t1 = (+ r m+) */
- duk__bi_mul_small(&nc_ctx->t2, &nc_ctx->t1, nc_ctx->B); /* t2 = (* (+ r m+) B) */
+ duk__bi_mul_small(&nc_ctx->t2, &nc_ctx->t1, (duk_uint32_t) nc_ctx->B); /* t2 = (* (+ r m+) B) */
if (duk__bi_compare(&nc_ctx->t2, &nc_ctx->s) <= (nc_ctx->high_ok ? -1 : 0)) {
DUK_DDD(DUK_DDDPRINT("k is too high"));
/* r <- (* r B)
@@ -82046,11 +83648,11 @@ DUK_LOCAL void duk__dragon4_scale(duk__numconv_stringify_ctx *nc_ctx) {
* m- <- (* m- B)
* k <- (- k 1)
*/
- duk__bi_mul_small_copy(&nc_ctx->r, nc_ctx->B, &nc_ctx->t1);
- duk__bi_mul_small_copy(&nc_ctx->mp, nc_ctx->B, &nc_ctx->t1);
+ duk__bi_mul_small_copy(&nc_ctx->r, (duk_uint32_t) nc_ctx->B, &nc_ctx->t1);
+ duk__bi_mul_small_copy(&nc_ctx->mp, (duk_uint32_t) nc_ctx->B, &nc_ctx->t1);
if (nc_ctx->unequal_gaps) {
DUK_DDD(DUK_DDDPRINT("m+ != m- -> need to update m- too"));
- duk__bi_mul_small_copy(&nc_ctx->mm, nc_ctx->B, &nc_ctx->t1);
+ duk__bi_mul_small_copy(&nc_ctx->mm, (duk_uint32_t) nc_ctx->B, &nc_ctx->t1);
}
k--;
} else {
@@ -82106,7 +83708,7 @@ DUK_LOCAL void duk__dragon4_generate(duk__numconv_stringify_ctx *nc_ctx) {
DUK__BI_PRINT("m-", &nc_ctx->mm);
/* (quotient-remainder (* r B) s) using a dummy subtraction loop */
- duk__bi_mul_small(&nc_ctx->t1, &nc_ctx->r, nc_ctx->B); /* t1 <- (* r B) */
+ duk__bi_mul_small(&nc_ctx->t1, &nc_ctx->r, (duk_uint32_t) nc_ctx->B); /* t1 <- (* r B) */
d = 0;
for (;;) {
if (duk__bi_compare(&nc_ctx->t1, &nc_ctx->s) < 0) {
@@ -82120,8 +83722,8 @@ DUK_LOCAL void duk__dragon4_generate(duk__numconv_stringify_ctx *nc_ctx) {
DUK_DDD(DUK_DDDPRINT("-> d(quot)=%ld", (long) d));
DUK__BI_PRINT("r(rem)", &nc_ctx->r);
- duk__bi_mul_small_copy(&nc_ctx->mp, nc_ctx->B, &nc_ctx->t2); /* m+ <- (* m+ B) */
- duk__bi_mul_small_copy(&nc_ctx->mm, nc_ctx->B, &nc_ctx->t2); /* m- <- (* m- B) */
+ duk__bi_mul_small_copy(&nc_ctx->mp, (duk_uint32_t) nc_ctx->B, &nc_ctx->t2); /* m+ <- (* m+ B) */
+ duk__bi_mul_small_copy(&nc_ctx->mm, (duk_uint32_t) nc_ctx->B, &nc_ctx->t2); /* m- <- (* m- B) */
DUK__BI_PRINT("mp(upd)", &nc_ctx->mp);
DUK__BI_PRINT("mm(upd)", &nc_ctx->mm);
@@ -82291,7 +83893,7 @@ DUK_LOCAL duk_small_int_t duk__dragon4_fixed_format_round(duk__numconv_stringify
DUK_DDD(DUK_DDDPRINT("carry propagated to first digit -> special case handling"));
DUK_MEMMOVE((void *) (&nc_ctx->digits[1]),
(const void *) (&nc_ctx->digits[0]),
- (size_t) (sizeof(char) * nc_ctx->count));
+ (size_t) (sizeof(char) * (size_t) nc_ctx->count));
nc_ctx->digits[0] = 1; /* don't increase 'count' */
nc_ctx->k++; /* position of highest digit changed */
nc_ctx->count++; /* number of digits changed */
@@ -82320,11 +83922,11 @@ DUK_LOCAL duk_small_int_t duk__dragon4_fixed_format_round(duk__numconv_stringify
#define DUK__NO_EXP (65536) /* arbitrary marker, outside valid exp range */
DUK_LOCAL void duk__dragon4_convert_and_push(duk__numconv_stringify_ctx *nc_ctx,
- duk_context *ctx,
- duk_small_int_t radix,
- duk_small_int_t digits,
- duk_small_uint_t flags,
- duk_small_int_t neg) {
+ duk_hthread *thr,
+ duk_small_int_t radix,
+ duk_small_int_t digits,
+ duk_small_uint_t flags,
+ duk_small_int_t neg) {
duk_small_int_t k;
duk_small_int_t pos, pos_end;
duk_small_int_t expt;
@@ -82460,7 +84062,7 @@ DUK_LOCAL void duk__dragon4_convert_and_push(duk__numconv_stringify_ctx *nc_ctx,
q += len;
}
- duk_push_lstring(ctx, (const char *) buf, (size_t) (q - buf));
+ duk_push_lstring(thr, (const char *) buf, (size_t) (q - buf));
}
/*
@@ -82639,7 +84241,7 @@ DUK_LOCAL void duk__dragon4_ctx_to_double(duk__numconv_stringify_ctx *nc_ctx, du
(unsigned long) DUK_DBLUNION_GET_LOW32(&u)));
DUK_ASSERT(expt >= 0 && expt <= 0x7ffL);
- t += expt << 20;
+ t += ((duk_uint32_t) expt) << 20;
#if 0 /* caller handles sign change */
if (negative) {
t |= 0x80000000U;
@@ -82661,7 +84263,7 @@ DUK_LOCAL void duk__dragon4_ctx_to_double(duk__numconv_stringify_ctx *nc_ctx, du
* Output: [ string ]
*/
-DUK_INTERNAL void duk_numconv_stringify(duk_context *ctx, duk_small_int_t radix, duk_small_int_t digits, duk_small_uint_t flags) {
+DUK_INTERNAL void duk_numconv_stringify(duk_hthread *thr, duk_small_int_t radix, duk_small_int_t digits, duk_small_uint_t flags) {
duk_double_t x;
duk_small_int_t c;
duk_small_int_t neg;
@@ -82669,8 +84271,8 @@ DUK_INTERNAL void duk_numconv_stringify(duk_context *ctx, duk_small_int_t radix,
duk__numconv_stringify_ctx nc_ctx_alloc; /* large context; around 2kB now */
duk__numconv_stringify_ctx *nc_ctx = &nc_ctx_alloc;
- x = (duk_double_t) duk_require_number(ctx, -1);
- duk_pop(ctx);
+ x = (duk_double_t) duk_require_number(thr, -1);
+ duk_pop(thr);
/*
* Handle special cases (NaN, infinity, zero).
@@ -82688,15 +84290,15 @@ DUK_INTERNAL void duk_numconv_stringify(duk_context *ctx, duk_small_int_t radix,
DUK_ASSERT(c == DUK_FP_NAN || DUK_SIGNBIT((double) x) == 0);
if (c == DUK_FP_NAN) {
- duk_push_hstring_stridx(ctx, DUK_STRIDX_NAN);
+ duk_push_hstring_stridx(thr, DUK_STRIDX_NAN);
return;
} else if (c == DUK_FP_INFINITE) {
if (neg) {
/* -Infinity */
- duk_push_hstring_stridx(ctx, DUK_STRIDX_MINUS_INFINITY);
+ duk_push_hstring_stridx(thr, DUK_STRIDX_MINUS_INFINITY);
} else {
/* Infinity */
- duk_push_hstring_stridx(ctx, DUK_STRIDX_INFINITY);
+ duk_push_hstring_stridx(thr, DUK_STRIDX_INFINITY);
}
return;
} else if (c == DUK_FP_ZERO) {
@@ -82730,7 +84332,7 @@ DUK_INTERNAL void duk_numconv_stringify(duk_context *ctx, duk_small_int_t radix,
*p++ = (duk_uint8_t) '-';
}
p += duk__dragon4_format_uint32(p, uval, radix);
- duk_push_lstring(ctx, (const char *) buf, (duk_size_t) (p - buf));
+ duk_push_lstring(thr, (const char *) buf, (duk_size_t) (p - buf));
return;
}
@@ -82789,7 +84391,7 @@ DUK_INTERNAL void duk_numconv_stringify(duk_context *ctx, duk_small_int_t radix,
}
DUK_DDD(DUK_DDDPRINT("count=%ld", (long) count));
DUK_ASSERT(count >= 1);
- DUK_MEMZERO((void *) nc_ctx->digits, count);
+ DUK_MEMZERO((void *) nc_ctx->digits, (size_t) count);
nc_ctx->count = count;
nc_ctx->k = 1; /* 0.000... */
neg = 0;
@@ -82851,7 +84453,7 @@ DUK_INTERNAL void duk_numconv_stringify(duk_context *ctx, duk_small_int_t radix,
*/
}
- duk__dragon4_convert_and_push(nc_ctx, ctx, radix, digits, flags, neg);
+ duk__dragon4_convert_and_push(nc_ctx, thr, radix, digits, flags, neg);
}
/*
@@ -82864,8 +84466,7 @@ DUK_INTERNAL void duk_numconv_stringify(duk_context *ctx, duk_small_int_t radix,
* fails due to an internal error, an InternalError is thrown.
*/
-DUK_INTERNAL void duk_numconv_parse(duk_context *ctx, duk_small_int_t radix, duk_small_uint_t flags) {
- duk_hthread *thr = (duk_hthread *) ctx;
+DUK_INTERNAL void duk_numconv_parse(duk_hthread *thr, duk_small_int_t radix, duk_small_uint_t flags) {
duk__numconv_stringify_ctx nc_ctx_alloc; /* large context; around 2kB now */
duk__numconv_stringify_ctx *nc_ctx = &nc_ctx_alloc;
duk_double_t res;
@@ -82885,7 +84486,7 @@ DUK_INTERNAL void duk_numconv_parse(duk_context *ctx, duk_small_int_t radix, duk
duk_small_int_t ch;
DUK_DDD(DUK_DDDPRINT("parse number: %!T, radix=%ld, flags=0x%08lx",
- (duk_tval *) duk_get_tval(ctx, -1),
+ (duk_tval *) duk_get_tval(thr, -1),
(long) radix, (unsigned long) flags));
DUK_ASSERT(radix >= 2 && radix <= 36);
@@ -82917,9 +84518,9 @@ DUK_INTERNAL void duk_numconv_parse(duk_context *ctx, duk_small_int_t radix, duk
* sometimes not. After white space trimming, all valid input
* characters are pure ASCII.
*/
- duk_trim(ctx, -1);
+ duk_trim(thr, -1);
}
- h_str = duk_require_hstring(ctx, -1);
+ h_str = duk_require_hstring(thr, -1);
DUK_ASSERT(h_str != NULL);
p = (const duk_uint8_t *) DUK_HSTRING_GET_DATA(h_str);
@@ -83158,8 +84759,8 @@ DUK_INTERNAL void duk_numconv_parse(duk_context *ctx, duk_small_int_t radix, duk
/* XXX: join these ops (multiply-accumulate), but only if
* code footprint decreases.
*/
- duk__bi_mul_small(&nc_ctx->t1, &nc_ctx->f, radix);
- duk__bi_add_small(&nc_ctx->f, &nc_ctx->t1, dig);
+ duk__bi_mul_small(&nc_ctx->t1, &nc_ctx->f, (duk_uint32_t) radix);
+ duk__bi_add_small(&nc_ctx->f, &nc_ctx->t1, (duk_uint32_t) dig);
dig_prec++;
}
} else {
@@ -83281,7 +84882,7 @@ DUK_INTERNAL void duk_numconv_parse(duk_context *ctx, duk_small_int_t radix, duk
* have enough (apparent) precision to work with.
*/
DUK_DDD(DUK_DDDPRINT("dig_prec=%ld, pad significand with zero", (long) dig_prec));
- duk__bi_mul_small_copy(&nc_ctx->f, radix, &nc_ctx->t1);
+ duk__bi_mul_small_copy(&nc_ctx->f, (duk_uint32_t) radix, &nc_ctx->t1);
DUK__BI_PRINT("f", &nc_ctx->f);
expt--;
dig_prec++;
@@ -83369,15 +84970,15 @@ DUK_INTERNAL void duk_numconv_parse(duk_context *ctx, duk_small_int_t radix, duk
if (neg) {
res = -res;
}
- duk_pop(ctx);
- duk_push_number(ctx, (double) res);
- DUK_DDD(DUK_DDDPRINT("result: %!T", (duk_tval *) duk_get_tval(ctx, -1)));
+ duk_pop(thr);
+ duk_push_number(thr, (double) res);
+ DUK_DDD(DUK_DDDPRINT("result: %!T", (duk_tval *) duk_get_tval(thr, -1)));
return;
parse_fail:
DUK_DDD(DUK_DDDPRINT("parse failed"));
- duk_pop(ctx);
- duk_push_nan(ctx);
+ duk_pop(thr);
+ duk_push_nan(thr);
return;
parse_explimit_error:
@@ -83486,7 +85087,8 @@ DUK_LOCAL duk_uint32_t duk__insert_u32(duk_re_compiler_ctx *re_ctx, duk_uint32_t
duk_small_int_t len;
len = duk_unicode_encode_xutf8((duk_ucodepoint_t) x, buf);
- DUK_BW_INSERT_ENSURE_BYTES(re_ctx->thr, &re_ctx->bw, offset, buf, len);
+ DUK_ASSERT(len >= 0);
+ DUK_BW_INSERT_ENSURE_BYTES(re_ctx->thr, &re_ctx->bw, offset, buf, (duk_size_t) len);
return (duk_uint32_t) len;
}
@@ -83628,71 +85230,213 @@ DUK_LOCAL duk_uint32_t duk__append_jump_offset(duk_re_compiler_ctx *re_ctx, duk_
/*
* duk_re_range_callback for generating character class ranges.
*
- * When ignoreCase is false, the range is simply emitted as is.
- * We don't, for instance, eliminate duplicates or overlapping
- * ranges in a character class.
- *
- * When ignoreCase is true, the range needs to be normalized through
- * canonicalization. Unfortunately a canonicalized version of a
- * continuous range is not necessarily continuous (e.g. [x-{] is
- * continuous but [X-{] is not). The current algorithm creates the
- * canonicalized range(s) space efficiently at the cost of compile
- * time execution time (see doc/regexp.rst for discussion).
- *
- * Note that the ctx->nranges is a context-wide temporary value
- * (this is OK because there cannot be multiple character classes
- * being parsed simultaneously).
- */
+ * When ignoreCase is false, the range is simply emitted as is. We don't,
+ * for instance, eliminate duplicates or overlapping ranges in a character
+ * class.
+ *
+ * When ignoreCase is true but the 'direct' flag is set, the caller knows
+ * that the range canonicalizes to itself for case insensitive matching,
+ * so the range is emitted as is. This is mainly useful for built-in ranges
+ * like \W.
+ *
+ * Otherwise, when ignoreCase is true, the range needs to be normalized
+ * through canonicalization. Unfortunately a canonicalized version of a
+ * continuous range is not necessarily continuous (e.g. [x-{] is continuous
+ * but [X-{] is not). As a result, a single input range may expand to a lot
+ * of output ranges. The current algorithm creates the canonicalized ranges
+ * footprint efficiently at the cost of compile time execution time; see
+ * doc/regexp.rst for discussion, and some more details below.
+ *
+ * Note that the ctx->nranges is a context-wide temporary value. This is OK
+ * because there cannot be multiple character classes being parsed
+ * simultaneously.
+ *
+ * More detail on canonicalization:
+ *
+ * Conceptually, a range is canonicalized by scanning the entire range,
+ * normalizing each codepoint by converting it to uppercase, and generating
+ * a set of result ranges.
+ *
+ * Ideally a minimal set of output ranges would be emitted by merging all
+ * possible ranges even if they're emitted out of sequence. Because the
+ * input string is also case normalized during matching, some codepoints
+ * never occur at runtime; these "don't care" codepoints can be included or
+ * excluded from ranges when merging/optimizing ranges.
+ *
+ * The current algorithm does not do optimal range merging. Rather, output
+ * codepoints are generated in sequence, and when the output codepoints are
+ * continuous (CP, CP+1, CP+2, ...), they are merged locally into as large a
+ * range as possible. A small canonicalization bitmap is used to reduce
+ * actual codepoint canonicalizations which are quite slow at present. The
+ * bitmap provides a "codepoint block is continuous with respect to
+ * canonicalization" for N-codepoint blocks. This allows blocks to be
+ * skipped quickly.
+ *
+ * There are a number of shortcomings and future work here:
+ *
+ * - Individual codepoint normalizations are slow because they involve
+ * walking bit-packed rules without a lookup index.
+ *
+ * - The conceptual algorithm needs to canonicalize every codepoint in the
+ * input range to figure out the output range(s). Even with the small
+ * canonicalization bitmap the algorithm runs quite slowly for worst case
+ * inputs. There are many data structure alternatives to improve this.
+ *
+ * - While the current algorithm generates maximal output ranges when the
+ * output codepoints are emitted linearly, output ranges are not sorted or
+ * merged otherwise. In the worst case a lot of ranges are emitted when
+ * most of the ranges could be merged. In this process one could take
+ * advantage of "don't care" codepoints, which are never matched against at
+ * runtime due to canonicalization of input codepoints before comparison,
+ * to merge otherwise discontinuous output ranges.
+ *
+ * - The runtime data structure is just a linear list of ranges to match
+ * against. This can be quite slow if there are a lot of output ranges.
+ * There are various ways to make matching against the ranges faster,
+ * e.g. sorting the ranges and using a binary search; skip lists; tree
+ * based representations; full or approximate codepoint bitmaps, etc.
+ *
+ * - Only BMP is supported, codepoints above BMP are assumed to canonicalize
+ * to themselves. For now this is one place where we don't want to
+ * support chars outside the BMP, because the exhaustive search would be
+ * massively larger. It would be possible to support non-BMP with a
+ * different algorithm, or perhaps doing case normalization only at match
+ * time.
+ */
+
+DUK_LOCAL void duk__regexp_emit_range(duk_re_compiler_ctx *re_ctx, duk_codepoint_t r1, duk_codepoint_t r2) {
+ DUK_ASSERT(r2 >= r1);
+ duk__append_u32(re_ctx, (duk_uint32_t) r1);
+ duk__append_u32(re_ctx, (duk_uint32_t) r2);
+ re_ctx->nranges++;
+}
+
+#if defined(DUK_USE_REGEXP_CANON_BITMAP)
+/* Find next canonicalization discontinuity (conservative estimate) starting
+ * from 'start', not exceeding 'end'. If continuity is fine up to 'end'
+ * inclusive, returns end. Minimum possible return value is start.
+ */
+DUK_LOCAL duk_codepoint_t duk__re_canon_next_discontinuity(duk_codepoint_t start, duk_codepoint_t end) {
+ duk_uint_t start_blk;
+ duk_uint_t end_blk;
+ duk_uint_t blk;
+ duk_uint_t offset;
+ duk_uint8_t mask;
+
+ /* Inclusive block range. */
+ DUK_ASSERT(start >= 0);
+ DUK_ASSERT(end >= 0);
+ DUK_ASSERT(end >= start);
+ start_blk = (duk_uint_t) (start >> DUK_CANON_BITMAP_BLKSHIFT);
+ end_blk = (duk_uint_t) (end >> DUK_CANON_BITMAP_BLKSHIFT);
+
+ for (blk = start_blk; blk <= end_blk; blk++) {
+ offset = blk >> 3;
+ mask = 1U << (blk & 0x07);
+ if (offset >= sizeof(duk_unicode_re_canon_bitmap)) {
+ /* Reached non-BMP range which is assumed continuous. */
+ return end;
+ }
+ DUK_ASSERT(offset < sizeof(duk_unicode_re_canon_bitmap));
+ if ((duk_unicode_re_canon_bitmap[offset] & mask) == 0) {
+ /* Block is discontinuous, continuity is guaranteed
+ * only up to end of previous block (+1 for exclusive
+ * return value => start of current block). Start
+ * block requires special handling.
+ */
+ if (blk > start_blk) {
+ return (duk_codepoint_t) (blk << DUK_CANON_BITMAP_BLKSHIFT);
+ } else {
+ return start;
+ }
+ }
+ }
+ DUK_ASSERT(blk == end_blk + 1); /* Reached end block which is continuous. */
+ return end;
+}
+#else /* DUK_USE_REGEXP_CANON_BITMAP */
+DUK_LOCAL duk_codepoint_t duk__re_canon_next_discontinuity(duk_codepoint_t start, duk_codepoint_t end) {
+ DUK_ASSERT(start >= 0);
+ DUK_ASSERT(end >= 0);
+ DUK_ASSERT(end >= start);
+ if (start >= 0x10000) {
+ /* Even without the bitmap, treat non-BMP as continuous. */
+ return end;
+ }
+ return start;
+}
+#endif /* DUK_USE_REGEXP_CANON_BITMAP */
-DUK_LOCAL void duk__generate_ranges(void *userdata, duk_codepoint_t r1, duk_codepoint_t r2, duk_bool_t direct) {
+DUK_LOCAL void duk__regexp_generate_ranges(void *userdata, duk_codepoint_t r1, duk_codepoint_t r2, duk_bool_t direct) {
duk_re_compiler_ctx *re_ctx = (duk_re_compiler_ctx *) userdata;
+ duk_codepoint_t r_start;
+ duk_codepoint_t r_end;
+ duk_codepoint_t i;
+ duk_codepoint_t t;
+ duk_codepoint_t r_disc;
- DUK_DD(DUK_DDPRINT("duk__generate_ranges(): re_ctx=%p, range=[%ld,%ld] direct=%ld",
+ DUK_DD(DUK_DDPRINT("duk__regexp_generate_ranges(): re_ctx=%p, range=[%ld,%ld] direct=%ld",
(void *) re_ctx, (long) r1, (long) r2, (long) direct));
- if (!direct && (re_ctx->re_flags & DUK_RE_FLAG_IGNORE_CASE)) {
- /*
- * Canonicalize a range, generating result ranges as necessary.
- * Needs to exhaustively scan the entire range (at most 65536
- * code points). If 'direct' is set, caller (lexer) has ensured
- * that the range is already canonicalization compatible (this
- * is used to avoid unnecessary canonicalization of built-in
- * ranges like \W, which are not affected by canonicalization).
- *
- * NOTE: here is one place where we don't want to support chars
- * outside the BMP, because the exhaustive search would be
- * massively larger.
+ DUK_ASSERT(r2 >= r1); /* SyntaxError for out of order range. */
+
+ if (direct || (re_ctx->re_flags & DUK_RE_FLAG_IGNORE_CASE) == 0) {
+ DUK_DD(DUK_DDPRINT("direct or not case sensitive, emit range: [%ld,%ld]", (long) r1, (long) r2));
+ duk__regexp_emit_range(re_ctx, r1, r2);
+ return;
+ }
+
+ DUK_DD(DUK_DDPRINT("case sensitive, process range: [%ld,%ld]", (long) r1, (long) r2));
+
+ r_start = duk_unicode_re_canonicalize_char(re_ctx->thr, r1);
+ r_end = r_start;
+
+ for (i = r1 + 1; i <= r2;) {
+ /* Input codepoint space processed up to i-1, and
+ * current range in r_{start,end} is up-to-date
+ * (inclusive) and may either break or continue.
*/
+ r_disc = duk__re_canon_next_discontinuity(i, r2);
+ DUK_ASSERT(r_disc >= i);
+ DUK_ASSERT(r_disc <= r2);
- duk_codepoint_t i;
- duk_codepoint_t t;
- duk_codepoint_t r_start, r_end;
+ r_end += r_disc - i; /* May be zero. */
+ t = duk_unicode_re_canonicalize_char(re_ctx->thr, r_disc);
+ if (t == r_end + 1) {
+ /* Not actually a discontinuity, continue range
+ * to r_disc and recheck.
+ */
+ r_end = t;
+ } else {
+ duk__regexp_emit_range(re_ctx, r_start, r_end);
+ r_start = t;
+ r_end = t;
+ }
+ i = r_disc + 1; /* Guarantees progress. */
+ }
+ duk__regexp_emit_range(re_ctx, r_start, r_end);
- r_start = duk_unicode_re_canonicalize_char(re_ctx->thr, r1);
- r_end = r_start;
- for (i = r1 + 1; i <= r2; i++) {
- t = duk_unicode_re_canonicalize_char(re_ctx->thr, i);
- if (t == r_end + 1) {
- r_end = t;
- } else {
- DUK_DD(DUK_DDPRINT("canonicalized, emit range: [%ld,%ld]", (long) r_start, (long) r_end));
- duk__append_u32(re_ctx, (duk_uint32_t) r_start);
- duk__append_u32(re_ctx, (duk_uint32_t) r_end);
- re_ctx->nranges++;
- r_start = t;
- r_end = t;
- }
- }
- DUK_DD(DUK_DDPRINT("canonicalized, emit range: [%ld,%ld]", (long) r_start, (long) r_end));
- duk__append_u32(re_ctx, (duk_uint32_t) r_start);
- duk__append_u32(re_ctx, (duk_uint32_t) r_end);
- re_ctx->nranges++;
- } else {
- DUK_DD(DUK_DDPRINT("direct, emit range: [%ld,%ld]", (long) r1, (long) r2));
- duk__append_u32(re_ctx, (duk_uint32_t) r1);
- duk__append_u32(re_ctx, (duk_uint32_t) r2);
- re_ctx->nranges++;
+#if 0 /* Exhaustive search, very slow. */
+ r_start = duk_unicode_re_canonicalize_char(re_ctx->thr, r1);
+ r_end = r_start;
+ for (i = r1 + 1; i <= r2; i++) {
+ t = duk_unicode_re_canonicalize_char(re_ctx->thr, i);
+ if (t == r_end + 1) {
+ r_end = t;
+ } else {
+ DUK_DD(DUK_DDPRINT("canonicalized, emit range: [%ld,%ld]", (long) r_start, (long) r_end));
+ duk__append_u32(re_ctx, (duk_uint32_t) r_start);
+ duk__append_u32(re_ctx, (duk_uint32_t) r_end);
+ re_ctx->nranges++;
+ r_start = t;
+ r_end = t;
+ }
}
+ DUK_DD(DUK_DDPRINT("canonicalized, emit range: [%ld,%ld]", (long) r_start, (long) r_end));
+ duk__append_u32(re_ctx, (duk_uint32_t) r_start);
+ duk__append_u32(re_ctx, (duk_uint32_t) r_end);
+ re_ctx->nranges++;
+#endif
}
/*
@@ -83827,21 +85571,21 @@ DUK_LOCAL void duk__parse_disjunction(duk_re_compiler_ctx *re_ctx, duk_bool_t ex
duk_uint32_t offset;
DUK_ASSERT(unpatched_disjunction_split >= 0);
- offset = unpatched_disjunction_jump;
+ offset = (duk_uint32_t) unpatched_disjunction_jump;
offset += duk__insert_jump_offset(re_ctx,
offset,
(duk_int32_t) (DUK__RE_BUFLEN(re_ctx) - offset));
/* offset is now target of the pending split (right after jump) */
duk__insert_jump_offset(re_ctx,
- unpatched_disjunction_split,
- offset - unpatched_disjunction_split);
+ (duk_uint32_t) unpatched_disjunction_split,
+ (duk_int32_t) offset - unpatched_disjunction_split);
}
/* add a new pending split to the beginning of the entire disjunction */
(void) duk__insert_u32(re_ctx,
entry_offset,
DUK_REOP_SPLIT1); /* prefer direct execution */
- unpatched_disjunction_split = entry_offset + 1; /* +1 for opcode */
+ unpatched_disjunction_split = (duk_int32_t) (entry_offset + 1); /* +1 for opcode */
/* add a new pending match jump for latest finished alternative */
duk__append_reop(re_ctx, DUK_REOP_JUMP);
@@ -83888,14 +85632,14 @@ DUK_LOCAL void duk__parse_disjunction(duk_re_compiler_ctx *re_ctx, duk_bool_t ex
}
duk__append_reop(re_ctx, DUK_REOP_MATCH); /* complete 'sub atom' */
- atom_code_length = (duk_int32_t) (DUK__RE_BUFLEN(re_ctx) - atom_start_offset);
+ atom_code_length = (duk_int32_t) (DUK__RE_BUFLEN(re_ctx) - (duk_size_t) atom_start_offset);
- offset = atom_start_offset;
+ offset = (duk_uint32_t) atom_start_offset;
if (re_ctx->curr_token.greedy) {
offset += duk__insert_u32(re_ctx, offset, DUK_REOP_SQGREEDY);
offset += duk__insert_u32(re_ctx, offset, qmin);
offset += duk__insert_u32(re_ctx, offset, qmax);
- offset += duk__insert_u32(re_ctx, offset, atom_char_length);
+ offset += duk__insert_u32(re_ctx, offset, (duk_uint32_t) atom_char_length);
offset += duk__insert_jump_offset(re_ctx, offset, atom_code_length);
} else {
offset += duk__insert_u32(re_ctx, offset, DUK_REOP_SQMINIMAL);
@@ -83935,9 +85679,9 @@ DUK_LOCAL void duk__parse_disjunction(duk_re_compiler_ctx *re_ctx, duk_bool_t ex
(long) atom_start_captures, (long) re_ctx->captures));
/* insert (DUK_REOP_WIPERANGE, start, count) in reverse order so the order ends up right */
- duk__insert_u32(re_ctx, atom_start_offset, (re_ctx->captures - atom_start_captures) * 2);
- duk__insert_u32(re_ctx, atom_start_offset, (atom_start_captures + 1) * 2);
- duk__insert_u32(re_ctx, atom_start_offset, DUK_REOP_WIPERANGE);
+ duk__insert_u32(re_ctx, (duk_uint32_t) atom_start_offset, (re_ctx->captures - atom_start_captures) * 2U);
+ duk__insert_u32(re_ctx, (duk_uint32_t) atom_start_offset, (atom_start_captures + 1) * 2);
+ duk__insert_u32(re_ctx, (duk_uint32_t) atom_start_offset, DUK_REOP_WIPERANGE);
} else {
DUK_DDD(DUK_DDDPRINT("no need to wipe captures: atom_start_captures == re_ctx->captures == %ld",
(long) atom_start_captures));
@@ -83949,7 +85693,7 @@ DUK_LOCAL void duk__parse_disjunction(duk_re_compiler_ctx *re_ctx, duk_bool_t ex
tmp_qmin = re_ctx->curr_token.qmin;
tmp_qmax = re_ctx->curr_token.qmax;
while (tmp_qmin > 0) {
- duk__append_slice(re_ctx, atom_start_offset, atom_code_length);
+ duk__append_slice(re_ctx, (duk_uint32_t) atom_start_offset, (duk_uint32_t) atom_code_length);
tmp_qmin--;
if (tmp_qmax != DUK_RE_QUANTIFIER_INFINITE) {
tmp_qmax--;
@@ -83967,7 +85711,7 @@ DUK_LOCAL void duk__parse_disjunction(duk_re_compiler_ctx *re_ctx, duk_bool_t ex
*/
duk__append_reop(re_ctx, DUK_REOP_JUMP);
duk__append_jump_offset(re_ctx, atom_code_length);
- duk__append_slice(re_ctx, atom_start_offset, atom_code_length);
+ duk__append_slice(re_ctx, (duk_uint32_t) atom_start_offset, (duk_uint32_t) atom_code_length);
}
if (re_ctx->curr_token.greedy) {
duk__append_reop(re_ctx, DUK_REOP_SPLIT2); /* prefer jump */
@@ -83994,7 +85738,7 @@ DUK_LOCAL void duk__parse_disjunction(duk_re_compiler_ctx *re_ctx, duk_bool_t ex
*/
duk_uint32_t offset = (duk_uint32_t) DUK__RE_BUFLEN(re_ctx);
while (tmp_qmax > 0) {
- duk__insert_slice(re_ctx, offset, atom_start_offset, atom_code_length);
+ duk__insert_slice(re_ctx, offset, (duk_uint32_t) atom_start_offset, (duk_uint32_t) atom_code_length);
if (re_ctx->curr_token.greedy) {
duk__insert_u32(re_ctx, offset, DUK_REOP_SPLIT1); /* prefer direct */
} else {
@@ -84008,7 +85752,7 @@ DUK_LOCAL void duk__parse_disjunction(duk_re_compiler_ctx *re_ctx, duk_bool_t ex
}
/* remove the original 'template' atom */
- duk__remove_slice(re_ctx, atom_start_offset, atom_code_length);
+ duk__remove_slice(re_ctx, (duk_uint32_t) atom_start_offset, (duk_uint32_t) atom_code_length);
}
/* 'taint' result as complex */
@@ -84076,7 +85820,7 @@ DUK_LOCAL void duk__parse_disjunction(duk_re_compiler_ctx *re_ctx, duk_bool_t ex
duk__append_reop(re_ctx, DUK_REOP_CHAR);
ch = re_ctx->curr_token.num;
if (re_ctx->re_flags & DUK_RE_FLAG_IGNORE_CASE) {
- ch = duk_unicode_re_canonicalize_char(re_ctx->thr, ch);
+ ch = (duk_uint32_t) duk_unicode_re_canonicalize_char(re_ctx->thr, (duk_codepoint_t) ch);
}
duk__append_u32(re_ctx, ch);
break;
@@ -84103,8 +85847,8 @@ DUK_LOCAL void duk__parse_disjunction(duk_re_compiler_ctx *re_ctx, duk_bool_t ex
DUK_ASSERT(DUK_RETOK_ATOM_WHITE == DUK_RETOK_ATOM_DIGIT + 2);
DUK_ASSERT(DUK_RETOK_ATOM_WORD_CHAR == DUK_RETOK_ATOM_DIGIT + 4);
- idx = (re_ctx->curr_token.t - DUK_RETOK_ATOM_DIGIT) >> 1;
- DUK_ASSERT(idx <= 2); /* Assume continuous token numbers; also checks negative underflow. */
+ idx = (duk_small_uint_t) ((re_ctx->curr_token.t - DUK_RETOK_ATOM_DIGIT) >> 1U);
+ DUK_ASSERT(idx <= 2U); /* Assume continuous token numbers; also checks negative underflow. */
duk__append_range_atom_matcher(re_ctx, re_op, duk__re_range_lookup1[idx], duk__re_range_lookup2[idx]);
break;
@@ -84179,7 +85923,7 @@ DUK_LOCAL void duk__parse_disjunction(duk_re_compiler_ctx *re_ctx, duk_bool_t ex
/* parse ranges until character class ends */
re_ctx->nranges = 0; /* note: ctx-wide temporary */
- duk_lexer_parse_re_ranges(&re_ctx->lex, duk__generate_ranges, (void *) re_ctx);
+ duk_lexer_parse_re_ranges(&re_ctx->lex, duk__regexp_generate_ranges, (void *) re_ctx);
/* insert range count */
duk__insert_u32(re_ctx, offset, re_ctx->nranges);
@@ -84225,14 +85969,14 @@ DUK_LOCAL void duk__parse_disjunction(duk_re_compiler_ctx *re_ctx, duk_bool_t ex
duk_uint32_t offset;
DUK_ASSERT(unpatched_disjunction_split >= 0);
- offset = unpatched_disjunction_jump;
+ offset = (duk_uint32_t) unpatched_disjunction_jump;
offset += duk__insert_jump_offset(re_ctx,
offset,
(duk_int32_t) (DUK__RE_BUFLEN(re_ctx) - offset));
/* offset is now target of the pending split (right after jump) */
duk__insert_jump_offset(re_ctx,
- unpatched_disjunction_split,
- offset - unpatched_disjunction_split);
+ (duk_uint32_t) unpatched_disjunction_split,
+ (duk_int32_t) offset - unpatched_disjunction_split);
}
#if 0
@@ -84317,7 +86061,6 @@ DUK_LOCAL duk_uint32_t duk__parse_regexp_flags(duk_hthread *thr, duk_hstring *h)
*/
DUK_LOCAL void duk__create_escaped_source(duk_hthread *thr, int idx_pattern) {
- duk_context *ctx = (duk_context *) thr;
duk_hstring *h;
const duk_uint8_t *p;
duk_bufwriter_ctx bw_alloc;
@@ -84326,12 +86069,12 @@ DUK_LOCAL void duk__create_escaped_source(duk_hthread *thr, int idx_pattern) {
duk_size_t i, n;
duk_uint_fast8_t c_prev, c;
- h = duk_known_hstring(ctx, idx_pattern);
+ h = duk_known_hstring(thr, idx_pattern);
p = (const duk_uint8_t *) DUK_HSTRING_GET_DATA(h);
n = (duk_size_t) DUK_HSTRING_GET_BYTELEN(h);
if (n == 0) {
- duk_push_string(ctx, "(?:)");
+ duk_push_string(thr, "(?:)");
return;
}
@@ -84358,7 +86101,7 @@ DUK_LOCAL void duk__create_escaped_source(duk_hthread *thr, int idx_pattern) {
}
DUK_BW_SETPTR_AND_COMPACT(thr, bw, q);
- (void) duk_buffer_to_string(ctx, -1); /* Safe if input is safe. */
+ (void) duk_buffer_to_string(thr, -1); /* Safe if input is safe. */
/* [ ... escaped_source ] */
}
@@ -84379,7 +86122,6 @@ DUK_LOCAL void duk__create_escaped_source(duk_hthread *thr, int idx_pattern) {
*/
DUK_INTERNAL void duk_regexp_compile(duk_hthread *thr) {
- duk_context *ctx = (duk_context *) thr;
duk_re_compiler_ctx re_ctx;
duk_lexer_point lex_point;
duk_hstring *h_pattern;
@@ -84387,15 +86129,14 @@ DUK_INTERNAL void duk_regexp_compile(duk_hthread *thr) {
duk__re_disjunction_info ign_disj;
DUK_ASSERT(thr != NULL);
- DUK_ASSERT(ctx != NULL);
/*
* Args validation
*/
/* TypeError if fails */
- h_pattern = duk_require_hstring_notsymbol(ctx, -2);
- h_flags = duk_require_hstring_notsymbol(ctx, -1);
+ h_pattern = duk_require_hstring_notsymbol(thr, -2);
+ h_flags = duk_require_hstring_notsymbol(thr, -1);
/*
* Create normalized 'source' property (E5 Section 15.10.3).
@@ -84473,7 +86214,7 @@ DUK_INTERNAL void duk_regexp_compile(duk_hthread *thr) {
/* [ ... pattern flags escaped_source buffer ] */
DUK_BW_COMPACT(thr, &re_ctx.bw);
- (void) duk_buffer_to_string(ctx, -1); /* Safe because flags is at most 7 bit. */
+ (void) duk_buffer_to_string(thr, -1); /* Safe because flags is at most 7 bit. */
/* [ ... pattern flags escaped_source bytecode ] */
@@ -84481,11 +86222,11 @@ DUK_INTERNAL void duk_regexp_compile(duk_hthread *thr) {
* Finalize stack
*/
- duk_remove(ctx, -4); /* -> [ ... flags escaped_source bytecode ] */
- duk_remove(ctx, -3); /* -> [ ... escaped_source bytecode ] */
+ duk_remove(thr, -4); /* -> [ ... flags escaped_source bytecode ] */
+ duk_remove(thr, -3); /* -> [ ... escaped_source bytecode ] */
DUK_DD(DUK_DDPRINT("regexp compilation successful, bytecode: %!T, escaped source: %!T",
- (duk_tval *) duk_get_tval(ctx, -1), (duk_tval *) duk_get_tval(ctx, -2)));
+ (duk_tval *) duk_get_tval(thr, -1), (duk_tval *) duk_get_tval(thr, -2)));
}
/*
@@ -84499,21 +86240,20 @@ DUK_INTERNAL void duk_regexp_compile(duk_hthread *thr) {
*/
DUK_INTERNAL void duk_regexp_create_instance(duk_hthread *thr) {
- duk_context *ctx = (duk_context *) thr;
duk_hobject *h;
/* [ ... escaped_source bytecode ] */
- duk_push_object(ctx);
- h = duk_known_hobject(ctx, -1);
- duk_insert(ctx, -3);
+ duk_push_object(thr);
+ h = duk_known_hobject(thr, -1);
+ duk_insert(thr, -3);
/* [ ... regexp_object escaped_source bytecode ] */
DUK_HOBJECT_SET_CLASS_NUMBER(h, DUK_HOBJECT_CLASS_REGEXP);
DUK_HOBJECT_SET_PROTOTYPE_UPDREF(thr, h, thr->builtins[DUK_BIDX_REGEXP_PROTOTYPE]);
- duk_xdef_prop_stridx_short(ctx, -3, DUK_STRIDX_INT_BYTECODE, DUK_PROPDESC_FLAGS_NONE);
+ duk_xdef_prop_stridx_short(thr, -3, DUK_STRIDX_INT_BYTECODE, DUK_PROPDESC_FLAGS_NONE);
/* [ ... regexp_object escaped_source ] */
@@ -84522,12 +86262,12 @@ DUK_INTERNAL void duk_regexp_create_instance(duk_hthread *thr) {
* property for the getter.
*/
- duk_xdef_prop_stridx_short(ctx, -2, DUK_STRIDX_INT_SOURCE, DUK_PROPDESC_FLAGS_NONE);
+ duk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_INT_SOURCE, DUK_PROPDESC_FLAGS_NONE);
/* [ ... regexp_object ] */
- duk_push_int(ctx, 0);
- duk_xdef_prop_stridx_short(ctx, -2, DUK_STRIDX_LAST_INDEX, DUK_PROPDESC_FLAGS_W);
+ duk_push_int(thr, 0);
+ duk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_LAST_INDEX, DUK_PROPDESC_FLAGS_W);
/* [ ... regexp_object ] */
}
@@ -85040,8 +86780,8 @@ DUK_LOCAL const duk_uint8_t *duk__match_regexp(duk_re_matcher_ctx *re_ctx, const
}
DUK_ASSERT(idx_count > 0);
- duk_require_stack((duk_context *) re_ctx->thr, 1);
- range_save = (duk_uint8_t **) duk_push_fixed_buffer_nozero((duk_context *) re_ctx->thr,
+ duk_require_stack(re_ctx->thr, 1);
+ range_save = (duk_uint8_t **) duk_push_fixed_buffer_nozero(re_ctx->thr,
sizeof(duk_uint8_t *) * idx_count);
DUK_ASSERT(range_save != NULL);
DUK_MEMCPY(range_save, re_ctx->saved + idx_start, sizeof(duk_uint8_t *) * idx_count);
@@ -85060,7 +86800,7 @@ DUK_LOCAL const duk_uint8_t *duk__match_regexp(duk_re_matcher_ctx *re_ctx, const
DUK_DDD(DUK_DDDPRINT("match: keep wiped/resaved values [%ld,%ld] (captures [%ld,%ld])",
(long) idx_start, (long) (idx_start + idx_count - 1),
(long) (idx_start / 2), (long) ((idx_start + idx_count - 1) / 2)));
- duk_pop((duk_context *) re_ctx->thr);
+ duk_pop_unsafe(re_ctx->thr);
sp = sub_sp;
goto match;
}
@@ -85072,7 +86812,7 @@ DUK_LOCAL const duk_uint8_t *duk__match_regexp(duk_re_matcher_ctx *re_ctx, const
DUK_MEMCPY((void *) (re_ctx->saved + idx_start),
(const void *) range_save,
sizeof(duk_uint8_t *) * idx_count);
- duk_pop((duk_context *) re_ctx->thr);
+ duk_pop_unsafe(re_ctx->thr);
goto fail;
}
case DUK_REOP_LOOKPOS:
@@ -85087,7 +86827,7 @@ DUK_LOCAL const duk_uint8_t *duk__match_regexp(duk_re_matcher_ctx *re_ctx, const
* The temporary save buffer is pushed on to the valstack to handle
* errors correctly. Each lookahead causes a C recursion and pushes
* more stuff on the value stack. If the C recursion limit is less
- * than the value stack spare, there is no need to check the stack.
+ * than the value stack slack, there is no need to check the stack.
* We do so regardless, just in case.
*/
@@ -85097,8 +86837,8 @@ DUK_LOCAL const duk_uint8_t *duk__match_regexp(duk_re_matcher_ctx *re_ctx, const
DUK_ASSERT(re_ctx->nsaved > 0);
- duk_require_stack((duk_context *) re_ctx->thr, 1);
- full_save = (duk_uint8_t **) duk_push_fixed_buffer_nozero((duk_context *) re_ctx->thr,
+ duk_require_stack(re_ctx->thr, 1);
+ full_save = (duk_uint8_t **) duk_push_fixed_buffer_nozero(re_ctx->thr,
sizeof(duk_uint8_t *) * re_ctx->nsaved);
DUK_ASSERT(full_save != NULL);
DUK_MEMCPY(full_save, re_ctx->saved, sizeof(duk_uint8_t *) * re_ctx->nsaved);
@@ -85117,7 +86857,7 @@ DUK_LOCAL const duk_uint8_t *duk__match_regexp(duk_re_matcher_ctx *re_ctx, const
sub_sp = duk__match_regexp(re_ctx, pc + skip, sp);
if (sub_sp) {
/* match: keep saves */
- duk_pop((duk_context *) re_ctx->thr);
+ duk_pop_unsafe(re_ctx->thr);
sp = sub_sp;
goto match;
}
@@ -85129,7 +86869,7 @@ DUK_LOCAL const duk_uint8_t *duk__match_regexp(duk_re_matcher_ctx *re_ctx, const
DUK_MEMCPY((void *) re_ctx->saved,
(const void *) full_save,
sizeof(duk_uint8_t *) * re_ctx->nsaved);
- duk_pop((duk_context *) re_ctx->thr);
+ duk_pop_unsafe(re_ctx->thr);
goto fail;
}
case DUK_REOP_BACKREFERENCE: {
@@ -85224,7 +86964,6 @@ DUK_LOCAL const duk_uint8_t *duk__match_regexp(duk_re_matcher_ctx *re_ctx, const
*/
DUK_LOCAL void duk__regexp_match_helper(duk_hthread *thr, duk_small_int_t force_global) {
- duk_context *ctx = (duk_context *) thr;
duk_re_matcher_ctx re_ctx;
duk_hobject *h_regexp;
duk_hstring *h_bytecode;
@@ -85239,11 +86978,10 @@ DUK_LOCAL void duk__regexp_match_helper(duk_hthread *thr, duk_small_int_t force_
duk_uint32_t char_offset;
DUK_ASSERT(thr != NULL);
- DUK_ASSERT(ctx != NULL);
DUK_DD(DUK_DDPRINT("regexp match: regexp=%!T, input=%!T",
- (duk_tval *) duk_get_tval(ctx, -2),
- (duk_tval *) duk_get_tval(ctx, -1)));
+ (duk_tval *) duk_get_tval(thr, -2),
+ (duk_tval *) duk_get_tval(thr, -1)));
/*
* Regexp instance check, bytecode check, input coercion.
@@ -85252,16 +86990,16 @@ DUK_LOCAL void duk__regexp_match_helper(duk_hthread *thr, duk_small_int_t force_
*/
/* TypeError if wrong; class check, see E5 Section 15.10.6 */
- h_regexp = duk_require_hobject_with_class(ctx, -2, DUK_HOBJECT_CLASS_REGEXP);
+ h_regexp = duk_require_hobject_with_class(thr, -2, DUK_HOBJECT_CLASS_REGEXP);
DUK_ASSERT(h_regexp != NULL);
DUK_ASSERT(DUK_HOBJECT_GET_CLASS_NUMBER(h_regexp) == DUK_HOBJECT_CLASS_REGEXP);
DUK_UNREF(h_regexp);
- h_input = duk_to_hstring(ctx, -1);
+ h_input = duk_to_hstring(thr, -1);
DUK_ASSERT(h_input != NULL);
- duk_get_prop_stridx_short(ctx, -2, DUK_STRIDX_INT_BYTECODE); /* [ ... re_obj input ] -> [ ... re_obj input bc ] */
- h_bytecode = duk_require_hstring(ctx, -1); /* no regexp instance should exist without a non-configurable bytecode property */
+ duk_get_prop_stridx_short(thr, -2, DUK_STRIDX_INT_BYTECODE); /* [ ... re_obj input ] -> [ ... re_obj input bc ] */
+ h_bytecode = duk_require_hstring(thr, -1); /* no regexp instance should exist without a non-configurable bytecode property */
DUK_ASSERT(h_bytecode != NULL);
/*
@@ -85294,14 +87032,14 @@ DUK_LOCAL void duk__regexp_match_helper(duk_hthread *thr, duk_small_int_t force_
re_ctx.bytecode = pc;
DUK_ASSERT(DUK_RE_FLAG_GLOBAL < 0x10000UL); /* must fit into duk_small_int_t */
- global = (duk_small_int_t) (force_global | (re_ctx.re_flags & DUK_RE_FLAG_GLOBAL));
+ global = (duk_small_int_t) (force_global | (duk_small_int_t) (re_ctx.re_flags & DUK_RE_FLAG_GLOBAL));
DUK_ASSERT(re_ctx.nsaved >= 2);
DUK_ASSERT((re_ctx.nsaved % 2) == 0);
- p_buf = (duk_uint8_t *) duk_push_fixed_buffer(ctx, sizeof(duk_uint8_t *) * re_ctx.nsaved); /* rely on zeroing */
+ p_buf = (duk_uint8_t *) duk_push_fixed_buffer(thr, sizeof(duk_uint8_t *) * re_ctx.nsaved); /* rely on zeroing */
DUK_UNREF(p_buf);
- re_ctx.saved = (const duk_uint8_t **) duk_get_buffer(ctx, -1, NULL);
+ re_ctx.saved = (const duk_uint8_t **) duk_get_buffer(thr, -1, NULL);
DUK_ASSERT(re_ctx.saved != NULL);
/* [ ... re_obj input bc saved_buf ] */
@@ -85339,10 +87077,10 @@ DUK_LOCAL void duk__regexp_match_helper(duk_hthread *thr, duk_small_int_t force_
/* [ ... re_obj input bc saved_buf ] */
- duk_get_prop_stridx_short(ctx, -4, DUK_STRIDX_LAST_INDEX); /* -> [ ... re_obj input bc saved_buf lastIndex ] */
- (void) duk_to_int(ctx, -1); /* ToInteger(lastIndex) */
- d = duk_get_number(ctx, -1); /* integer, but may be +/- Infinite, +/- zero (not NaN, though) */
- duk_pop(ctx);
+ duk_get_prop_stridx_short(thr, -4, DUK_STRIDX_LAST_INDEX); /* -> [ ... re_obj input bc saved_buf lastIndex ] */
+ (void) duk_to_int(thr, -1); /* ToInteger(lastIndex) */
+ d = duk_get_number(thr, -1); /* integer, but may be +/- Infinite, +/- zero (not NaN, though) */
+ duk_pop_nodecref_unsafe(thr);
if (global) {
if (d < 0.0 || d > (double) DUK_HSTRING_GET_CHARLEN(h_input)) {
@@ -85379,7 +87117,7 @@ DUK_LOCAL void duk__regexp_match_helper(duk_hthread *thr, duk_small_int_t force_
DUK_ASSERT_DISABLE(char_offset >= 0);
DUK_ASSERT(char_offset <= DUK_HSTRING_GET_CHARLEN(h_input));
- /* Note: ctx.steps is intentionally not reset, it applies to the entire unanchored match */
+ /* Note: re_ctx.steps is intentionally not reset, it applies to the entire unanchored match */
DUK_ASSERT(re_ctx.recursion_depth == 0);
DUK_DDD(DUK_DDDPRINT("attempt match at char offset %ld; %p [%p,%p]",
@@ -85394,7 +87132,7 @@ DUK_LOCAL void duk__regexp_match_helper(duk_hthread *thr, duk_small_int_t force_
*
* - Clearing saved[] is not necessary because backtracking does it
*
- * - Backtracking also rewinds ctx.recursion back to zero, unless an
+ * - Backtracking also rewinds re_ctx.recursion back to zero, unless an
* internal/limit error occurs (which causes a longjmp())
*
* - If we supported anchored matches, we would break out here
@@ -85465,10 +87203,10 @@ DUK_LOCAL void duk__regexp_match_helper(duk_hthread *thr, duk_small_int_t force_
* objects are usually short lived.
*/
- duk_push_array(ctx);
+ duk_push_array(thr);
#if defined(DUK_USE_ASSERTIONS)
- h_res = duk_require_hobject(ctx, -1);
+ h_res = duk_require_hobject(thr, -1);
DUK_ASSERT(DUK_HOBJECT_HAS_EXTENSIBLE(h_res));
DUK_ASSERT(DUK_HOBJECT_HAS_EXOTIC_ARRAY(h_res));
DUK_ASSERT(DUK_HOBJECT_GET_CLASS_NUMBER(h_res) == DUK_HOBJECT_CLASS_ARRAY);
@@ -85476,11 +87214,11 @@ DUK_LOCAL void duk__regexp_match_helper(duk_hthread *thr, duk_small_int_t force_
/* [ ... re_obj input bc saved_buf res_obj ] */
- duk_push_u32(ctx, char_offset);
- duk_xdef_prop_stridx_short_wec(ctx, -2, DUK_STRIDX_INDEX);
+ duk_push_u32(thr, char_offset);
+ duk_xdef_prop_stridx_short_wec(thr, -2, DUK_STRIDX_INDEX);
- duk_dup_m4(ctx);
- duk_xdef_prop_stridx_short_wec(ctx, -2, DUK_STRIDX_INPUT);
+ duk_dup_m4(thr);
+ duk_xdef_prop_stridx_short_wec(thr, -2, DUK_STRIDX_INPUT);
for (i = 0; i < re_ctx.nsaved; i += 2) {
/* Captures which are undefined have NULL pointers and are returned
@@ -85488,7 +87226,7 @@ DUK_LOCAL void duk__regexp_match_helper(duk_hthread *thr, duk_small_int_t force_
* (this should, of course, never happen in practice).
*/
if (re_ctx.saved[i] && re_ctx.saved[i + 1] && re_ctx.saved[i + 1] >= re_ctx.saved[i]) {
- duk_push_lstring(ctx,
+ duk_push_lstring(thr,
(const char *) re_ctx.saved[i],
(duk_size_t) (re_ctx.saved[i+1] - re_ctx.saved[i]));
if (i == 0) {
@@ -85497,14 +87235,14 @@ DUK_LOCAL void duk__regexp_match_helper(duk_hthread *thr, duk_small_int_t force_
* will be zero). Also assumes clen reflects the
* correct char length.
*/
- char_end_offset = char_offset + (duk_uint32_t) duk_get_length(ctx, -1); /* add charlen */
+ char_end_offset = char_offset + (duk_uint32_t) duk_get_length(thr, -1); /* add charlen */
}
} else {
- duk_push_undefined(ctx);
+ duk_push_undefined(thr);
}
/* [ ... re_obj input bc saved_buf res_obj val ] */
- duk_put_prop_index(ctx, -2, i / 2);
+ duk_put_prop_index(thr, -2, (duk_uarridx_t) (i / 2));
}
/* [ ... re_obj input bc saved_buf res_obj ] */
@@ -85513,8 +87251,8 @@ DUK_LOCAL void duk__regexp_match_helper(duk_hthread *thr, duk_small_int_t force_
if (global) {
/* global regexp: lastIndex updated on match */
- duk_push_u32(ctx, char_end_offset);
- duk_put_prop_stridx_short(ctx, -6, DUK_STRIDX_LAST_INDEX);
+ duk_push_u32(thr, char_end_offset);
+ duk_put_prop_stridx_short(thr, -6, DUK_STRIDX_LAST_INDEX);
} else {
/* non-global regexp: lastIndex never updated on match */
;
@@ -85528,21 +87266,21 @@ DUK_LOCAL void duk__regexp_match_helper(duk_hthread *thr, duk_small_int_t force_
DUK_DDD(DUK_DDDPRINT("regexp does not match"));
- duk_push_null(ctx);
+ duk_push_null(thr);
/* [ ... re_obj input bc saved_buf res_obj ] */
- duk_push_int(ctx, 0);
- duk_put_prop_stridx_short(ctx, -6, DUK_STRIDX_LAST_INDEX);
+ duk_push_int(thr, 0);
+ duk_put_prop_stridx_short(thr, -6, DUK_STRIDX_LAST_INDEX);
}
/* [ ... re_obj input bc saved_buf res_obj ] */
- duk_insert(ctx, -5);
+ duk_insert(thr, -5);
/* [ ... res_obj re_obj input bc saved_buf ] */
- duk_pop_n(ctx, 4);
+ duk_pop_n_unsafe(thr, 4);
/* [ ... res_obj ] */
@@ -85953,6 +87691,7 @@ DUK_LOCAL duk_uint_t duk__selftest_double_rounding(void) {
DUK_LOCAL duk_uint_t duk__selftest_fmod(void) {
duk_uint_t error_count = 0;
duk__test_double_union u1, u2;
+ volatile duk_double_t t1, t2, t3;
/* fmod() with integer argument and exponent 2^32 is used by e.g.
* ToUint32() and some Duktape internals.
@@ -85969,6 +87708,22 @@ DUK_LOCAL duk_uint_t duk__selftest_fmod(void) {
u2.d = 10.0;
DUK__DBLUNION_CMP_TRUE(&u1, &u2);
+ /* 52-bit integer split into two parts:
+ * >>> 0x1fedcba9876543
+ * 8987183256397123
+ * >>> float(0x1fedcba9876543) / float(2**53)
+ * 0.9977777777777778
+ */
+ u1.d = DUK_FMOD(8987183256397123.0, 4294967296.0);
+ u2.d = (duk_double_t) 0xa9876543UL;
+ DUK__DBLUNION_CMP_TRUE(&u1, &u2);
+ t1 = 8987183256397123.0;
+ t2 = 4294967296.0;
+ t3 = t1 / t2;
+ u1.d = DUK_FLOOR(t3);
+ u2.d = (duk_double_t) 0x1fedcbUL;
+ DUK__DBLUNION_CMP_TRUE(&u1, &u2);
+
/* C99 behavior is for fmod() result sign to mathc argument sign. */
u1.d = DUK_FMOD(-10.0, 4294967296.0);
u2.d = -10.0;
@@ -86027,7 +87782,7 @@ DUK_LOCAL duk_uint_t duk__selftest_64bit_arithmetic(void) {
/* Catch a double-to-int64 cast issue encountered in practice. */
d = 2147483648.0;
i = (duk_int64_t) d;
- if (i != 0x80000000LL) {
+ if (i != DUK_I64_CONSTANT(0x80000000)) {
DUK__FAILED("casting 2147483648.0 to duk_int64_t failed");
}
#else
@@ -86122,7 +87877,7 @@ DUK_LOCAL duk_uint_t duk__selftest_alloc_funcs(duk_alloc_function alloc_func,
}
for (i = 1; i <= 256; i++) {
- ptr = alloc_func(udata, i);
+ ptr = alloc_func(udata, (duk_size_t) i);
if (ptr == NULL) {
DUK_D(DUK_DPRINT("alloc failed, ignore"));
continue; /* alloc failed, ignore */
@@ -86231,9 +87986,9 @@ DUK_INTERNAL DUK_ALWAYS_INLINE void duk_tval_set_number_chkfast_fast(duk_tval *t
if (shift >= 0 && shift <= 46) { /* exponents 1023 to 1069 */
duk_int64_t t;
- if (((0x000fffffffffffffLL >> shift) & i) == 0) {
- t = i | 0x0010000000000000LL; /* implicit leading one */
- t = t & 0x001fffffffffffffLL;
+ if (((DUK_I64_CONSTANT(0x000fffffffffffff) >> shift) & i) == 0) {
+ t = i | DUK_I64_CONSTANT(0x0010000000000000); /* implicit leading one */
+ t = t & DUK_I64_CONSTANT(0x001fffffffffffff);
t = t >> (52 - shift);
if (i < 0) {
t = -t;
@@ -86242,13 +87997,13 @@ DUK_INTERNAL DUK_ALWAYS_INLINE void duk_tval_set_number_chkfast_fast(duk_tval *t
return;
}
} else if (shift == -1023) { /* exponent 0 */
- if (i >= 0 && (i & 0x000fffffffffffffLL) == 0) {
+ if (i >= 0 && (i & DUK_I64_CONSTANT(0x000fffffffffffff)) == 0) {
/* Note: reject negative zero. */
DUK_TVAL_SET_FASTINT(tv, (duk_int64_t) 0);
return;
}
} else if (shift == 47) { /* exponent 1070 */
- if (i < 0 && (i & 0x000fffffffffffffLL) == 0) {
+ if (i < 0 && (i & DUK_I64_CONSTANT(0x000fffffffffffff)) == 0) {
DUK_TVAL_SET_FASTINT(tv, (duk_int64_t) DUK_FASTINT_MIN);
return;
}
@@ -86274,15 +88029,15 @@ DUK_INTERNAL DUK_ALWAYS_INLINE duk_double_t duk_tval_get_number_packed(duk_tval
t = (duk_uint64_t) DUK_DBLUNION_GET_UINT64(tv);
if ((t >> 48) != DUK_TAG_FASTINT) {
return tv->d;
- } else if (t & 0x0000800000000000ULL) {
+ } else if (t & DUK_U64_CONSTANT(0x0000800000000000)) {
t = (duk_uint64_t) (-((duk_int64_t) t)); /* avoid unary minus on unsigned */
- t = t & 0x0000ffffffffffffULL; /* negative */
- t |= 0xc330000000000000ULL;
+ t = t & DUK_U64_CONSTANT(0x0000ffffffffffff); /* negative */
+ t |= DUK_U64_CONSTANT(0xc330000000000000);
DUK_DBLUNION_SET_UINT64(&du, t);
return du.d + 4503599627370496.0; /* 1 << 52 */
} else if (t != 0) {
- t &= 0x0000ffffffffffffULL; /* positive */
- t |= 0x4330000000000000ULL;
+ t &= DUK_U64_CONSTANT(0x0000ffffffffffff); /* positive */
+ t |= DUK_U64_CONSTANT(0x4330000000000000);
DUK_DBLUNION_SET_UINT64(&du, t);
return du.d - 4503599627370496.0; /* 1 << 52 */
} else {
@@ -86301,11 +88056,11 @@ DUK_INTERNAL DUK_ALWAYS_INLINE duk_double_t duk_tval_get_number_unpacked(duk_tva
if (tv->t == DUK_TAG_FASTINT) {
if (tv->v.fi >= 0) {
- t = 0x4330000000000000ULL | (duk_uint64_t) tv->v.fi;
+ t = DUK_U64_CONSTANT(0x4330000000000000) | (duk_uint64_t) tv->v.fi;
DUK_DBLUNION_SET_UINT64(&du, t);
return du.d - 4503599627370496.0; /* 1 << 52 */
} else {
- t = 0xc330000000000000ULL | (duk_uint64_t) (-tv->v.fi);
+ t = DUK_U64_CONSTANT(0xc330000000000000) | (duk_uint64_t) (-tv->v.fi);
DUK_DBLUNION_SET_UINT64(&du, t);
return du.d + 4503599627370496.0; /* 1 << 52 */
}
@@ -86324,11 +88079,11 @@ DUK_INTERNAL DUK_ALWAYS_INLINE duk_double_t duk_tval_get_number_unpacked_fastint
DUK_ASSERT(tv->t == DUK_TAG_FASTINT);
if (tv->v.fi >= 0) {
- t = 0x4330000000000000ULL | (duk_uint64_t) tv->v.fi;
+ t = DUK_U64_CONSTANT(0x4330000000000000) | (duk_uint64_t) tv->v.fi;
DUK_DBLUNION_SET_UINT64(&du, t);
return du.d - 4503599627370496.0; /* 1 << 52 */
} else {
- t = 0xc330000000000000ULL | (duk_uint64_t) (-tv->v.fi);
+ t = DUK_U64_CONSTANT(0xc330000000000000) | (duk_uint64_t) (-tv->v.fi);
DUK_DBLUNION_SET_UINT64(&du, t);
return du.d + 4503599627370496.0; /* 1 << 52 */
}
@@ -92477,6 +94232,29 @@ const duk_uint16_t duk_unicode_re_canon_lookup[65536] = {
65528L,65529L,65530L,65531L,65532L,65533L,65534L,65535L,
};
#endif
+
+#if defined(DUK_USE_REGEXP_CANON_BITMAP)
+/*
+ * Automatically generated by extract_caseconv.py, do not edit!
+ */
+
+const duk_uint8_t duk_unicode_re_canon_bitmap[256] = {
+23,0,224,19,1,228,255,255,255,255,255,255,255,255,255,255,255,255,255,127,
+255,255,255,255,255,255,255,255,231,247,0,16,255,227,255,255,63,255,255,
+255,255,255,255,255,1,252,255,255,255,255,255,255,255,255,255,255,255,255,
+255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+227,193,255,255,255,147,255,255,255,255,255,255,255,255,255,255,255,255,
+255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,251,
+};
+#endif
/*
* Bitstream decoder.
*/
@@ -92520,7 +94298,7 @@ DUK_INTERNAL duk_uint32_t duk_bd_decode(duk_bitdecoder_ctx *ctx, duk_small_int_t
* to be cleared, we just ignore them on next round.
*/
shift = ctx->currbits - bits;
- mask = (1 << bits) - 1;
+ mask = (((duk_uint32_t) 1U) << bits) - 1U;
tmp = (ctx->currval >> shift) & mask;
ctx->currbits = shift; /* remaining */
@@ -92592,7 +94370,7 @@ DUK_LOCAL const duk_uint8_t duk__bitpacked_lookup[16] = {
DUK_ASC_0, DUK_ASC_1, DUK_ASC_2, DUK_ASC_3,
DUK_ASC_4, DUK_ASC_5, DUK_ASC_6, DUK_ASC_7,
DUK_ASC_8, DUK_ASC_9, DUK_ASC_UNDERSCORE, DUK_ASC_SPACE,
- 0xff, 0x80, DUK_ASC_DOUBLEQUOTE, DUK_ASC_LCURLY
+ 0x82, 0x80, DUK_ASC_DOUBLEQUOTE, DUK_ASC_LCURLY
};
DUK_INTERNAL duk_small_uint_t duk_bd_decode_bitpacked_string(duk_bitdecoder_ctx *bd, duk_uint8_t *out) {
@@ -92687,7 +94465,7 @@ DUK_INTERNAL void duk_be_finish(duk_bitencoder_ctx *ctx) {
DUK_ASSERT(ctx->currbits == 0);
}
/*
- * Fast buffer writer with spare management.
+ * Fast buffer writer with slack management.
*/
/* #include duk_internal.h -> already included */
@@ -92715,21 +94493,17 @@ DUK_INTERNAL void duk_bw_init(duk_hthread *thr, duk_bufwriter_ctx *bw_ctx, duk_h
DUK_ASSERT(thr != NULL);
DUK_ASSERT(bw_ctx != NULL);
DUK_ASSERT(h_buf != NULL);
- DUK_UNREF(thr);
bw_ctx->buf = h_buf;
duk__bw_update_ptrs(thr, bw_ctx, 0, DUK_HBUFFER_DYNAMIC_GET_SIZE(h_buf));
}
DUK_INTERNAL void duk_bw_init_pushbuf(duk_hthread *thr, duk_bufwriter_ctx *bw_ctx, duk_size_t buf_size) {
- duk_context *ctx;
-
DUK_ASSERT(thr != NULL);
DUK_ASSERT(bw_ctx != NULL);
- ctx = (duk_context *) thr;
- (void) duk_push_dynamic_buffer(ctx, buf_size);
- bw_ctx->buf = (duk_hbuffer_dynamic *) duk_known_hbuffer(ctx, -1);
+ (void) duk_push_dynamic_buffer(thr, buf_size);
+ bw_ctx->buf = (duk_hbuffer_dynamic *) duk_known_hbuffer(thr, -1);
duk__bw_update_ptrs(thr, bw_ctx, 0, buf_size);
}
@@ -92749,7 +94523,7 @@ DUK_INTERNAL duk_uint8_t *duk_bw_resize(duk_hthread *thr, duk_bufwriter_ctx *bw_
*/
curr_off = (duk_size_t) (bw_ctx->p - bw_ctx->p_base);
- add_sz = (curr_off >> DUK_BW_SPARE_SHIFT) + DUK_BW_SPARE_ADD;
+ add_sz = (curr_off >> DUK_BW_SLACK_SHIFT) + DUK_BW_SLACK_ADD;
new_sz = curr_off + sz + add_sz;
if (DUK_UNLIKELY(new_sz < curr_off)) {
/* overflow */
@@ -92809,7 +94583,6 @@ DUK_INTERNAL void duk_bw_write_ensure_slice(duk_hthread *thr, duk_bufwriter_ctx
DUK_ASSERT(src_off <= DUK_BW_GET_SIZE(thr, bw));
DUK_ASSERT(len <= DUK_BW_GET_SIZE(thr, bw));
DUK_ASSERT(src_off + len <= DUK_BW_GET_SIZE(thr, bw));
- DUK_UNREF(thr);
DUK_BW_ENSURE(thr, bw, len);
duk_bw_write_raw_slice(thr, bw, src_off, len);
@@ -92826,7 +94599,7 @@ DUK_INTERNAL void duk_bw_insert_raw_bytes(duk_hthread *thr, duk_bufwriter_ctx *b
DUK_UNREF(thr);
p_base = bw->p_base;
- buf_sz = bw->p - p_base;
+ buf_sz = (duk_size_t) (bw->p - p_base); /* constrained by maximum buffer size */
move_sz = buf_sz - dst_off;
DUK_ASSERT(p_base != NULL); /* buffer size is >= 1 */
@@ -92844,7 +94617,6 @@ DUK_INTERNAL void duk_bw_insert_ensure_bytes(duk_hthread *thr, duk_bufwriter_ctx
DUK_ASSERT(bw != NULL);
DUK_ASSERT(dst_off <= DUK_BW_GET_SIZE(thr, bw));
DUK_ASSERT(buf != NULL);
- DUK_UNREF(thr);
DUK_BW_ENSURE(thr, bw, len);
duk_bw_insert_raw_bytes(thr, bw, dst_off, buf, len);
@@ -92874,7 +94646,7 @@ DUK_INTERNAL void duk_bw_insert_raw_slice(duk_hthread *thr, duk_bufwriter_ctx *b
src_off += len;
}
- buf_sz = bw->p - p_base;
+ buf_sz = (duk_size_t) (bw->p - p_base);
move_sz = buf_sz - dst_off;
DUK_ASSERT(p_base != NULL); /* buffer size is >= 1 */
@@ -92894,7 +94666,6 @@ DUK_INTERNAL void duk_bw_insert_ensure_slice(duk_hthread *thr, duk_bufwriter_ctx
DUK_ASSERT(src_off <= DUK_BW_GET_SIZE(thr, bw));
DUK_ASSERT(len <= DUK_BW_GET_SIZE(thr, bw));
DUK_ASSERT(src_off + len <= DUK_BW_GET_SIZE(thr, bw));
- DUK_UNREF(thr);
/* Don't support "straddled" source now. */
DUK_ASSERT(dst_off <= src_off || dst_off >= src_off + len);
@@ -92913,7 +94684,7 @@ DUK_INTERNAL duk_uint8_t *duk_bw_insert_raw_area(duk_hthread *thr, duk_bufwriter
DUK_UNREF(thr);
p_base = bw->p_base;
- buf_sz = bw->p - p_base;
+ buf_sz = (duk_size_t) (bw->p - p_base);
move_sz = buf_sz - off;
p_dst = p_base + off + len;
p_src = p_base + off;
@@ -92925,7 +94696,6 @@ DUK_INTERNAL duk_uint8_t *duk_bw_insert_ensure_area(duk_hthread *thr, duk_bufwri
DUK_ASSERT(thr != NULL);
DUK_ASSERT(bw != NULL);
DUK_ASSERT(off <= DUK_BW_GET_SIZE(thr, bw));
- DUK_UNREF(thr);
DUK_BW_ENSURE(thr, bw, len);
return duk_bw_insert_raw_area(thr, bw, off, len);
@@ -93169,9 +94939,9 @@ DUK_INTERNAL duk_double_t duk_util_tinyrandom_get_double(duk_hthread *thr) {
#if defined(DUK__RANDOM_XOROSHIRO128PLUS)
DUK_LOCAL DUK_ALWAYS_INLINE duk_uint64_t duk__rnd_splitmix64(duk_uint64_t *x) {
duk_uint64_t z;
- z = (*x += 0x9E3779B97F4A7C15ULL);
- z = (z ^ (z >> 30U)) * 0xBF58476D1CE4E5B9ULL;
- z = (z ^ (z >> 27U)) * 0x94D049BB133111EBULL;
+ z = (*x += DUK_U64_CONSTANT(0x9E3779B97F4A7C15));
+ z = (z ^ (z >> 30U)) * DUK_U64_CONSTANT(0xBF58476D1CE4E5B9);
+ z = (z ^ (z >> 27U)) * DUK_U64_CONSTANT(0x94D049BB133111EB);
return z ^ (z >> 31U);
}
@@ -93217,7 +94987,7 @@ DUK_INTERNAL duk_double_t duk_util_tinyrandom_get_double(duk_hthread *thr) {
* is the same so a direct assignment works. For mixed endian the
* 32-bit parts must be swapped.
*/
- v = (0x3ffULL << 52U) | (duk__xoroshiro128plus((duk_uint64_t *) thr->heap->rnd_state) >> 12U);
+ v = (DUK_U64_CONSTANT(0x3ff) << 52U) | (duk__xoroshiro128plus((duk_uint64_t *) thr->heap->rnd_state) >> 12U);
du.ull[0] = v;
#if defined(DUK_USE_DOUBLE_ME)
do {
diff --git a/content/handlers/javascript/duktape/duktape.h b/content/handlers/javascript/duktape/duktape.h
index 21257d30c..a3b4f546e 100644
--- a/content/handlers/javascript/duktape/duktape.h
+++ b/content/handlers/javascript/duktape/duktape.h
@@ -1,5 +1,5 @@
/*
- * Duktape public API for Duktape 2.1.0.
+ * Duktape public API for Duktape 2.2.0.
*
* See the API reference for documentation on call semantics. The exposed,
* supported API is between the "BEGIN PUBLIC API" and "END PUBLIC API"
@@ -89,6 +89,9 @@
* * Remko Tron\u00e7on (https://el-tramo.be)
* * Romero Malaquias (rbsm@ic.ufal.br)
* * Michael Drake <michael.drake@codethink.co.uk>
+ * * Steven Don (https://github.com/shdon)
+ * * Simon Stone (https://github.com/sstone1)
+ * * \J. McC. (https://github.com/jmhmccr)
*
* Other contributions
* ===================
@@ -151,7 +154,7 @@
* development snapshots have 99 for patch level (e.g. 0.10.99 would be a
* development version after 0.10.0 but before the next official release).
*/
-#define DUK_VERSION 20100L
+#define DUK_VERSION 20200L
/* Git commit, describe, and branch for Duktape build. Useful for
* non-official snapshot builds so that application code can easily log
@@ -286,35 +289,35 @@ struct duk_time_components {
/* Number of value stack entries (in addition to actual call arguments)
* guaranteed to be allocated on entry to a Duktape/C function.
*/
-#define DUK_API_ENTRY_STACK 64
+#define DUK_API_ENTRY_STACK 64U
/* Value types, used by e.g. duk_get_type() */
-#define DUK_TYPE_MIN 0
-#define DUK_TYPE_NONE 0 /* no value, e.g. invalid index */
-#define DUK_TYPE_UNDEFINED 1 /* Ecmascript undefined */
-#define DUK_TYPE_NULL 2 /* Ecmascript null */
-#define DUK_TYPE_BOOLEAN 3 /* Ecmascript boolean: 0 or 1 */
-#define DUK_TYPE_NUMBER 4 /* Ecmascript number: double */
-#define DUK_TYPE_STRING 5 /* Ecmascript string: CESU-8 / extended UTF-8 encoded */
-#define DUK_TYPE_OBJECT 6 /* Ecmascript object: includes objects, arrays, functions, threads */
-#define DUK_TYPE_BUFFER 7 /* fixed or dynamic, garbage collected byte buffer */
-#define DUK_TYPE_POINTER 8 /* raw void pointer */
-#define DUK_TYPE_LIGHTFUNC 9 /* lightweight function pointer */
-#define DUK_TYPE_MAX 9
+#define DUK_TYPE_MIN 0U
+#define DUK_TYPE_NONE 0U /* no value, e.g. invalid index */
+#define DUK_TYPE_UNDEFINED 1U /* Ecmascript undefined */
+#define DUK_TYPE_NULL 2U /* Ecmascript null */
+#define DUK_TYPE_BOOLEAN 3U /* Ecmascript boolean: 0 or 1 */
+#define DUK_TYPE_NUMBER 4U /* Ecmascript number: double */
+#define DUK_TYPE_STRING 5U /* Ecmascript string: CESU-8 / extended UTF-8 encoded */
+#define DUK_TYPE_OBJECT 6U /* Ecmascript object: includes objects, arrays, functions, threads */
+#define DUK_TYPE_BUFFER 7U /* fixed or dynamic, garbage collected byte buffer */
+#define DUK_TYPE_POINTER 8U /* raw void pointer */
+#define DUK_TYPE_LIGHTFUNC 9U /* lightweight function pointer */
+#define DUK_TYPE_MAX 9U
/* Value mask types, used by e.g. duk_get_type_mask() */
-#define DUK_TYPE_MASK_NONE (1 << DUK_TYPE_NONE)
-#define DUK_TYPE_MASK_UNDEFINED (1 << DUK_TYPE_UNDEFINED)
-#define DUK_TYPE_MASK_NULL (1 << DUK_TYPE_NULL)
-#define DUK_TYPE_MASK_BOOLEAN (1 << DUK_TYPE_BOOLEAN)
-#define DUK_TYPE_MASK_NUMBER (1 << DUK_TYPE_NUMBER)
-#define DUK_TYPE_MASK_STRING (1 << DUK_TYPE_STRING)
-#define DUK_TYPE_MASK_OBJECT (1 << DUK_TYPE_OBJECT)
-#define DUK_TYPE_MASK_BUFFER (1 << DUK_TYPE_BUFFER)
-#define DUK_TYPE_MASK_POINTER (1 << DUK_TYPE_POINTER)
-#define DUK_TYPE_MASK_LIGHTFUNC (1 << DUK_TYPE_LIGHTFUNC)
-#define DUK_TYPE_MASK_THROW (1 << 10) /* internal flag value: throw if mask doesn't match */
-#define DUK_TYPE_MASK_PROMOTE (1 << 11) /* internal flag value: promote to object if mask matches */
+#define DUK_TYPE_MASK_NONE (1U << DUK_TYPE_NONE)
+#define DUK_TYPE_MASK_UNDEFINED (1U << DUK_TYPE_UNDEFINED)
+#define DUK_TYPE_MASK_NULL (1U << DUK_TYPE_NULL)
+#define DUK_TYPE_MASK_BOOLEAN (1U << DUK_TYPE_BOOLEAN)
+#define DUK_TYPE_MASK_NUMBER (1U << DUK_TYPE_NUMBER)
+#define DUK_TYPE_MASK_STRING (1U << DUK_TYPE_STRING)
+#define DUK_TYPE_MASK_OBJECT (1U << DUK_TYPE_OBJECT)
+#define DUK_TYPE_MASK_BUFFER (1U << DUK_TYPE_BUFFER)
+#define DUK_TYPE_MASK_POINTER (1U << DUK_TYPE_POINTER)
+#define DUK_TYPE_MASK_LIGHTFUNC (1U << DUK_TYPE_LIGHTFUNC)
+#define DUK_TYPE_MASK_THROW (1U << 10) /* internal flag value: throw if mask doesn't match */
+#define DUK_TYPE_MASK_PROMOTE (1U << 11) /* internal flag value: promote to object if mask matches */
/* Coercion hints */
#define DUK_HINT_NONE 0 /* prefer number, unless input is a Date, in which
@@ -324,52 +327,83 @@ struct duk_time_components {
#define DUK_HINT_NUMBER 2 /* prefer number */
/* Enumeration flags for duk_enum() */
-#define DUK_ENUM_INCLUDE_NONENUMERABLE (1 << 0) /* enumerate non-numerable properties in addition to enumerable */
-#define DUK_ENUM_INCLUDE_HIDDEN (1 << 1) /* enumerate hidden symbols too (in Duktape 1.x called internal properties) */
-#define DUK_ENUM_INCLUDE_SYMBOLS (1 << 2) /* enumerate symbols */
-#define DUK_ENUM_EXCLUDE_STRINGS (1 << 3) /* exclude strings */
-#define DUK_ENUM_OWN_PROPERTIES_ONLY (1 << 4) /* don't walk prototype chain, only check own properties */
-#define DUK_ENUM_ARRAY_INDICES_ONLY (1 << 5) /* only enumerate array indices */
-#define DUK_ENUM_SORT_ARRAY_INDICES (1 << 6) /* sort array indices (applied to full enumeration result, including inherited array indices) */
-#define DUK_ENUM_NO_PROXY_BEHAVIOR (1 << 7) /* enumerate a proxy object itself without invoking proxy behavior */
+#define DUK_ENUM_INCLUDE_NONENUMERABLE (1U << 0) /* enumerate non-numerable properties in addition to enumerable */
+#define DUK_ENUM_INCLUDE_HIDDEN (1U << 1) /* enumerate hidden symbols too (in Duktape 1.x called internal properties) */
+#define DUK_ENUM_INCLUDE_SYMBOLS (1U << 2) /* enumerate symbols */
+#define DUK_ENUM_EXCLUDE_STRINGS (1U << 3) /* exclude strings */
+#define DUK_ENUM_OWN_PROPERTIES_ONLY (1U << 4) /* don't walk prototype chain, only check own properties */
+#define DUK_ENUM_ARRAY_INDICES_ONLY (1U << 5) /* only enumerate array indices */
+/* XXX: misleading name */
+#define DUK_ENUM_SORT_ARRAY_INDICES (1U << 6) /* sort array indices (applied to full enumeration result, including inherited array indices); XXX: misleading name */
+#define DUK_ENUM_NO_PROXY_BEHAVIOR (1U << 7) /* enumerate a proxy object itself without invoking proxy behavior */
/* Compilation flags for duk_compile() and duk_eval() */
/* DUK_COMPILE_xxx bits 0-2 are reserved for an internal 'nargs' argument.
*/
-#define DUK_COMPILE_EVAL (1 << 3) /* compile eval code (instead of global code) */
-#define DUK_COMPILE_FUNCTION (1 << 4) /* compile function code (instead of global code) */
-#define DUK_COMPILE_STRICT (1 << 5) /* use strict (outer) context for global, eval, or function code */
-#define DUK_COMPILE_SHEBANG (1 << 6) /* allow shebang ('#! ...') comment on first line of source */
-#define DUK_COMPILE_SAFE (1 << 7) /* (internal) catch compilation errors */
-#define DUK_COMPILE_NORESULT (1 << 8) /* (internal) omit eval result */
-#define DUK_COMPILE_NOSOURCE (1 << 9) /* (internal) no source string on stack */
-#define DUK_COMPILE_STRLEN (1 << 10) /* (internal) take strlen() of src_buffer (avoids double evaluation in macro) */
-#define DUK_COMPILE_NOFILENAME (1 << 11) /* (internal) no filename on stack */
-#define DUK_COMPILE_FUNCEXPR (1 << 12) /* (internal) source is a function expression (used for Function constructor) */
-
-/* Flags for duk_def_prop() and its variants */
-#define DUK_DEFPROP_WRITABLE (1 << 0) /* set writable (effective if DUK_DEFPROP_HAVE_WRITABLE set) */
-#define DUK_DEFPROP_ENUMERABLE (1 << 1) /* set enumerable (effective if DUK_DEFPROP_HAVE_ENUMERABLE set) */
-#define DUK_DEFPROP_CONFIGURABLE (1 << 2) /* set configurable (effective if DUK_DEFPROP_HAVE_CONFIGURABLE set) */
-#define DUK_DEFPROP_HAVE_WRITABLE (1 << 3) /* set/clear writable */
-#define DUK_DEFPROP_HAVE_ENUMERABLE (1 << 4) /* set/clear enumerable */
-#define DUK_DEFPROP_HAVE_CONFIGURABLE (1 << 5) /* set/clear configurable */
-#define DUK_DEFPROP_HAVE_VALUE (1 << 6) /* set value (given on value stack) */
-#define DUK_DEFPROP_HAVE_GETTER (1 << 7) /* set getter (given on value stack) */
-#define DUK_DEFPROP_HAVE_SETTER (1 << 8) /* set setter (given on value stack) */
-#define DUK_DEFPROP_FORCE (1 << 9) /* force change if possible, may still fail for e.g. virtual properties */
+#define DUK_COMPILE_EVAL (1U << 3) /* compile eval code (instead of global code) */
+#define DUK_COMPILE_FUNCTION (1U << 4) /* compile function code (instead of global code) */
+#define DUK_COMPILE_STRICT (1U << 5) /* use strict (outer) context for global, eval, or function code */
+#define DUK_COMPILE_SHEBANG (1U << 6) /* allow shebang ('#! ...') comment on first line of source */
+#define DUK_COMPILE_SAFE (1U << 7) /* (internal) catch compilation errors */
+#define DUK_COMPILE_NORESULT (1U << 8) /* (internal) omit eval result */
+#define DUK_COMPILE_NOSOURCE (1U << 9) /* (internal) no source string on stack */
+#define DUK_COMPILE_STRLEN (1U << 10) /* (internal) take strlen() of src_buffer (avoids double evaluation in macro) */
+#define DUK_COMPILE_NOFILENAME (1U << 11) /* (internal) no filename on stack */
+#define DUK_COMPILE_FUNCEXPR (1U << 12) /* (internal) source is a function expression (used for Function constructor) */
+
+/* Flags for duk_def_prop() and its variants; base flags + a lot of convenience shorthands */
+#define DUK_DEFPROP_WRITABLE (1U << 0) /* set writable (effective if DUK_DEFPROP_HAVE_WRITABLE set) */
+#define DUK_DEFPROP_ENUMERABLE (1U << 1) /* set enumerable (effective if DUK_DEFPROP_HAVE_ENUMERABLE set) */
+#define DUK_DEFPROP_CONFIGURABLE (1U << 2) /* set configurable (effective if DUK_DEFPROP_HAVE_CONFIGURABLE set) */
+#define DUK_DEFPROP_HAVE_WRITABLE (1U << 3) /* set/clear writable */
+#define DUK_DEFPROP_HAVE_ENUMERABLE (1U << 4) /* set/clear enumerable */
+#define DUK_DEFPROP_HAVE_CONFIGURABLE (1U << 5) /* set/clear configurable */
+#define DUK_DEFPROP_HAVE_VALUE (1U << 6) /* set value (given on value stack) */
+#define DUK_DEFPROP_HAVE_GETTER (1U << 7) /* set getter (given on value stack) */
+#define DUK_DEFPROP_HAVE_SETTER (1U << 8) /* set setter (given on value stack) */
+#define DUK_DEFPROP_FORCE (1U << 9) /* force change if possible, may still fail for e.g. virtual properties */
#define DUK_DEFPROP_SET_WRITABLE (DUK_DEFPROP_HAVE_WRITABLE | DUK_DEFPROP_WRITABLE)
#define DUK_DEFPROP_CLEAR_WRITABLE DUK_DEFPROP_HAVE_WRITABLE
#define DUK_DEFPROP_SET_ENUMERABLE (DUK_DEFPROP_HAVE_ENUMERABLE | DUK_DEFPROP_ENUMERABLE)
#define DUK_DEFPROP_CLEAR_ENUMERABLE DUK_DEFPROP_HAVE_ENUMERABLE
#define DUK_DEFPROP_SET_CONFIGURABLE (DUK_DEFPROP_HAVE_CONFIGURABLE | DUK_DEFPROP_CONFIGURABLE)
#define DUK_DEFPROP_CLEAR_CONFIGURABLE DUK_DEFPROP_HAVE_CONFIGURABLE
+#define DUK_DEFPROP_W DUK_DEFPROP_WRITABLE
+#define DUK_DEFPROP_E DUK_DEFPROP_ENUMERABLE
+#define DUK_DEFPROP_C DUK_DEFPROP_CONFIGURABLE
+#define DUK_DEFPROP_WE (DUK_DEFPROP_WRITABLE | DUK_DEFPROP_ENUMERABLE)
+#define DUK_DEFPROP_WC (DUK_DEFPROP_WRITABLE | DUK_DEFPROP_CONFIGURABLE)
+#define DUK_DEFPROP_WEC (DUK_DEFPROP_WRITABLE | DUK_DEFPROP_ENUMERABLE | DUK_DEFPROP_CONFIGURABLE)
+#define DUK_DEFPROP_HAVE_W DUK_DEFPROP_HAVE_WRITABLE
+#define DUK_DEFPROP_HAVE_E DUK_DEFPROP_HAVE_ENUMERABLE
+#define DUK_DEFPROP_HAVE_C DUK_DEFPROP_HAVE_CONFIGURABLE
+#define DUK_DEFPROP_HAVE_WE (DUK_DEFPROP_HAVE_WRITABLE | DUK_DEFPROP_HAVE_ENUMERABLE)
+#define DUK_DEFPROP_HAVE_WC (DUK_DEFPROP_HAVE_WRITABLE | DUK_DEFPROP_HAVE_CONFIGURABLE)
+#define DUK_DEFPROP_HAVE_WEC (DUK_DEFPROP_HAVE_WRITABLE | DUK_DEFPROP_HAVE_ENUMERABLE | DUK_DEFPROP_HAVE_CONFIGURABLE)
+#define DUK_DEFPROP_SET_W DUK_DEFPROP_SET_WRITABLE
+#define DUK_DEFPROP_SET_E DUK_DEFPROP_SET_ENUMERABLE
+#define DUK_DEFPROP_SET_C DUK_DEFPROP_SET_CONFIGURABLE
+#define DUK_DEFPROP_SET_WE (DUK_DEFPROP_SET_WRITABLE | DUK_DEFPROP_SET_ENUMERABLE)
+#define DUK_DEFPROP_SET_WC (DUK_DEFPROP_SET_WRITABLE | DUK_DEFPROP_SET_CONFIGURABLE)
+#define DUK_DEFPROP_SET_WEC (DUK_DEFPROP_SET_WRITABLE | DUK_DEFPROP_SET_ENUMERABLE | DUK_DEFPROP_SET_CONFIGURABLE)
+#define DUK_DEFPROP_CLEAR_W DUK_DEFPROP_CLEAR_WRITABLE
+#define DUK_DEFPROP_CLEAR_E DUK_DEFPROP_CLEAR_ENUMERABLE
+#define DUK_DEFPROP_CLEAR_C DUK_DEFPROP_CLEAR_CONFIGURABLE
+#define DUK_DEFPROP_CLEAR_WE (DUK_DEFPROP_CLEAR_WRITABLE | DUK_DEFPROP_CLEAR_ENUMERABLE)
+#define DUK_DEFPROP_CLEAR_WC (DUK_DEFPROP_CLEAR_WRITABLE | DUK_DEFPROP_CLEAR_CONFIGURABLE)
+#define DUK_DEFPROP_CLEAR_WEC (DUK_DEFPROP_CLEAR_WRITABLE | DUK_DEFPROP_CLEAR_ENUMERABLE | DUK_DEFPROP_CLEAR_CONFIGURABLE)
+#define DUK_DEFPROP_ATTR_W (DUK_DEFPROP_HAVE_WEC | DUK_DEFPROP_W)
+#define DUK_DEFPROP_ATTR_E (DUK_DEFPROP_HAVE_WEC | DUK_DEFPROP_E)
+#define DUK_DEFPROP_ATTR_C (DUK_DEFPROP_HAVE_WEC | DUK_DEFPROP_C)
+#define DUK_DEFPROP_ATTR_WE (DUK_DEFPROP_HAVE_WEC | DUK_DEFPROP_WE)
+#define DUK_DEFPROP_ATTR_WC (DUK_DEFPROP_HAVE_WEC | DUK_DEFPROP_WC)
+#define DUK_DEFPROP_ATTR_WEC (DUK_DEFPROP_HAVE_WEC | DUK_DEFPROP_WEC)
/* Flags for duk_push_thread_raw() */
-#define DUK_THREAD_NEW_GLOBAL_ENV (1 << 0) /* create a new global environment */
+#define DUK_THREAD_NEW_GLOBAL_ENV (1U << 0) /* create a new global environment */
/* Flags for duk_gc() */
-#define DUK_GC_COMPACT (1 << 0) /* compact heap objects */
+#define DUK_GC_COMPACT (1U << 0) /* compact heap objects */
/* Error codes (must be 8 bits at most, see duk_error.h) */
#define DUK_ERR_NONE 0 /* no error (e.g. from duk_get_error_code()) */
@@ -400,6 +434,23 @@ struct duk_time_components {
#define DUK_LEVEL_DDDEBUG 2
/*
+ * Macros to create Symbols as C statically constructed strings.
+ *
+ * Call e.g. as DUK_HIDDEN_SYMBOL("myProperty") <=> ("\xFF" "myProperty").
+ * Local symbols have a unique suffix, caller should take care to avoid
+ * conflicting with the Duktape internal representation by e.g. prepending
+ * a '!' character: DUK_LOCAL_SYMBOL("myLocal", "!123").
+ *
+ * Note that these can only be used for string constants, not dynamically
+ * created strings.
+ */
+
+#define DUK_HIDDEN_SYMBOL(x) ("\xFF" x)
+#define DUK_GLOBAL_SYMBOL(x) ("\x80" x)
+#define DUK_LOCAL_SYMBOL(x,uniq) ("\x81" x "\xff" uniq)
+#define DUK_WELLKNOWN_SYMBOL(x) ("\x81" x "\xff")
+
+/*
* If no variadic macros, __FILE__ and __LINE__ are passed through globals
* which is ugly and not thread safe.
*/
@@ -631,6 +682,7 @@ DUK_EXTERNAL_DECL duk_idx_t duk_push_array(duk_context *ctx);
DUK_EXTERNAL_DECL duk_idx_t duk_push_c_function(duk_context *ctx, duk_c_function func, duk_idx_t nargs);
DUK_EXTERNAL_DECL duk_idx_t duk_push_c_lightfunc(duk_context *ctx, duk_c_function func, duk_idx_t nargs, duk_idx_t length, duk_int_t magic);
DUK_EXTERNAL_DECL duk_idx_t duk_push_thread_raw(duk_context *ctx, duk_uint_t flags);
+DUK_EXTERNAL_DECL duk_idx_t duk_push_proxy(duk_context *ctx, duk_uint_t proxy_flags);
#define duk_push_thread(ctx) \
duk_push_thread_raw((ctx), 0 /*flags*/)
@@ -734,6 +786,8 @@ DUK_EXTERNAL_DECL duk_bool_t duk_is_thread(duk_context *ctx, duk_idx_t idx);
#define duk_is_callable(ctx,idx) \
duk_is_function((ctx), (idx))
+DUK_EXTERNAL_DECL duk_bool_t duk_is_constructable(duk_context *ctx, duk_idx_t idx);
+
DUK_EXTERNAL_DECL duk_bool_t duk_is_dynamic_buffer(duk_context *ctx, duk_idx_t idx);
DUK_EXTERNAL_DECL duk_bool_t duk_is_fixed_buffer(duk_context *ctx, duk_idx_t idx);
DUK_EXTERNAL_DECL duk_bool_t duk_is_external_buffer(duk_context *ctx, duk_idx_t idx);
@@ -850,6 +904,7 @@ DUK_EXTERNAL_DECL duk_int_t duk_require_int(duk_context *ctx, duk_idx_t idx);
DUK_EXTERNAL_DECL duk_uint_t duk_require_uint(duk_context *ctx, duk_idx_t idx);
DUK_EXTERNAL_DECL const char *duk_require_string(duk_context *ctx, duk_idx_t idx);
DUK_EXTERNAL_DECL const char *duk_require_lstring(duk_context *ctx, duk_idx_t idx, duk_size_t *out_len);
+DUK_EXTERNAL_DECL void duk_require_object(duk_context *ctx, duk_idx_t idx);
DUK_EXTERNAL_DECL void *duk_require_buffer(duk_context *ctx, duk_idx_t idx, duk_size_t *out_size);
DUK_EXTERNAL_DECL void *duk_require_buffer_data(duk_context *ctx, duk_idx_t idx, duk_size_t *out_size);
DUK_EXTERNAL_DECL void *duk_require_pointer(duk_context *ctx, duk_idx_t idx);
@@ -954,18 +1009,22 @@ DUK_EXTERNAL_DECL duk_bool_t duk_get_prop(duk_context *ctx, duk_idx_t obj_idx);
DUK_EXTERNAL_DECL duk_bool_t duk_get_prop_string(duk_context *ctx, duk_idx_t obj_idx, const char *key);
DUK_EXTERNAL_DECL duk_bool_t duk_get_prop_lstring(duk_context *ctx, duk_idx_t obj_idx, const char *key, duk_size_t key_len);
DUK_EXTERNAL_DECL duk_bool_t duk_get_prop_index(duk_context *ctx, duk_idx_t obj_idx, duk_uarridx_t arr_idx);
+DUK_EXTERNAL_DECL duk_bool_t duk_get_prop_heapptr(duk_context *ctx, duk_idx_t obj_idx, void *ptr);
DUK_EXTERNAL_DECL duk_bool_t duk_put_prop(duk_context *ctx, duk_idx_t obj_idx);
DUK_EXTERNAL_DECL duk_bool_t duk_put_prop_string(duk_context *ctx, duk_idx_t obj_idx, const char *key);
DUK_EXTERNAL_DECL duk_bool_t duk_put_prop_lstring(duk_context *ctx, duk_idx_t obj_idx, const char *key, duk_size_t key_len);
DUK_EXTERNAL_DECL duk_bool_t duk_put_prop_index(duk_context *ctx, duk_idx_t obj_idx, duk_uarridx_t arr_idx);
+DUK_EXTERNAL_DECL duk_bool_t duk_put_prop_heapptr(duk_context *ctx, duk_idx_t obj_idx, void *ptr);
DUK_EXTERNAL_DECL duk_bool_t duk_del_prop(duk_context *ctx, duk_idx_t obj_idx);
DUK_EXTERNAL_DECL duk_bool_t duk_del_prop_string(duk_context *ctx, duk_idx_t obj_idx, const char *key);
DUK_EXTERNAL_DECL duk_bool_t duk_del_prop_lstring(duk_context *ctx, duk_idx_t obj_idx, const char *key, duk_size_t key_len);
DUK_EXTERNAL_DECL duk_bool_t duk_del_prop_index(duk_context *ctx, duk_idx_t obj_idx, duk_uarridx_t arr_idx);
+DUK_EXTERNAL_DECL duk_bool_t duk_del_prop_heapptr(duk_context *ctx, duk_idx_t obj_idx, void *ptr);
DUK_EXTERNAL_DECL duk_bool_t duk_has_prop(duk_context *ctx, duk_idx_t obj_idx);
DUK_EXTERNAL_DECL duk_bool_t duk_has_prop_string(duk_context *ctx, duk_idx_t obj_idx, const char *key);
DUK_EXTERNAL_DECL duk_bool_t duk_has_prop_lstring(duk_context *ctx, duk_idx_t obj_idx, const char *key, duk_size_t key_len);
DUK_EXTERNAL_DECL duk_bool_t duk_has_prop_index(duk_context *ctx, duk_idx_t obj_idx, duk_uarridx_t arr_idx);
+DUK_EXTERNAL_DECL duk_bool_t duk_has_prop_heapptr(duk_context *ctx, duk_idx_t obj_idx, void *ptr);
DUK_EXTERNAL_DECL void duk_get_prop_desc(duk_context *ctx, duk_idx_t obj_idx, duk_uint_t flags);
DUK_EXTERNAL_DECL void duk_def_prop(duk_context *ctx, duk_idx_t obj_idx, duk_uint_t flags);
@@ -1024,6 +1083,8 @@ DUK_EXTERNAL_DECL void duk_put_number_list(duk_context *ctx, duk_idx_t obj_idx,
DUK_EXTERNAL_DECL void duk_compact(duk_context *ctx, duk_idx_t obj_idx);
DUK_EXTERNAL_DECL void duk_enum(duk_context *ctx, duk_idx_t obj_idx, duk_uint_t enum_flags);
DUK_EXTERNAL_DECL duk_bool_t duk_next(duk_context *ctx, duk_idx_t enum_idx, duk_bool_t get_value);
+DUK_EXTERNAL_DECL void duk_seal(duk_context *ctx, duk_idx_t obj_idx);
+DUK_EXTERNAL_DECL void duk_freeze(duk_context *ctx, duk_idx_t obj_idx);
/*
* String manipulation
diff --git a/content/hlcache.c b/content/hlcache.c
index 731c0bbb7..33436f7ed 100644
--- a/content/hlcache.c
+++ b/content/hlcache.c
@@ -179,20 +179,23 @@ static bool hlcache_type_is_acceptable(lwc_string *mime_type,
* \param pw Pointer to private data (hlcache_handle)
*/
static void hlcache_content_callback(struct content *c, content_msg msg,
- union content_msg_data data, void *pw)
+ const union content_msg_data *data, void *pw)
{
hlcache_handle *handle = pw;
- hlcache_event event;
nserror error = NSERROR_OK;
+ hlcache_event event = {
+ .type = msg,
+ };
- event.type = msg;
- event.data = data;
+ if (data != NULL) {
+ event.data = *data;
+ }
if (handle->cb != NULL)
error = handle->cb(handle, &event, handle->pw);
if (error != NSERROR_OK)
- LOG("Error in callback: %d", error);
+ NSLOG(netsurf, INFO, "Error in callback: %d", error);
}
/**
@@ -563,7 +566,8 @@ void hlcache_finalise(void)
num_contents++;
}
- LOG("%d contents remain before cache drain", num_contents);
+ NSLOG(netsurf, INFO, "%d contents remain before cache drain",
+ num_contents);
/* Drain cache */
do {
@@ -577,14 +581,17 @@ void hlcache_finalise(void)
}
} while (num_contents > 0 && num_contents != prev_contents);
- LOG("%d contents remaining:", num_contents);
+ NSLOG(netsurf, INFO, "%d contents remaining:", num_contents);
for (entry = hlcache->content_list; entry != NULL; entry = entry->next) {
hlcache_handle entry_handle = { entry, NULL, NULL };
if (entry->content != NULL) {
- LOG(" %p : %s (%d users)", entry, nsurl_access(hlcache_handle_get_url(&entry_handle)), content_count_users(entry->content));
+ NSLOG(netsurf, INFO, " %p : %s (%d users)",
+ entry,
+ nsurl_access(hlcache_handle_get_url(&entry_handle)),
+ content_count_users(entry->content));
} else {
- LOG(" %p", entry);
+ NSLOG(netsurf, INFO, " %p", entry);
}
}
@@ -612,12 +619,13 @@ void hlcache_finalise(void)
hlcache->retrieval_ctx_ring = NULL;
}
- LOG("hit/miss %d/%d", hlcache->hit_count, hlcache->miss_count);
+ NSLOG(netsurf, INFO, "hit/miss %d/%d", hlcache->hit_count,
+ hlcache->miss_count);
free(hlcache);
hlcache = NULL;
- LOG("Finalising low-level cache");
+ NSLOG(netsurf, INFO, "Finalising low-level cache");
llcache_finalise();
}
diff --git a/content/llcache.c b/content/llcache.c
index eb300534d..0c6f3a93b 100644
--- a/content/llcache.c
+++ b/content/llcache.c
@@ -52,16 +52,6 @@
#include "content/backing_store.h"
#include "content/urldb.h"
-/** Define to enable tracing of llcache operations. */
-#undef LLCACHE_TRACE
-//#define LLCACHE_TRACE 1
-
-#ifdef LLCACHE_TRACE
-#define LLCACHE_LOG(x...) LOG(x)
-#else
-#define LLCACHE_LOG(x...) ((void) 0)
-#endif
-
/**
* State of a low-level cache object fetch.
*/
@@ -316,7 +306,8 @@ static nserror llcache_object_user_new(llcache_handle_callback cb, void *pw,
u->handle = h;
- LLCACHE_LOG("Created user %p (%p, %p, %p)", u, h, (void *) cb, pw);
+ NSLOG(llcache, DEBUG,
+ "Created user %p (%p, %p, %p)", u, h, (void *) cb, pw);
*user = u;
@@ -333,7 +324,7 @@ static nserror llcache_object_user_new(llcache_handle_callback cb, void *pw,
*/
static nserror llcache_object_user_destroy(llcache_object_user *user)
{
- LLCACHE_LOG("Destroyed user %p", user);
+ NSLOG(llcache, DEBUG, "Destroyed user %p", user);
assert(user->next == NULL);
assert(user->prev == NULL);
@@ -377,7 +368,7 @@ static nserror llcache_object_remove_user(llcache_object *object,
object->last_used = time(NULL);
}
- LLCACHE_LOG("Removing user %p from %p", user, object);
+ NSLOG(llcache, DEBUG, "Removing user %p from %p", user, object);
return NSERROR_OK;
}
@@ -433,7 +424,7 @@ static nserror llcache_object_new(nsurl *url, llcache_object **result)
if (obj == NULL)
return NSERROR_NOMEM;
- LLCACHE_LOG("Created object %p (%s)", obj, nsurl_access(url));
+ NSLOG(llcache, DEBUG, "Created object %p (%s)", obj, nsurl_access(url));
obj->url = nsurl_ref(url);
@@ -874,7 +865,7 @@ static nserror llcache_object_refetch(llcache_object *object)
/* Reset fetch state */
object->fetch.state = LLCACHE_FETCH_INIT;
- LLCACHE_LOG("Re-fetching %p", object);
+ NSLOG(llcache, DEBUG, "Re-fetching %p", object);
/* Kick off fetch */
res = fetch_start(object->url,
@@ -921,7 +912,7 @@ static nserror llcache_object_fetch(llcache_object *object, uint32_t flags,
nsurl *referer_clone = NULL;
llcache_post_data *post_clone = NULL;
- LLCACHE_LOG("Starting fetch for %p", object);
+ NSLOG(llcache, DEBUG, "Starting fetch for %p", object);
if (post != NULL) {
error = llcache_post_data_clone(post, &post_clone);
@@ -955,8 +946,8 @@ static nserror llcache_object_destroy(llcache_object *object)
{
size_t i;
- LLCACHE_LOG("Destroying object %p, %s", object,
- nsurl_access(object->url));
+ NSLOG(llcache, DEBUG, "Destroying object %p, %s", object,
+ nsurl_access(object->url));
if (object->source_data != NULL) {
if (object->store_state == LLCACHE_STATE_DISC) {
@@ -1038,16 +1029,17 @@ llcache_object_rfc2616_remaining_lifetime(const llcache_cache_control *cd)
current_age += cd->res_time - cd->req_time + now - cd->res_time;
/* Determine freshness lifetime of this object */
- if (cd->max_age != INVALID_AGE)
+ if (cd->max_age != INVALID_AGE) {
freshness_lifetime = cd->max_age;
- else if (cd->expires != 0)
+ } else if (cd->expires != 0) {
freshness_lifetime = cd->expires - cd->date;
- else if (cd->last_modified != 0)
+ } else if (cd->last_modified != 0) {
freshness_lifetime = (now - cd->last_modified) / 10;
- else
+ } else {
freshness_lifetime = 0;
+ }
- /* LLCACHE_LOG("%d:%d", freshness_lifetime, current_age); */
+ NSLOG(llcache, DEBUG, "%d:%d", freshness_lifetime, current_age);
if ((cd->no_cache == LLCACHE_VALIDATE_FRESH) &&
(freshness_lifetime > current_age)) {
@@ -1076,7 +1068,7 @@ static bool llcache_object_is_fresh(const llcache_object *object)
remaining_lifetime = llcache_object_rfc2616_remaining_lifetime(cd);
- LLCACHE_LOG("%p: (%d > 0 || %d != %d)", object,
+ NSLOG(llcache, DEBUG, "%p: (%d > 0 || %d != %d)", object,
remaining_lifetime,
object->fetch.state, LLCACHE_FETCH_COMPLETE);
@@ -1322,7 +1314,7 @@ llcache_serialise_metadata(llcache_object *object,
datasize -= use;
}
- LLCACHE_LOG("Filled buffer with %d spare", datasize);
+ NSLOG(llcache, DEBUG, "Filled buffer with %d spare", datasize);
*data_out = data;
*datasize_out = allocsize - datasize;
@@ -1331,13 +1323,13 @@ llcache_serialise_metadata(llcache_object *object,
overflow:
/* somehow we overflowed the buffer - hth? */
- LOG("Overflowed metadata buffer");
+ NSLOG(llcache, INFO, "Overflowed metadata buffer");
free(data);
return NSERROR_INVALID;
operror:
/* output error */
- LOG("Output error");
+ NSLOG(llcache, INFO, "Output error");
free(data);
return NSERROR_INVALID;
}
@@ -1374,7 +1366,7 @@ llcache_process_metadata(llcache_object *object)
size_t num_headers;
size_t hloop;
- LOG("Retrieving metadata");
+ NSLOG(llcache, INFO, "Retrieving metadata");
/* attempt to retrieve object metadata from the backing store */
res = guit->llcache->fetch(object->url,
@@ -1385,7 +1377,7 @@ llcache_process_metadata(llcache_object *object)
return res;
}
- LOG("Processing retrieved data");
+ NSLOG(llcache, INFO, "Processing retrieved data");
/* metadata line 1 is the url the metadata referrs to */
line = 1;
@@ -1408,8 +1400,8 @@ llcache_process_metadata(llcache_object *object)
* by simply skipping caching of this object.
*/
- LOG("Got metadata for %s instead of %s",
- nsurl_access(metadataurl), nsurl_access(object->url));
+ NSLOG(llcache, INFO, "Got metadata for %s instead of %s",
+ nsurl_access(metadataurl), nsurl_access(object->url));
nsurl_unref(metadataurl);
@@ -1502,7 +1494,9 @@ llcache_process_metadata(llcache_object *object)
return NSERROR_OK;
format_error:
- LOG("metadata error on line %d error code %d\n", line, res);
+ NSLOG(llcache, INFO,
+ "metadata error on line %d error code %d\n",
+ line, res);
guit->llcache->release(object->url, BACKING_STORE_META);
return res;
@@ -1584,7 +1578,7 @@ llcache_object_retrieve_from_cache(nsurl *url,
nserror error;
llcache_object *obj, *newest = NULL;
- LLCACHE_LOG("Searching cache for %s flags:%x referer:%s post:%p",
+ NSLOG(llcache, DEBUG, "Searching cache for %s flags:%x referer:%s post:%p",
nsurl_access(url), flags,
referer==NULL?"":nsurl_access(referer), post);
@@ -1603,7 +1597,7 @@ llcache_object_retrieve_from_cache(nsurl *url,
* pull from persistent store.
*/
if (newest == NULL) {
- LLCACHE_LOG("No viable object found in llcache");
+ NSLOG(llcache, DEBUG, "No viable object found in llcache");
error = llcache_object_new(url, &obj);
if (error != NSERROR_OK)
@@ -1612,7 +1606,7 @@ llcache_object_retrieve_from_cache(nsurl *url,
/* attempt to retrieve object from persistent store */
error = llcache_object_fetch_persistant(obj, flags, referer, post, redirect_count);
if (error == NSERROR_OK) {
- LLCACHE_LOG("retrieved object from persistent store");
+ NSLOG(llcache, DEBUG, "retrieved object from persistent store");
/* set newest object from persistent store which
* will cause the normal object handling to be used.
@@ -1630,7 +1624,7 @@ llcache_object_retrieve_from_cache(nsurl *url,
if ((newest != NULL) && (llcache_object_is_fresh(newest))) {
/* Found a suitable object, and it's still fresh */
- LLCACHE_LOG("Found fresh %p", newest);
+ NSLOG(llcache, DEBUG, "Found fresh %p", newest);
/* The client needs to catch up with the object's state.
* This will occur the next time that llcache_poll is called.
@@ -1651,7 +1645,7 @@ llcache_object_retrieve_from_cache(nsurl *url,
* failed, destroy cache object and fall though to
* cache miss to re-fetch
*/
- LLCACHE_LOG("Persistent retrieval failed for %p", newest);
+ NSLOG(llcache, DEBUG, "Persistent retrieval failed for %p", newest);
llcache_object_remove_from_list(newest, &llcache->cached_objects);
llcache_object_destroy(newest);
@@ -1672,7 +1666,7 @@ llcache_object_retrieve_from_cache(nsurl *url,
if (error != NSERROR_OK)
return error;
- LLCACHE_LOG("Found candidate %p (%p)", obj, newest);
+ NSLOG(llcache, DEBUG, "Found candidate %p (%p)", obj, newest);
/* Clone candidate's cache data */
error = llcache_object_clone_cache_data(newest, obj, true);
@@ -1702,7 +1696,7 @@ llcache_object_retrieve_from_cache(nsurl *url,
return NSERROR_OK;
}
- LLCACHE_LOG("Persistent retrieval failed for %p", newest);
+ NSLOG(llcache, DEBUG, "Persistent retrieval failed for %p", newest);
/* retrieval of source data from persistent store
* failed, destroy cache object and fall though to
@@ -1757,7 +1751,7 @@ llcache_object_retrieve(nsurl *url,
nsurl *defragmented_url;
bool uncachable = false;
- LLCACHE_LOG("Retrieve %s (%x, %s, %p)", nsurl_access(url), flags,
+ NSLOG(llcache, DEBUG, "Retrieve %s (%x, %s, %p)", nsurl_access(url), flags,
referer==NULL?"":nsurl_access(referer), post);
@@ -1824,7 +1818,7 @@ llcache_object_retrieve(nsurl *url,
/* Returned object is already in the cached list */
}
- LLCACHE_LOG("Retrieved %p", obj);
+ NSLOG(llcache, DEBUG, "Retrieved %p", obj);
*result = obj;
@@ -1857,7 +1851,7 @@ static nserror llcache_object_add_user(llcache_object *object,
object->users->prev = user;
object->users = user;
- LLCACHE_LOG("Adding user %p to %p", user, object);
+ NSLOG(llcache, DEBUG, "Adding user %p to %p", user, object);
return NSERROR_OK;
}
@@ -1898,7 +1892,7 @@ static nserror llcache_fetch_redirect(llcache_object *object,
/* Forcibly stop redirecting if we've followed too many redirects */
#define REDIRECT_LIMIT 10
if (object->fetch.redirect_count > REDIRECT_LIMIT) {
- LOG("Too many nested redirects");
+ NSLOG(llcache, INFO, "Too many nested redirects");
event.type = LLCACHE_EVENT_ERROR;
event.data.msg = messages_get("BadRedirect");
@@ -2493,8 +2487,10 @@ static void llcache_persist_slowcheck(void *p)
total_bandwidth = (llcache->total_written * 1000) / llcache->total_elapsed;
if (total_bandwidth < llcache->minimum_bandwidth) {
- LOG("Current bandwidth %" PRIu64 " less than minimum %" PRIsizet,
- total_bandwidth, llcache->minimum_bandwidth);
+ NSLOG(llcache, INFO,
+ "Current bandwidth %"PRIu64" less than minimum %"PRIsizet,
+ total_bandwidth,
+ llcache->minimum_bandwidth);
guit->llcache->finalise();
}
}
@@ -2524,7 +2520,7 @@ static void llcache_persist(void *p)
ret = build_candidate_list(&lst, &lst_count);
if (ret != NSERROR_OK) {
- LLCACHE_LOG("Unable to construct candidate list for persistent writeout");
+ NSLOG(llcache, DEBUG, "Unable to construct candidate list for persistent writeout");
return;
}
@@ -2542,7 +2538,7 @@ static void llcache_persist(void *p)
total_elapsed += elapsed;
total_bandwidth = (total_written * 1000) / total_elapsed;
- LLCACHE_LOG("Wrote %zd bytes in %lums bw:%lu %s",
+ NSLOG(llcache, DEBUG, "Wrote %zd bytes in %lums bw:%lu %s",
written, elapsed, (written * 1000) / elapsed,
nsurl_access(lst[idx]->url) );
@@ -2550,7 +2546,7 @@ static void llcache_persist(void *p)
* (bandwidth) for this run being exceeded.
*/
if (total_elapsed > llcache->time_quantum) {
- LOG("Overran timeslot");
+ NSLOG(llcache, INFO, "Overran timeslot");
/* writeout has exhausted the available time.
* Either the writeout is slow or the last
* object was very large.
@@ -2609,10 +2605,10 @@ static void llcache_persist(void *p)
llcache->total_written += total_written;
llcache->total_elapsed += total_elapsed;
- LLCACHE_LOG("writeout size:%zd time:%lu bandwidth:%lubytes/s",
+ NSLOG(llcache, DEBUG, "writeout size:%zd time:%lu bandwidth:%lubytes/s",
total_written, total_elapsed, total_bandwidth);
- LLCACHE_LOG("Rescheduling writeout in %dms", next);
+ NSLOG(llcache, DEBUG, "Rescheduling writeout in %dms", next);
guit->misc->schedule(next, llcache_persist, NULL);
}
@@ -2629,7 +2625,7 @@ static void llcache_fetch_callback(const fetch_msg *msg, void *p)
llcache_object *object = p;
llcache_event event;
- LLCACHE_LOG("Fetch event %d for %p", msg->type, object);
+ NSLOG(llcache, DEBUG, "Fetch event %d for %p", msg->type, object);
switch (msg->type) {
case FETCH_HEADER:
@@ -2702,9 +2698,7 @@ static void llcache_fetch_callback(const fetch_msg *msg, void *p)
error = llcache_object_refetch(object);
break;
}
- /* Otherwise fall through to error, setting the message to
- * a timeout
- */
+ /* Fall through */
case FETCH_ERROR:
/* An error occurred while fetching */
/* The fetch has has already been cleaned up by the fetcher */
@@ -2853,10 +2847,7 @@ static nserror llcache_object_notify_users(llcache_object *object)
nserror error;
llcache_object_user *user, *next_user;
llcache_event event;
-
-#ifdef LLCACHE_TRACE
bool emitted_notify = false;
-#endif
/**
* State transitions and event emission for users.
@@ -2917,17 +2908,20 @@ static nserror llcache_object_notify_users(llcache_object *object)
* continue is used)
*/
-#ifdef LLCACHE_TRACE
if (handle->state != objstate) {
if (emitted_notify == false) {
- LOG("Notifying users of %p", object);
+ NSLOG(llcache, DEBUG,
+ "Notifying users of %p",
+ object);
emitted_notify = true;
}
- LOG("User %p state: %d Object state: %d", user,
- handle->state, objstate);
+ NSLOG(llcache, DEBUG,
+ "User %p state: %d Object state: %d",
+ user,
+ handle->state,
+ objstate);
}
-#endif
/* User: INIT, Obj: HEADERS, DATA, COMPLETE => User->HEADERS */
if (handle->state == LLCACHE_FETCH_INIT &&
@@ -3184,7 +3178,7 @@ void llcache_clean(bool purge)
int remaining_lifetime;
uint32_t limit;
- LLCACHE_LOG("Attempting cache clean");
+ NSLOG(llcache, DEBUG, "Attempting cache clean");
/* If the cache is being purged set the size limit to zero. */
if (purge) {
@@ -3204,7 +3198,7 @@ void llcache_clean(bool purge)
(object->candidate_count == 0) &&
(object->fetch.fetch == NULL) &&
(object->fetch.outstanding_query == false)) {
- LLCACHE_LOG("Discarding uncachable object with no users (%p) %s",
+ NSLOG(llcache, DEBUG, "Discarding uncachable object with no users (%p) %s",
object, nsurl_access(object->url));
llcache_object_remove_from_list(object,
@@ -3231,7 +3225,7 @@ void llcache_clean(bool purge)
(object->fetch.outstanding_query == false) &&
(remaining_lifetime <= 0)) {
/* object is stale */
- LLCACHE_LOG("discarding stale cacheable object with no "
+ NSLOG(llcache, DEBUG, "discarding stale cacheable object with no "
"users or pending fetches (%p) %s",
object, nsurl_access(object->url));
@@ -3277,7 +3271,7 @@ void llcache_clean(bool purge)
llcache_size -= object->source_len;
- LLCACHE_LOG("Freeing source data for %p len:%zd",
+ NSLOG(llcache, DEBUG, "Freeing source data for %p len:%zd",
object,
object->source_len);
}
@@ -3297,12 +3291,12 @@ void llcache_clean(bool purge)
(object->fetch.outstanding_query == false) &&
(object->store_state == LLCACHE_STATE_DISC) &&
(object->source_data == NULL)) {
- LLCACHE_LOG("discarding backed object len:%zd "
- "age:%d (%p) %s",
- object->source_len,
- time(NULL) - object->last_used,
- object,
- nsurl_access(object->url));
+ NSLOG(llcache, DEBUG,
+ "discarding backed object len:%zd age:%ld (%p) %s",
+ object->source_len,
+ (long)(time(NULL) - object->last_used),
+ object,
+ nsurl_access(object->url));
llcache_size -= total_object_size(object);
@@ -3328,11 +3322,12 @@ void llcache_clean(bool purge)
(object->fetch.fetch == NULL) &&
(object->fetch.outstanding_query == false) &&
(object->store_state == LLCACHE_STATE_RAM)) {
- LLCACHE_LOG("discarding fresh object len:%zd age:%d (%p) %s",
- object->source_len,
- time(NULL) - object->last_used,
- object,
- nsurl_access(object->url));
+ NSLOG(llcache, DEBUG,
+ "discarding fresh object len:%zd age:%ld (%p) %s",
+ object->source_len,
+ (long)(time(NULL) - object->last_used),
+ object,
+ nsurl_access(object->url));
llcache_size -= object->source_len + sizeof(*object);
@@ -3342,7 +3337,7 @@ void llcache_clean(bool purge)
}
}
- LLCACHE_LOG("Size: %u (limit: %u)", llcache_size, limit);
+ NSLOG(llcache, DEBUG, "Size: %u (limit: %u)", llcache_size, limit);
}
/* Exported interface documented in content/llcache.h */
@@ -3364,7 +3359,9 @@ llcache_initialise(const struct llcache_parameters *prm)
llcache->fetch_attempts = prm->fetch_attempts;
llcache->all_caught_up = true;
- LOG("llcache initialising with a limit of %d bytes", llcache->limit);
+ NSLOG(llcache, INFO,
+ "llcache initialising with a limit of %d bytes",
+ llcache->limit);
/* backing store initialisation */
return guit->llcache->initialise(&prm->store);
@@ -3427,10 +3424,11 @@ void llcache_finalise(void)
llcache->total_elapsed;
}
- LOG("Backing store wrote %"PRIu64" bytes in %"PRIu64" ms "
- "(average %"PRIu64" bytes/second)",
- llcache->total_written, llcache->total_elapsed,
- total_bandwidth);
+ NSLOG(llcache, INFO,
+ "Backing store wrote %"PRIu64" bytes in %"PRIu64" ms ""(average %"PRIu64" bytes/second)",
+ llcache->total_written,
+ llcache->total_elapsed,
+ total_bandwidth);
free(llcache);
llcache = NULL;
diff --git a/content/urldb.c b/content/urldb.c
index 313ec316d..cacc475f2 100644
--- a/content/urldb.c
+++ b/content/urldb.c
@@ -202,7 +202,6 @@ struct path_data {
char **fragment; /**< Array of fragments */
bool persistent; /**< This entry should persist */
- struct bitmap *thumb; /**< Thumbnail image of resource */
struct url_internal_data urld; /**< URL data for resource */
/**
@@ -662,7 +661,8 @@ static bool urldb__host_is_ip_address(const char *host)
c[slash - host] = '\0';
sane_host = c;
host_len = slash - host;
- LOG("WARNING: called with non-host '%s'", host);
+ NSLOG(netsurf, INFO, "WARNING: called with non-host '%s'",
+ host);
}
if (strspn(sane_host, "0123456789abcdefABCDEF[].:") < host_len)
@@ -1292,7 +1292,7 @@ urldb_match_path(const struct path_data *parent,
assert(parent->segment == NULL);
if (path[0] != '/') {
- LOG("path is %s", path);
+ NSLOG(netsurf, INFO, "path is %s", path);
}
assert(path[0] == '/');
@@ -1422,12 +1422,14 @@ static void urldb_dump_paths(struct path_data *parent)
do {
if (p->segment != NULL) {
- LOG("\t%s : %u", lwc_string_data(p->scheme), p->port);
+ NSLOG(netsurf, INFO, "\t%s : %u",
+ lwc_string_data(p->scheme), p->port);
- LOG("\t\t'%s'", p->segment);
+ NSLOG(netsurf, INFO, "\t\t'%s'", p->segment);
for (i = 0; i != p->frag_cnt; i++) {
- LOG("\t\t\t#%s", p->fragment[i]);
+ NSLOG(netsurf, INFO, "\t\t\t#%s",
+ p->fragment[i]);
}
}
@@ -1457,10 +1459,10 @@ static void urldb_dump_hosts(struct host_part *parent)
struct host_part *h;
if (parent->part) {
- LOG("%s", parent->part);
+ NSLOG(netsurf, INFO, "%s", parent->part);
- LOG("\t%s invalid SSL certs",
- parent->permit_invalid_certs ? "Permits" : "Denies");
+ NSLOG(netsurf, INFO, "\t%s invalid SSL certs",
+ parent->permit_invalid_certs ? "Permits" : "Denies");
}
/* Dump path data */
@@ -1512,7 +1514,7 @@ static void urldb_dump_search(struct search_node *parent, int depth)
}
s[i]= 0;
- LOG("%s", s);
+ NSLOG(netsurf, INFO, "%s", s);
urldb_dump_search(parent->right, depth + 1);
}
@@ -2699,10 +2701,6 @@ static void urldb_destroy_path_node_content(struct path_data *node)
free(node->fragment[i]);
free(node->fragment);
- if (node->thumb) {
- guit->bitmap->destroy(node->thumb);
- }
-
free(node->urld.title);
for (a = node->cookies; a; a = b) {
@@ -2866,14 +2864,15 @@ nserror urldb_load(const char *filename)
assert(filename);
- LOG("Loading URL file %s", filename);
+ NSLOG(netsurf, INFO, "Loading URL file %s", filename);
if (url_bloom == NULL)
url_bloom = bloom_create(BLOOM_SIZE);
fp = fopen(filename, "r");
if (!fp) {
- LOG("Failed to open file '%s' for reading", filename);
+ NSLOG(netsurf, INFO, "Failed to open file '%s' for reading",
+ filename);
return NSERROR_NOT_FOUND;
}
@@ -2884,12 +2883,12 @@ nserror urldb_load(const char *filename)
version = atoi(s);
if (version < MIN_URL_FILE_VERSION) {
- LOG("Unsupported URL file version.");
+ NSLOG(netsurf, INFO, "Unsupported URL file version.");
fclose(fp);
return NSERROR_INVALID;
}
if (version > URL_FILE_VERSION) {
- LOG("Unknown URL file version.");
+ NSLOG(netsurf, INFO, "Unknown URL file version.");
fclose(fp);
return NSERROR_INVALID;
}
@@ -2919,13 +2918,13 @@ nserror urldb_load(const char *filename)
/* no URLs => try next host */
if (urls == 0) {
- LOG("No URLs for '%s'", host);
+ NSLOG(netsurf, INFO, "No URLs for '%s'", host);
continue;
}
h = urldb_add_host(host);
if (!h) {
- LOG("Failed adding host: '%s'", host);
+ NSLOG(netsurf, INFO, "Failed adding host: '%s'", host);
fclose(fp);
return NSERROR_NOMEM;
}
@@ -2976,7 +2975,8 @@ nserror urldb_load(const char *filename)
* Need a nsurl_save too.
*/
if (nsurl_create(url, &nsurl) != NSERROR_OK) {
- LOG("Failed inserting '%s'", url);
+ NSLOG(netsurf, INFO, "Failed inserting '%s'",
+ url);
fclose(fp);
return NSERROR_NOMEM;
}
@@ -2989,7 +2989,8 @@ nserror urldb_load(const char *filename)
/* Copy and merge path/query strings */
if (nsurl_get(nsurl, NSURL_PATH | NSURL_QUERY,
&path_query, &len) != NSERROR_OK) {
- LOG("Failed inserting '%s'", url);
+ NSLOG(netsurf, INFO, "Failed inserting '%s'",
+ url);
fclose(fp);
return NSERROR_NOMEM;
}
@@ -3000,7 +3001,8 @@ nserror urldb_load(const char *filename)
p = urldb_add_path(scheme_lwc, port, h, path_query,
fragment_lwc, nsurl);
if (!p) {
- LOG("Failed inserting '%s'", url);
+ NSLOG(netsurf, INFO, "Failed inserting '%s'",
+ url);
fclose(fp);
return NSERROR_NOMEM;
}
@@ -3044,7 +3046,7 @@ nserror urldb_load(const char *filename)
}
fclose(fp);
- LOG("Successfully loaded URL file");
+ NSLOG(netsurf, INFO, "Successfully loaded URL file");
#undef MAXIMUM_URL_LENGTH
return NSERROR_OK;
@@ -3060,7 +3062,8 @@ nserror urldb_save(const char *filename)
fp = fopen(filename, "w");
if (!fp) {
- LOG("Failed to open file '%s' for writing", filename);
+ NSLOG(netsurf, INFO, "Failed to open file '%s' for writing",
+ filename);
return NSERROR_SAVE_FAILED;
}
@@ -3457,48 +3460,6 @@ bool urldb_get_cert_permissions(nsurl *url)
}
-/* exported interface documented in content/urldb.h */
-bool urldb_set_thumbnail(nsurl *url, struct bitmap *bitmap)
-{
- struct path_data *p;
-
- assert(url);
-
- /* add url, in case it's missing */
- urldb_add_url(url);
-
- p = urldb_find_url(url);
- if (p == NULL) {
- return false;
- }
-
- LOG("Setting bitmap on %s", nsurl_access(url));
-
- if ((p->thumb) && (p->thumb != bitmap)) {
- guit->bitmap->destroy(p->thumb);
- }
-
- p->thumb = bitmap;
-
- return true;
-}
-
-
-/* exported interface documented in netsurf/url_db.h */
-struct bitmap *urldb_get_thumbnail(nsurl *url)
-{
- struct path_data *p;
-
- assert(url);
-
- p = urldb_find_url(url);
- if (!p)
- return NULL;
-
- return p->thumb;
-}
-
-
/* exported interface documented in netsurf/url_db.h */
void
urldb_iterate_partial(const char *prefix,
@@ -3754,7 +3715,8 @@ bool urldb_set_cookie(const char *header, nsurl *url, nsurl *referer)
}
suffix = nspsl_getpublicsuffix(dot);
if (suffix == NULL) {
- LOG("domain %s was a public suffix domain", dot);
+ NSLOG(netsurf, INFO,
+ "domain %s was a public suffix domain", dot);
urldb_free_cookie(c);
goto error;
}
@@ -4161,7 +4123,7 @@ void urldb_load_cookies(const char *filename)
for (; *p && *p != '\t'; p++) \
; /* do nothing */ \
if (p >= end) { \
- LOG("Overran input"); \
+ NSLOG(netsurf, INFO, "Overran input"); \
continue; \
} \
*p++ = '\0'; \
@@ -4171,7 +4133,7 @@ void urldb_load_cookies(const char *filename)
for (; *p && *p == '\t'; p++) \
; /* do nothing */ \
if (p >= end) { \
- LOG("Overran input"); \
+ NSLOG(netsurf, INFO, "Overran input"); \
continue; \
} \
}
@@ -4200,7 +4162,8 @@ void urldb_load_cookies(const char *filename)
if (loaded_cookie_file_version <
MIN_COOKIE_FILE_VERSION) {
- LOG("Unsupported Cookie file version");
+ NSLOG(netsurf, INFO,
+ "Unsupported Cookie file version");
break;
}
diff --git a/content/urldb.h b/content/urldb.h
index b2c233194..4aa548704 100644
--- a/content/urldb.h
+++ b/content/urldb.h
@@ -111,16 +111,6 @@ bool urldb_get_cert_permissions(struct nsurl *url);
/**
- * Set thumbnail for url, replacing any existing thumbnail
- *
- * \param url Absolute URL to consider
- * \param bitmap Opaque pointer to thumbnail data, or NULL to invalidate
- * \return true on successful setting else false
- */
-bool urldb_set_thumbnail(struct nsurl *url, struct bitmap *bitmap);
-
-
-/**
* Parse Set-Cookie header and insert cookie(s) into database
*
* \param header Header to parse, with Set-Cookie: stripped
diff --git a/desktop/browser.c b/desktop/browser.c
index e7ff158f9..19cfebb99 100644
--- a/desktop/browser.c
+++ b/desktop/browser.c
@@ -171,7 +171,7 @@ browser_window_redraw(struct browser_window *bw,
nserror res;
if (bw == NULL) {
- LOG("NULL browser window");
+ NSLOG(netsurf, INFO, "NULL browser window");
return false;
}
@@ -336,7 +336,7 @@ browser_window_redraw(struct browser_window *bw,
bool browser_window_redraw_ready(struct browser_window *bw)
{
if (bw == NULL) {
- LOG("NULL browser window");
+ NSLOG(netsurf, INFO, "NULL browser window");
return false;
} else if (bw->current_content != NULL) {
/* Can't render locked contents */
@@ -415,7 +415,8 @@ void browser_window_set_position(struct browser_window *bw, int x, int y)
bw->x = x;
bw->y = y;
} else {
- LOG("Asked to set position of front end window.");
+ NSLOG(netsurf, INFO,
+ "Asked to set position of front end window.");
assert(0);
}
}
@@ -811,7 +812,7 @@ nserror browser_window_debug(struct browser_window *bw, enum content_debug op)
static bool slow_script(void *ctx)
{
static int count = 0;
- LOG("Continuing execution %d", count);
+ NSLOG(netsurf, INFO, "Continuing execution %d", count);
count++;
if (count > 1) {
count = 0;
@@ -886,7 +887,7 @@ nserror browser_window_create(enum browser_window_create_flags flags,
}
if (url != NULL) {
- enum browser_window_nav_flags nav_flags = BW_NAVIGATE_NONE;
+ enum browser_window_nav_flags nav_flags = BW_NAVIGATE_NO_TERMINAL_HISTORY_UPDATE;
if (flags & BW_CREATE_UNVERIFIABLE)
nav_flags |= BW_NAVIGATE_UNVERIFIABLE;
if (flags & BW_CREATE_HISTORY)
@@ -982,11 +983,12 @@ browser_window_download(struct browser_window *bw,
/* no internal handler for this type, call out to frontend */
error = guit->misc->launch_url(url);
} else if (error != NSERROR_OK) {
- LOG("Failed to fetch download: %d", error);
+ NSLOG(netsurf, INFO, "Failed to fetch download: %d", error);
} else {
error = download_context_create(l, root->window);
if (error != NSERROR_OK) {
- LOG("Failed creating download context: %d", error);
+ NSLOG(netsurf, INFO,
+ "Failed creating download context: %d", error);
llcache_handle_abort(l);
llcache_handle_release(l);
}
@@ -1094,6 +1096,7 @@ browser_window_favicon_callback(hlcache_handle *c,
break;
case CONTENT_MSG_ERROR:
+ case CONTENT_MSG_ERRORCODE:
/* clean up after ourselves */
if (c == bw->favicon.loading) {
@@ -1113,7 +1116,8 @@ browser_window_favicon_callback(hlcache_handle *c,
error = nsurl_create("resource:favicon.ico", &nsurl);
if (error != NSERROR_OK) {
- LOG("Unable to create default location url");
+ NSLOG(netsurf, INFO,
+ "Unable to create default location url");
} else {
hlcache_handle_retrieve(nsurl,
HLCACHE_RETRIEVE_SNIFF_TYPE,
@@ -1203,7 +1207,8 @@ browser_window_update_favicon(hlcache_handle *c,
error = nsurl_create("resource:favicon.ico", &nsurl);
}
if (error != NSERROR_OK) {
- LOG("Unable to create default location url");
+ NSLOG(netsurf, INFO,
+ "Unable to create default location url");
return;
}
} else {
@@ -1211,9 +1216,11 @@ browser_window_update_favicon(hlcache_handle *c,
}
if (link == NULL) {
- LOG("fetching general favicon from '%s'", nsurl_access(nsurl));
+ NSLOG(netsurf, INFO, "fetching general favicon from '%s'",
+ nsurl_access(nsurl));
} else {
- LOG("fetching favicon rel:%s '%s'", lwc_string_data(link->rel), nsurl_access(nsurl));
+ NSLOG(netsurf, INFO, "fetching favicon rel:%s '%s'",
+ lwc_string_data(link->rel), nsurl_access(nsurl));
}
hlcache_handle_retrieve(nsurl, HLCACHE_RETRIEVE_SNIFF_TYPE,
@@ -1348,6 +1355,7 @@ browser_window_callback(hlcache_handle *c,
{
struct browser_window *bw = pw;
nserror res = NSERROR_OK;
+ float sx, sy;
switch (event->type) {
case CONTENT_MSG_DOWNLOAD:
@@ -1397,23 +1405,6 @@ browser_window_callback(hlcache_handle *c,
bw->current_content = c;
bw->loading_content = NULL;
- /* Format the new content to the correct dimensions */
- browser_window_get_dimensions(bw, &width, &height, true);
- content_reformat(c, false, width, height);
-
- browser_window_remove_caret(bw, false);
-
- if (bw->window != NULL) {
- guit->window->new_content(bw->window);
-
- browser_window_refresh_url_bar(bw);
- }
-
- /* new content; set scroll_to_top */
- browser_window_update(bw, true);
- content_open(c, bw, 0, 0);
- browser_window_set_status(bw, content_get_status_message(c));
-
/* history */
if (bw->history_add && bw->history) {
nsurl *url = hlcache_handle_get_url(c);
@@ -1450,6 +1441,23 @@ browser_window_callback(hlcache_handle *c,
browser_window_history_add(bw, c, bw->frag_id);
}
+ /* Format the new content to the correct dimensions */
+ browser_window_get_dimensions(bw, &width, &height, true);
+ content_reformat(c, false, width, height);
+
+ browser_window_remove_caret(bw, false);
+
+ if (bw->window != NULL) {
+ guit->window->new_content(bw->window);
+
+ browser_window_refresh_url_bar(bw);
+ }
+
+ /* new content; set scroll_to_top */
+ browser_window_update(bw, true);
+ content_open(c, bw, 0, 0);
+ browser_window_set_status(bw, content_get_status_message(c));
+
/* frames */
if ((content_get_type(c) == CONTENT_HTML) &&
(html_get_frameset(c) != NULL)) {
@@ -1478,6 +1486,19 @@ browser_window_callback(hlcache_handle *c,
browser_window_stop_throbber(bw);
browser_window_update_favicon(c, bw, NULL);
+ if (browser_window_history_get_scroll(bw, &sx, &sy) == NSERROR_OK) {
+ int scrollx = (int)((float)content_get_width(bw->current_content) * sx);
+ int scrolly = (int)((float)content_get_height(bw->current_content) * sy);
+ struct rect rect;
+ rect.x0 = rect.x1 = scrollx;
+ rect.y0 = rect.y1 = scrolly;
+ if (browser_window_set_scroll(bw, &rect) != NSERROR_OK) {
+ NSLOG(netsurf, WARNING,
+ "Unable to set browser scroll offsets to %d by %d",
+ scrollx, scrolly);
+ }
+ }
+
browser_window_history_update(bw, c);
hotlist_update_url(hlcache_handle_get_url(c));
@@ -1810,7 +1831,7 @@ static void browser_window_destroy_internal(struct browser_window *bw)
{
assert(bw);
- LOG("Destroying window");
+ NSLOG(netsurf, INFO, "Destroying window");
if (bw->children != NULL || bw->iframes != NULL) {
browser_window_destroy_children(bw);
@@ -1830,7 +1851,8 @@ static void browser_window_destroy_internal(struct browser_window *bw)
/* The ugly cast here is so the reformat function can be
* passed a gui window pointer in its API rather than void*
*/
- LOG("Clearing reformat schedule for browser window %p", bw);
+ NSLOG(netsurf, INFO,
+ "Clearing reformat schedule for browser window %p", bw);
guit->misc->schedule(-1, scheduled_reformat, bw);
/* If this brower window is not the root window, and has focus, unset
@@ -1910,7 +1932,8 @@ static void browser_window_destroy_internal(struct browser_window *bw)
free(bw->name);
free(bw->status.text);
bw->status.text = NULL;
- LOG("Status text cache match:miss %d:%d", bw->status.match, bw->status.miss);
+ NSLOG(netsurf, INFO, "Status text cache match:miss %d:%d",
+ bw->status.match, bw->status.miss);
}
/**
@@ -2003,14 +2026,28 @@ browser_window_navigate(struct browser_window *bw,
assert(bw);
assert(url);
- LOG("bw %p, url %s", bw, nsurl_access(url));
+ NSLOG(netsurf, INFO, "bw %p, url %s", bw, nsurl_access(url));
+
+ /* If we're navigating and we have a history entry and a content
+ * then update the history entry before we navigate to save our
+ * current state. However since history navigation pre-moves
+ * the history state, we ensure that we only do this if we've not
+ * been suppressed. In the suppressed case, the history code
+ * updates the history itself before navigating.
+ */
+ if (bw->current_content != NULL &&
+ bw->history != NULL &&
+ bw->history->current != NULL &&
+ !(flags & BW_NAVIGATE_NO_TERMINAL_HISTORY_UPDATE)) {
+ browser_window_history_update(bw, bw->current_content);
+ }
/* don't allow massively nested framesets */
for (cur = bw; cur->parent; cur = cur->parent) {
depth++;
}
if (depth > FRAME_DEPTH) {
- LOG("frame depth too high.");
+ NSLOG(netsurf, INFO, "frame depth too high.");
return NSERROR_FRAME_DEPTH;
}
@@ -2102,7 +2139,7 @@ browser_window_navigate(struct browser_window *bw,
browser_window_remove_caret(bw, false);
browser_window_destroy_children(bw);
- LOG("Loading '%s'", nsurl_access(url));
+ NSLOG(netsurf, INFO, "Loading '%s'", nsurl_access(url));
browser_window_set_status(bw, messages_get("Loading"));
bw->history_add = (flags & BW_NAVIGATE_HISTORY);
@@ -2318,7 +2355,8 @@ void browser_window_set_dimensions(struct browser_window *bw,
bw->width = width;
bw->height = height;
} else {
- LOG("Asked to set dimensions of front end window.");
+ NSLOG(netsurf, INFO,
+ "Asked to set dimensions of front end window.");
assert(0);
}
}
@@ -2348,6 +2386,11 @@ static bool frag_scroll(struct browser_window *bw)
rect.x1 = rect.x0;
rect.y1 = rect.y0;
if (browser_window_set_scroll(bw, &rect) == NSERROR_OK) {
+ if (bw->current_content != NULL &&
+ bw->history != NULL &&
+ bw->history->current != NULL) {
+ browser_window_history_update(bw, bw->current_content);
+ }
return true;
}
return false;
diff --git a/desktop/browser_history.c b/desktop/browser_history.c
index dbbc67daf..640302773 100644
--- a/desktop/browser_history.c
+++ b/desktop/browser_history.c
@@ -32,6 +32,7 @@
#include "utils/utils.h"
#include "netsurf/layout.h"
#include "netsurf/content.h"
+#include "netsurf/window.h"
#include "content/hlcache.h"
#include "content/urldb.h"
#include "netsurf/bitmap.h"
@@ -50,7 +51,7 @@
* Clone a history entry
*
* \param history opaque history structure, as returned by history_create()
- * \param entry entry to clone
+ * \param entry entry to clone
* \return A cloned history entry or NULL on error
*/
static struct history_entry *
@@ -62,47 +63,85 @@ browser_window_history__clone_entry(struct history *history,
struct history_entry *prev = NULL;
struct history_entry *new_entry;
+ assert(entry);
assert(entry->page.url);
assert(entry->page.title);
/* clone the entry */
- new_entry = malloc(sizeof *entry);
- if (!new_entry)
+ new_entry = calloc(1, sizeof *entry);
+ if (!new_entry) {
return NULL;
+ }
- memcpy(new_entry, entry, sizeof *entry);
- new_entry->page.url = nsurl_ref(entry->page.url);
- if (entry->page.frag_id)
- new_entry->page.frag_id = lwc_string_ref(entry->page.frag_id);
-
+ /* copy page information */
new_entry->page.title = strdup(entry->page.title);
- if (!new_entry->page.url || !new_entry->page.title ||
- ((entry->page.frag_id) && (!new_entry->page.frag_id))) {
- nsurl_unref(new_entry->page.url);
- if (new_entry->page.frag_id)
- lwc_string_unref(new_entry->page.frag_id);
+ if (new_entry->page.title == NULL) {
+ free(new_entry);
+ return NULL;
+ }
+
+ new_entry->page.url = nsurl_ref(entry->page.url);
+ if (new_entry->page.url == NULL) {
free(new_entry->page.title);
free(new_entry);
return NULL;
}
- /* update references */
- if (history->current == entry)
- history->current = new_entry;
+ if (entry->page.frag_id == NULL) {
+ new_entry->page.frag_id = NULL;
+ } else {
+ new_entry->page.frag_id = lwc_string_ref(entry->page.frag_id);
+ if (new_entry->page.frag_id == NULL) {
+ nsurl_unref(new_entry->page.url);
+ free(new_entry);
+ return NULL;
+ }
+ }
+
+ if (entry->page.bitmap == NULL) {
+ new_entry->page.bitmap = NULL;
+ } else {
+ /* create a new bitmap and copy original into it */
+ unsigned char *bmsrc_data;
+ unsigned char *bmdst_data;
+ size_t bmsize;
+
+ new_entry->page.bitmap = guit->bitmap->create(WIDTH, HEIGHT,
+ BITMAP_NEW | BITMAP_OPAQUE);
+
+ if (new_entry->page.bitmap != NULL) {
+ bmsrc_data = guit->bitmap->get_buffer(entry->page.bitmap);
+ bmdst_data = guit->bitmap->get_buffer(new_entry->page.bitmap);
+ bmsize = guit->bitmap->get_rowstride(new_entry->page.bitmap) *
+ guit->bitmap->get_height(new_entry->page.bitmap);
+ memcpy(bmdst_data, bmsrc_data, bmsize);
+ }
+ }
+
+ /* copy tree values */
+ new_entry->back = entry->back;
+ new_entry->next = entry->next;
+ new_entry->forward = entry->forward;
+ new_entry->forward_pref = entry->forward_pref;
+ new_entry->forward_last = entry->forward_last;
/* recurse for all children */
- for (child = new_entry->forward; child; child = child->next) {
+ for (child = new_entry->forward; child != NULL; child = child->next) {
new_child = browser_window_history__clone_entry(history, child);
- if (new_child) {
- new_child->back = new_entry;
- } else {
+ if (new_child == NULL) {
nsurl_unref(new_entry->page.url);
- if (new_entry->page.frag_id)
+ if (new_entry->page.frag_id) {
lwc_string_unref(new_entry->page.frag_id);
+ }
free(new_entry->page.title);
+ if (entry->page.bitmap != NULL) {
+ guit->bitmap->destroy(entry->page.bitmap);
+ }
free(new_entry);
return NULL;
}
+
+ new_child->back = new_entry;
if (prev)
prev->next = new_child;
if (new_entry->forward == child)
@@ -113,6 +152,12 @@ browser_window_history__clone_entry(struct history *history,
new_entry->forward_last = new_child;
prev = new_child;
}
+
+ /* update references */
+ if (history->current == entry) {
+ history->current = new_entry;
+ }
+
return new_entry;
}
@@ -123,15 +168,20 @@ browser_window_history__clone_entry(struct history *history,
static void browser_window_history__free_entry(struct history_entry *entry)
{
- if (!entry)
- return;
- browser_window_history__free_entry(entry->forward);
- browser_window_history__free_entry(entry->next);
- nsurl_unref(entry->page.url);
- if (entry->page.frag_id)
- lwc_string_unref(entry->page.frag_id);
- free(entry->page.title);
- free(entry);
+ if (entry != NULL) {
+ browser_window_history__free_entry(entry->forward);
+ browser_window_history__free_entry(entry->next);
+
+ nsurl_unref(entry->page.url);
+ if (entry->page.frag_id) {
+ lwc_string_unref(entry->page.frag_id);
+ }
+ free(entry->page.title);
+ if (entry->page.bitmap != NULL) {
+ guit->bitmap->destroy(entry->page.bitmap);
+ }
+ free(entry);
+ }
}
@@ -286,7 +336,7 @@ nserror browser_window_history_clone(const struct browser_window *existing,
new_history->start = browser_window_history__clone_entry(new_history,
new_history->start);
if (!new_history->start) {
- LOG("Insufficient memory to clone history");
+ NSLOG(netsurf, INFO, "Insufficient memory to clone history");
browser_window_history_destroy(clone);
clone->history = NULL;
return NSERROR_NOMEM;
@@ -297,14 +347,14 @@ nserror browser_window_history_clone(const struct browser_window *existing,
/* exported interface documented in desktop/browser_history.h */
-nserror browser_window_history_add(struct browser_window *bw,
- struct hlcache_handle *content, lwc_string *frag_id)
+nserror
+browser_window_history_add(struct browser_window *bw,
+ struct hlcache_handle *content,
+ lwc_string *frag_id)
{
struct history *history;
struct history_entry *entry;
- nsurl *nsurl = hlcache_handle_get_url(content);
char *title;
- struct bitmap *bitmap;
nserror ret;
assert(bw);
@@ -313,32 +363,50 @@ nserror browser_window_history_add(struct browser_window *bw,
history = bw->history;
- /* allocate space */
entry = malloc(sizeof *entry);
if (entry == NULL) {
return NSERROR_NOMEM;
}
+ /* page information */
title = strdup(content_get_title(content));
if (title == NULL) {
free(entry);
return NSERROR_NOMEM;
}
- entry->page.url = nsurl_ref(nsurl);
- entry->page.frag_id = frag_id ? lwc_string_ref(frag_id) : 0;
-
+ entry->page.url = nsurl_ref(hlcache_handle_get_url(content));
+ entry->page.frag_id = frag_id ? lwc_string_ref(frag_id) : NULL;
entry->page.title = title;
+ entry->page.scroll_x = 0.0f;
+ entry->page.scroll_y = 0.0f;
+
+ /* create thumbnail for localhistory view */
+ NSLOG(netsurf, DEBUG,
+ "Creating thumbnail for %s", nsurl_access(entry->page.url));
+
+ entry->page.bitmap = guit->bitmap->create(WIDTH, HEIGHT,
+ BITMAP_NEW | BITMAP_CLEAR_MEMORY | BITMAP_OPAQUE);
+ if (entry->page.bitmap != NULL) {
+ ret = guit->bitmap->render(entry->page.bitmap, content);
+ if (ret != NSERROR_OK) {
+ /* Thumbnail render failed */
+ NSLOG(netsurf, WARNING, "Thumbnail render failed");
+ }
+ }
+
+ /* insert into tree */
entry->back = history->current;
- entry->next = 0;
- entry->forward = entry->forward_pref = entry->forward_last = 0;
+ entry->next = NULL;
+ entry->forward = entry->forward_pref = entry->forward_last = NULL;
entry->children = 0;
- entry->bitmap = 0;
+
if (history->current) {
- if (history->current->forward_last)
+ if (history->current->forward_last) {
history->current->forward_last->next = entry;
- else
+ } else {
history->current->forward = entry;
+ }
history->current->forward_pref = entry;
history->current->forward_last = entry;
history->current->children++;
@@ -347,33 +415,6 @@ nserror browser_window_history_add(struct browser_window *bw,
}
history->current = entry;
- /* if we have a thumbnail, don't update until the page has finished
- * loading */
- bitmap = urldb_get_thumbnail(nsurl);
- if (bitmap == NULL) {
- LOG("Creating thumbnail for %s", nsurl_access(nsurl));
- bitmap = guit->bitmap->create(WIDTH, HEIGHT,
- BITMAP_NEW | BITMAP_CLEAR_MEMORY |
- BITMAP_OPAQUE);
- if (bitmap != NULL) {
- ret = guit->bitmap->render(bitmap, content);
- if (ret == NSERROR_OK) {
- /* Successful thumbnail so register it
- * with the url.
- */
- urldb_set_thumbnail(nsurl, bitmap);
- } else {
- /* Thumbnailing failed. Ignore it
- * silently but clean up bitmap.
- */
- LOG("Thumbnail renderfailed");
- guit->bitmap->destroy(bitmap);
- bitmap = NULL;
- }
- }
- }
- entry->bitmap = bitmap;
-
browser_window_history__layout(history);
return NSERROR_OK;
@@ -386,12 +427,15 @@ nserror browser_window_history_update(struct browser_window *bw,
{
struct history *history;
char *title;
+ int sx, sy;
assert(bw != NULL);
history = bw->history;
- if (!history || !history->current || !history->current->bitmap) {
+ if (!history ||
+ !history->current ||
+ !history->current->page.bitmap) {
return NSERROR_INVALID;
}
@@ -402,16 +446,50 @@ nserror browser_window_history_update(struct browser_window *bw,
if (title == NULL) {
return NSERROR_NOMEM;
}
-
+ NSLOG(netsurf, INFO, "Updating history entry for %s", title);
free(history->current->page.title);
history->current->page.title = title;
- guit->bitmap->render(history->current->bitmap, content);
+ if (history->current->page.bitmap != NULL) {
+ guit->bitmap->render(history->current->page.bitmap, content);
+ }
+ if (bw->window != NULL &&
+ guit->window->get_scroll(bw->window, &sx, &sy)) {
+ /* Successfully got scroll offsets, update the entry */
+ history->current->page.scroll_x = \
+ (float)sx / (float)content_get_width(content);
+ history->current->page.scroll_y = \
+ (float)sy / (float)content_get_height(content);
+ NSLOG(netsurf, INFO, "Updated scroll offsets to %g by %g",
+ history->current->page.scroll_x,
+ history->current->page.scroll_y);
+ }
return NSERROR_OK;
}
+/* exported interface documented in desktop/browser_private.h */
+nserror
+browser_window_history_get_scroll(struct browser_window *bw,
+ float *sx, float *sy)
+{
+ struct history *history;
+
+ assert(bw != NULL);
+ history = bw->history;
+
+ if (!history ||
+ !history->current ||
+ !history->current->page.bitmap) {
+ return NSERROR_INVALID;
+ }
+
+ *sx = history->current->page.scroll_x;
+ *sy = history->current->page.scroll_y;
+
+ return NSERROR_OK;
+}
/* exported interface documented in desktop/browser_history.h */
void browser_window_history_destroy(struct browser_window *bw)
@@ -470,6 +548,27 @@ bool browser_window_history_forward_available(struct browser_window *bw)
bw->history->current->forward_pref);
}
+/* exported interface documented in desktop/browser_history.h */
+nserror
+browser_window_history_get_thumbnail(struct browser_window *bw,
+ struct bitmap **bitmap_out)
+{
+ struct bitmap *bitmap;
+
+ if (!bw || !bw->history || !bw->history->current) {
+ return NSERROR_INVALID;
+ }
+
+ if (bw->history->current->page.bitmap == NULL) {
+ bitmap = content_get_bitmap(bw->current_content);
+ } else {
+ bitmap = bw->history->current->page.bitmap;
+ }
+
+ *bitmap_out = bitmap;
+
+ return NSERROR_OK;
+}
/* exported interface documented in desktop/browser_history.h */
nserror browser_window_history_go(struct browser_window *bw,
@@ -502,9 +601,11 @@ nserror browser_window_history_go(struct browser_window *bw,
url, NULL, bw, NULL);
history->current = current;
} else {
+ browser_window_history_update(bw, bw->current_content);
history->current = entry;
error = browser_window_navigate(bw, url, NULL,
- BW_NAVIGATE_NONE, NULL, NULL, NULL);
+ BW_NAVIGATE_NO_TERMINAL_HISTORY_UPDATE,
+ NULL, NULL, NULL);
}
nsurl_unref(url);
@@ -514,7 +615,7 @@ nserror browser_window_history_go(struct browser_window *bw,
/* exported interface documented in desktop/browser_history.h */
-void browser_window_history_enumerate_forward(const struct browser_window *bw,
+void browser_window_history_enumerate_forward(const struct browser_window *bw,
browser_window_history_enumerate_cb cb, void *user_data)
{
struct history_entry *e;
@@ -532,7 +633,7 @@ void browser_window_history_enumerate_forward(const struct browser_window *bw,
/* exported interface documented in desktop/browser_history.h */
-void browser_window_history_enumerate_back(const struct browser_window *bw,
+void browser_window_history_enumerate_back(const struct browser_window *bw,
browser_window_history_enumerate_cb cb, void *user_data)
{
struct history_entry *e;
diff --git a/desktop/browser_history.h b/desktop/browser_history.h
index 9140e2ce0..9b6f1fd42 100644
--- a/desktop/browser_history.h
+++ b/desktop/browser_history.h
@@ -37,6 +37,7 @@
struct browser_window;
struct history_entry;
+struct bitmap;
/**
* Go back in the history.
@@ -75,6 +76,14 @@ bool browser_window_history_back_available(struct browser_window *bw);
*/
bool browser_window_history_forward_available(struct browser_window *bw);
+/**
+ * Get the thumbnail bitmap for the current history entry
+ *
+ * \param bw The browser window
+ * \param bitmap The bitmat for the current history entry.
+ * \return NSERROR_OK or error code on faliure.
+ */
+nserror browser_window_history_get_thumbnail(struct browser_window *bw, struct bitmap **bitmap_out);
/**
* Callback function type for history enumeration
@@ -136,21 +145,19 @@ struct nsurl *browser_window_history_entry_get_url(const struct history_entry *e
/**
* Returns the URL to a history entry
*
- * \param entry the history entry to retrieve the fragment id from
- * \return the fragment id
+ * \param entry the history entry to retrieve the fragment id from
+ * \return the fragment id
*/
-const char *browser_window_history_entry_get_fragment_id(
- const struct history_entry *entry);
+const char *browser_window_history_entry_get_fragment_id(const struct history_entry *entry);
/**
* Returns the title of a history entry
*
- * \param entry the history entry to retrieve the title from
- * \return the title
+ * \param entry The history entry to retrieve the title from
+ * \return the title
*/
-const char *browser_window_history_entry_get_title(
- const struct history_entry *entry);
+const char *browser_window_history_entry_get_title(const struct history_entry *entry);
/**
@@ -161,7 +168,6 @@ const char *browser_window_history_entry_get_title(
* \param new_window open entry in new window
* \return NSERROR_OK or error code on faliure.
*/
-nserror browser_window_history_go(struct browser_window *bw,
- struct history_entry *entry, bool new_window);
+nserror browser_window_history_go(struct browser_window *bw, struct history_entry *entry, bool new_window);
#endif
diff --git a/desktop/browser_private.h b/desktop/browser_private.h
index 8bbc573eb..192d22bf0 100644
--- a/desktop/browser_private.h
+++ b/desktop/browser_private.h
@@ -45,6 +45,9 @@ struct history_page {
struct nsurl *url; /**< Page URL, never NULL. */
lwc_string *frag_id; /** Fragment identifier, or NULL. */
char *title; /**< Page title, never NULL. */
+ struct bitmap *bitmap; /**< Thumbnail bitmap, or NULL. */
+ float scroll_x; /**< Scroll X offset when visited */
+ float scroll_y; /**< Scroll Y offset when visited */
};
/**
@@ -61,7 +64,6 @@ struct history_entry {
unsigned int children; /**< Number of children. */
int x; /**< Position of node. */
int y; /**< Position of node. */
- struct bitmap *bitmap; /**< Thumbnail bitmap, or 0. */
};
/**
@@ -325,7 +327,7 @@ nserror browser_window_history_add(struct browser_window *bw,
struct hlcache_handle *content, lwc_string *frag_id);
/**
- * Update the thumbnail for the current entry.
+ * Update the thumbnail and scroll offsets for the current entry.
*
* \param bw The browser window to update the history within.
* \param content content for current entry
@@ -335,6 +337,17 @@ nserror browser_window_history_update(struct browser_window *bw,
struct hlcache_handle *content);
/**
+ * Retrieve the stored scroll offsets for the current history entry
+ *
+ * \param bw The browser window to retrieve scroll offsets for.
+ * \param sx Pointer to a float for the X scroll offset
+ * \param sy Pointer to a float for the Y scroll offset
+ * \return NSERROR_OK or error code on failure.
+ */
+nserror browser_window_history_get_scroll(struct browser_window *bw,
+ float *sx, float *sy);
+
+/**
* Free a history structure.
*
* \param bw The browser window to destroy the history within.
diff --git a/desktop/cookie_manager.c b/desktop/cookie_manager.c
index 5429f6864..a2aab8e9f 100644
--- a/desktop/cookie_manager.c
+++ b/desktop/cookie_manager.c
@@ -576,7 +576,9 @@ static nserror cookie_manager_init_entry_fields(void)
goto error;
}
- cm_ctx.fields[COOKIE_M_DOMAIN].flags = TREE_FLAG_SHOW_NAME;
+ cm_ctx.fields[COOKIE_M_DOMAIN].flags =
+ TREE_FLAG_SHOW_NAME |
+ TREE_FLAG_SEARCHABLE;
label = "TreeviewLabelDomain";
label = messages_get(label);
if (lwc_intern_string(label, strlen(label),
@@ -718,7 +720,8 @@ static void cookie_manager_delete_entry(struct cookie_manager_entry *e)
urldb_delete_cookie(domain, path, name);
} else {
- LOG("Delete cookie fail: ""need domain, path, and name.");
+ NSLOG(netsurf, INFO,
+ "Delete cookie fail: ""need domain, path, and name.");
}
}
@@ -788,7 +791,7 @@ nserror cookie_manager_init(struct core_window_callback_table *cw_t,
return err;
}
- LOG("Generating cookie manager data");
+ NSLOG(netsurf, INFO, "Generating cookie manager data");
/* Init. cookie manager treeview entry fields */
err = cookie_manager_init_entry_fields();
@@ -808,7 +811,9 @@ nserror cookie_manager_init(struct core_window_callback_table *cw_t,
err = treeview_create(&cm_ctx.tree, &cm_tree_cb_t,
COOKIE_M_N_FIELDS, cm_ctx.fields,
cw_t, core_window_handle,
- TREEVIEW_NO_MOVES | TREEVIEW_DEL_EMPTY_DIRS);
+ TREEVIEW_NO_MOVES |
+ TREEVIEW_DEL_EMPTY_DIRS |
+ TREEVIEW_SEARCHABLE);
if (err != NSERROR_OK) {
cm_ctx.tree = NULL;
return err;
@@ -825,7 +830,7 @@ nserror cookie_manager_init(struct core_window_callback_table *cw_t,
/* Inform client of window height */
treeview_get_height(cm_ctx.tree);
- LOG("Generated cookie manager data");
+ NSLOG(netsurf, INFO, "Generated cookie manager data");
return NSERROR_OK;
}
@@ -837,7 +842,7 @@ nserror cookie_manager_fini(void)
int i;
nserror err;
- LOG("Finalising cookie manager");
+ NSLOG(netsurf, INFO, "Finalising cookie manager");
cm_ctx.built = false;
@@ -860,7 +865,7 @@ nserror cookie_manager_fini(void)
return err;
}
- LOG("Finalised cookie manager");
+ NSLOG(netsurf, INFO, "Finalised cookie manager");
return err;
}
diff --git a/desktop/font_haru.c b/desktop/font_haru.c
index caa751bcb..f92d89197 100644
--- a/desktop/font_haru.c
+++ b/desktop/font_haru.c
@@ -74,7 +74,10 @@ const struct font_functions haru_nsfont = {
static void error_handler(HPDF_STATUS error_no, HPDF_STATUS detail_no,
void *user_data)
{
- LOG("ERROR: in font_haru \n\terror_no=%x\n\tdetail_no=%d\n", (HPDF_UINT)error_no, (HPDF_UINT)detail_no);
+ NSLOG(netsurf, INFO,
+ "ERROR: in font_haru \n\terror_no=%x\n\tdetail_no=%d\n",
+ (HPDF_UINT)error_no,
+ (HPDF_UINT)detail_no);
#ifdef FONT_HARU_DEBUG
exit(1);
#endif
@@ -143,7 +146,9 @@ bool haru_nsfont_width(const plot_font_style_t *fstyle,
*width = width_real;
#ifdef FONT_HARU_DEBUG
- LOG("Measuring string: %s ; Calculated width: %f %i", string_nt, width_real, *width);
+ NSLOG(netsurf, INFO,
+ "Measuring string: %s ; Calculated width: %f %i", string_nt,
+ width_real, *width);
#endif
free(string_nt);
HPDF_Free(pdf);
@@ -201,7 +206,11 @@ bool haru_nsfont_position_in_string(const plot_font_style_t *fstyle,
*actual_x = real_width;
#ifdef FONT_HARU_DEBUG
- LOG("Position in string: %s at x: %i; Calculated position: %i", string_nt, x, *char_offset);
+ NSLOG(netsurf, INFO,
+ "Position in string: %s at x: %i; Calculated position: %i",
+ string_nt,
+ x,
+ *char_offset);
#endif
free(string_nt);
HPDF_Free(pdf);
@@ -246,7 +255,12 @@ bool haru_nsfont_split(const plot_font_style_t *fstyle,
HPDF_TRUE, &real_width);
#ifdef FONT_HARU_DEBUG
- LOG("Splitting string: %s for width: %i ; Calculated position: %i Calculated real_width: %f", string_nt, x, *char_offset, real_width);
+ NSLOG(netsurf, INFO,
+ "Splitting string: %s for width: %i ; Calculated position: %i Calculated real_width: %f",
+ string_nt,
+ x,
+ *char_offset,
+ real_width);
#endif
*char_offset = offset - 1;
@@ -327,7 +341,7 @@ bool haru_nsfont_apply_style(const plot_font_style_t *fstyle,
strcat(font_name, "-Roman");
#ifdef FONT_HARU_DEBUG
- LOG("Setting font: %s", font_name);
+ NSLOG(netsurf, INFO, "Setting font: %s", font_name);
#endif
size = fstyle->size;
diff --git a/desktop/frames.c b/desktop/frames.c
index 9eefefe02..e22287630 100644
--- a/desktop/frames.c
+++ b/desktop/frames.c
@@ -354,9 +354,11 @@ nserror browser_window_create_frameset(struct browser_window *bw,
window->parent = bw;
if (window->name)
- LOG("Created frame '%s'", window->name);
+ NSLOG(netsurf, INFO, "Created frame '%s'",
+ window->name);
else
- LOG("Created frame (unnamed)");
+ NSLOG(netsurf, INFO,
+ "Created frame (unnamed)");
}
}
diff --git a/desktop/global_history.c b/desktop/global_history.c
index a19349f51..ad39a3e41 100644
--- a/desktop/global_history.c
+++ b/desktop/global_history.c
@@ -536,7 +536,9 @@ static nserror global_history_initialise_entry_fields(void)
goto error;
}
- gh_ctx.fields[GH_URL].flags = TREE_FLAG_COPY_TEXT;
+ gh_ctx.fields[GH_URL].flags =
+ TREE_FLAG_COPY_TEXT |
+ TREE_FLAG_SEARCHABLE;
label = "TreeviewLabelURL";
label = messages_get(label);
if (lwc_intern_string(label, strlen(label),
@@ -596,7 +598,7 @@ static nserror global_history_initialise_time(void)
/* get the current time */
t = time(NULL);
if (t == -1) {
- LOG("time info unaviable");
+ NSLOG(netsurf, INFO, "time info unaviable");
return NSERROR_UNKNOWN;
}
@@ -607,7 +609,7 @@ static nserror global_history_initialise_time(void)
full_time->tm_hour = 0;
t = mktime(full_time);
if (t == -1) {
- LOG("mktime failed");
+ NSLOG(netsurf, INFO, "mktime failed");
return NSERROR_UNKNOWN;
}
@@ -729,7 +731,7 @@ nserror global_history_init(struct core_window_callback_table *cw_t,
return err;
}
- LOG("Loading global history");
+ NSLOG(netsurf, INFO, "Loading global history");
/* Init. global history treeview time */
err = global_history_initialise_time();
@@ -752,7 +754,8 @@ nserror global_history_init(struct core_window_callback_table *cw_t,
err = treeview_create(&gh_ctx.tree, &gh_tree_cb_t,
N_FIELDS, gh_ctx.fields,
cw_t, core_window_handle,
- TREEVIEW_NO_MOVES | TREEVIEW_DEL_EMPTY_DIRS);
+ TREEVIEW_NO_MOVES | TREEVIEW_DEL_EMPTY_DIRS |
+ TREEVIEW_SEARCHABLE);
if (err != NSERROR_OK) {
gh_ctx.tree = NULL;
return err;
@@ -785,7 +788,7 @@ nserror global_history_init(struct core_window_callback_table *cw_t,
/* Inform client of window height */
treeview_get_height(gh_ctx.tree);
- LOG("Loaded global history");
+ NSLOG(netsurf, INFO, "Loaded global history");
return NSERROR_OK;
}
@@ -797,7 +800,7 @@ nserror global_history_fini(void)
int i;
nserror err;
- LOG("Finalising global history");
+ NSLOG(netsurf, INFO, "Finalising global history");
gh_ctx.built = false;
@@ -815,7 +818,7 @@ nserror global_history_fini(void)
return err;
}
- LOG("Finalised global history");
+ NSLOG(netsurf, INFO, "Finalised global history");
return err;
}
@@ -832,7 +835,8 @@ nserror global_history_add(nsurl *url)
data = urldb_get_url_data(url);
if (data == NULL) {
- LOG("Can't add URL to history that's not present in urldb.");
+ NSLOG(netsurf, INFO,
+ "Can't add URL to history that's not present in urldb.");
return NSERROR_BAD_PARAMETER;
}
diff --git a/desktop/hotlist.c b/desktop/hotlist.c
index 0f5be77c9..4bdd7c8cb 100644
--- a/desktop/hotlist.c
+++ b/desktop/hotlist.c
@@ -138,7 +138,8 @@ static nserror hotlist_save(const char *path)
/* Replace any old hotlist file with the one we just saved */
if (rename(temp_path, path) != 0) {
res = NSERROR_SAVE_FAILED;
- LOG("Error renaming hotlist: %s.", strerror(errno));
+ NSLOG(netsurf, INFO, "Error renaming hotlist: %s.",
+ strerror(errno));
goto cleanup;
}
@@ -652,20 +653,20 @@ static nserror hotlist_load_entry(dom_node *li, hotlist_load_ctx *ctx)
/* The li must contain an "a" element */
a = libdom_find_first_element(li, corestring_lwc_a);
if (a == NULL) {
- LOG("Missing <a> in <li>");
+ NSLOG(netsurf, INFO, "Missing <a> in <li>");
return NSERROR_INVALID;
}
derror = dom_node_get_text_content(a, &title1);
if (derror != DOM_NO_ERR) {
- LOG("No title");
+ NSLOG(netsurf, INFO, "No title");
dom_node_unref(a);
return NSERROR_INVALID;
}
derror = dom_element_get_attribute(a, corestring_dom_href, &url1);
if (derror != DOM_NO_ERR || url1 == NULL) {
- LOG("No URL");
+ NSLOG(netsurf, INFO, "No URL");
dom_string_unref(title1);
dom_node_unref(a);
return NSERROR_INVALID;
@@ -683,7 +684,8 @@ static nserror hotlist_load_entry(dom_node *li, hotlist_load_ctx *ctx)
dom_string_unref(url1);
if (err != NSERROR_OK) {
- LOG("Failed normalising '%s'", dom_string_data(url1));
+ NSLOG(netsurf, INFO, "Failed normalising '%s'",
+ dom_string_data(url1));
if (title1 != NULL) {
dom_string_unref(title1);
@@ -763,7 +765,8 @@ nserror hotlist_load_directory_cb(dom_node *node, void *ctx)
error = dom_node_get_text_content(node, &title);
if (error != DOM_NO_ERR || title == NULL) {
- LOG("Empty <h4> or memory exhausted.");
+ NSLOG(netsurf, INFO,
+ "Empty <h4> or memory exhausted.");
dom_string_unref(name);
return NSERROR_DOM;
}
@@ -861,7 +864,7 @@ static nserror hotlist_load(const char *path, bool *loaded)
/* Handle no path */
if (path == NULL) {
- LOG("No hotlist file path provided.");
+ NSLOG(netsurf, INFO, "No hotlist file path provided.");
return NSERROR_OK;
}
@@ -1195,8 +1198,10 @@ static nserror hotlist_initialise_entry_fields(void)
goto error;
}
- hl_ctx.fields[HL_URL].flags = TREE_FLAG_ALLOW_EDIT |
- TREE_FLAG_COPY_TEXT;
+ hl_ctx.fields[HL_URL].flags =
+ TREE_FLAG_ALLOW_EDIT |
+ TREE_FLAG_COPY_TEXT |
+ TREE_FLAG_SEARCHABLE;
label = "TreeviewLabelURL";
label = messages_get(label);
if (lwc_intern_string(label, strlen(label),
@@ -1283,7 +1288,7 @@ nserror hotlist_init(
return err;
}
- LOG("Loading hotlist");
+ NSLOG(netsurf, INFO, "Loading hotlist");
hl_ctx.tree = NULL;
hl_ctx.built = false;
@@ -1310,7 +1315,7 @@ nserror hotlist_init(
/* Create the hotlist treeview */
err = treeview_create(&hl_ctx.tree, &hl_tree_cb_t,
HL_N_FIELDS, hl_ctx.fields, NULL, NULL,
- TREEVIEW_NO_FLAGS);
+ TREEVIEW_SEARCHABLE);
if (err != NSERROR_OK) {
free(hl_ctx.save_path);
hl_ctx.tree = NULL;
@@ -1329,7 +1334,7 @@ nserror hotlist_init(
* the treeview is built. */
hl_ctx.built = true;
- LOG("Loaded hotlist");
+ NSLOG(netsurf, INFO, "Loaded hotlist");
return NSERROR_OK;
}
@@ -1375,7 +1380,7 @@ nserror hotlist_fini(void)
int i;
nserror err;
- LOG("Finalising hotlist");
+ NSLOG(netsurf, INFO, "Finalising hotlist");
/* Remove any existing scheduled save callback */
guit->misc->schedule(-1, hotlist_schedule_save_cb, NULL);
@@ -1384,7 +1389,7 @@ nserror hotlist_fini(void)
/* Save the hotlist */
err = hotlist_save(hl_ctx.save_path);
if (err != NSERROR_OK) {
- LOG("Problem saving the hotlist.");
+ NSLOG(netsurf, INFO, "Problem saving the hotlist.");
}
free(hl_ctx.save_path);
@@ -1403,7 +1408,7 @@ nserror hotlist_fini(void)
return err;
}
- LOG("Finalised hotlist");
+ NSLOG(netsurf, INFO, "Finalised hotlist");
return err;
}
diff --git a/desktop/knockout.c b/desktop/knockout.c
index 7e964fc84..6dbf4ebcf 100644
--- a/desktop/knockout.c
+++ b/desktop/knockout.c
@@ -267,7 +267,9 @@ static nserror knockout_plot_flush(const struct redraw_context *ctx)
/* debugging information */
#ifdef KNOCKOUT_DEBUG
- LOG("Entries are %i/%i, %i/%i, %i/%i", knockout_entry_cur, KNOCKOUT_ENTRIES, knockout_box_cur, KNOCKOUT_BOXES, knockout_polygon_cur, KNOCKOUT_POLYGONS);
+ NSLOG(netsurf, INFO, "Entries are %i/%i, %i/%i, %i/%i",
+ knockout_entry_cur, KNOCKOUT_ENTRIES, knockout_box_cur,
+ KNOCKOUT_BOXES, knockout_polygon_cur, KNOCKOUT_POLYGONS);
#endif
for (i = 0; i < knockout_entry_cur; i++) {
@@ -702,8 +704,8 @@ knockout_plot_clip(const struct redraw_context *ctx, const struct rect *clip)
if (clip->x1 < clip->x0 || clip->y0 > clip->y1) {
#ifdef KNOCKOUT_DEBUG
- LOG("bad clip rectangle %i %i %i %i",
- clip->x0, clip->y0, clip->x1, clip->y1);
+ NSLOG(netsurf, INFO, "bad clip rectangle %i %i %i %i",
+ clip->x0, clip->y0, clip->x1, clip->y1);
#endif
return NSERROR_BAD_SIZE;
}
diff --git a/desktop/local_history.c b/desktop/local_history.c
index 01222e204..3219de90c 100644
--- a/desktop/local_history.c
+++ b/desktop/local_history.c
@@ -144,9 +144,9 @@ redraw_entry(struct history *history,
}
/* Only attempt to plot bitmap if it is present */
- if (entry->bitmap != NULL) {
+ if (entry->page.bitmap != NULL) {
res = ctx->plot->bitmap(ctx,
- entry->bitmap,
+ entry->page.bitmap,
entry->x + x,
entry->y + y,
WIDTH, HEIGHT,
diff --git a/desktop/mouse.c b/desktop/mouse.c
index 6d22fd461..d22910582 100644
--- a/desktop/mouse.c
+++ b/desktop/mouse.c
@@ -30,5 +30,5 @@
*/
void browser_mouse_state_dump(browser_mouse_state mouse)
{
- LOG("mouse state: %s %s %s %s %s %s %s %s %s %s %s %s %s %s", mouse & BROWSER_MOUSE_PRESS_1 ? "P1" : " ", mouse & BROWSER_MOUSE_PRESS_2 ? "P2" : " ", mouse & BROWSER_MOUSE_CLICK_1 ? "C1" : " ", mouse & BROWSER_MOUSE_CLICK_2 ? "C2" : " ", mouse & BROWSER_MOUSE_DOUBLE_CLICK ? "DC" : " ", mouse & BROWSER_MOUSE_TRIPLE_CLICK ? "TC" : " ", mouse & BROWSER_MOUSE_DRAG_1 ? "D1" : " ", mouse & BROWSER_MOUSE_DRAG_2 ? "D2" : " ", mouse & BROWSER_MOUSE_DRAG_ON ? "DO" : " ", mouse & BROWSER_MOUSE_HOLDING_1 ? "H1" : " ", mouse & BROWSER_MOUSE_HOLDING_2 ? "H2" : " ", mouse & BROWSER_MOUSE_MOD_1 ? "M1" : " ", mouse & BROWSER_MOUSE_MOD_2 ? "M2" : " ", mouse & BROWSER_MOUSE_MOD_3 ? "M3" : " ");
+ NSLOG(netsurf, INFO, "mouse state: %s %s %s %s %s %s %s %s %s %s %s %s %s %s", mouse & BROWSER_MOUSE_PRESS_1 ? "P1" : " ", mouse & BROWSER_MOUSE_PRESS_2 ? "P2" : " ", mouse & BROWSER_MOUSE_CLICK_1 ? "C1" : " ", mouse & BROWSER_MOUSE_CLICK_2 ? "C2" : " ", mouse & BROWSER_MOUSE_DOUBLE_CLICK ? "DC" : " ", mouse & BROWSER_MOUSE_TRIPLE_CLICK ? "TC" : " ", mouse & BROWSER_MOUSE_DRAG_1 ? "D1" : " ", mouse & BROWSER_MOUSE_DRAG_2 ? "D2" : " ", mouse & BROWSER_MOUSE_DRAG_ON ? "DO" : " ", mouse & BROWSER_MOUSE_HOLDING_1 ? "H1" : " ", mouse & BROWSER_MOUSE_HOLDING_2 ? "H2" : " ", mouse & BROWSER_MOUSE_MOD_1 ? "M1" : " ", mouse & BROWSER_MOUSE_MOD_2 ? "M2" : " ", mouse & BROWSER_MOUSE_MOD_3 ? "M3" : " ");
}
diff --git a/desktop/netsurf.c b/desktop/netsurf.c
index 3baa936f3..8aa949a5a 100644
--- a/desktop/netsurf.c
+++ b/desktop/netsurf.c
@@ -89,7 +89,8 @@
static void netsurf_lwc_iterator(lwc_string *str, void *pw)
{
- LOG("[%3u] %.*s", str->refcnt, (int)lwc_string_length(str), lwc_string_data(str));
+ NSLOG(netsurf, INFO, "[%3u] %.*s", str->refcnt,
+ (int)lwc_string_length(str), lwc_string_data(str));
}
/**
@@ -165,8 +166,9 @@ nserror netsurf_init(const char *store_path)
if (hlcache_parameters.llcache.limit < MINIMUM_MEMORY_CACHE_SIZE) {
hlcache_parameters.llcache.limit = MINIMUM_MEMORY_CACHE_SIZE;
- LOG("Setting minimum memory cache size %" PRIsizet,
- hlcache_parameters.llcache.limit);
+ NSLOG(netsurf, INFO,
+ "Setting minimum memory cache size %"PRIsizet,
+ hlcache_parameters.llcache.limit);
}
/* Set up the max attempts made to fetch a timing out resource */
@@ -243,19 +245,19 @@ void netsurf_exit(void)
{
hlcache_stop();
- LOG("Closing GUI");
+ NSLOG(netsurf, INFO, "Closing GUI");
guit->misc->quit();
- LOG("Finalising JavaScript");
+ NSLOG(netsurf, INFO, "Finalising JavaScript");
js_finalise();
- LOG("Finalising Web Search");
+ NSLOG(netsurf, INFO, "Finalising Web Search");
search_web_finalise();
- LOG("Finalising high-level cache");
+ NSLOG(netsurf, INFO, "Finalising high-level cache");
hlcache_finalise();
- LOG("Closing fetches");
+ NSLOG(netsurf, INFO, "Closing fetches");
fetcher_quit();
/* dump any remaining cache entries */
@@ -264,21 +266,21 @@ void netsurf_exit(void)
/* Clean up after content handlers */
content_factory_fini();
- LOG("Closing utf8");
+ NSLOG(netsurf, INFO, "Closing utf8");
utf8_finalise();
- LOG("Destroying URLdb");
+ NSLOG(netsurf, INFO, "Destroying URLdb");
urldb_destroy();
- LOG("Destroying System colours");
+ NSLOG(netsurf, INFO, "Destroying System colours");
ns_system_colour_finalize();
- LOG("Destroying Messages");
+ NSLOG(netsurf, INFO, "Destroying Messages");
messages_destroy();
corestrings_fini();
- LOG("Remaining lwc strings:");
+ NSLOG(netsurf, INFO, "Remaining lwc strings:");
lwc_iterate_strings(netsurf_lwc_iterator, NULL);
- LOG("Exited successfully");
+ NSLOG(netsurf, INFO, "Exited successfully");
}
diff --git a/desktop/options.h b/desktop/options.h
index d91898c6e..9b7064efa 100644
--- a/desktop/options.h
+++ b/desktop/options.h
@@ -289,3 +289,8 @@ NSOPTION_COLOUR(sys_colour_ThreeDShadow, 0x00d5d5d5)
NSOPTION_COLOUR(sys_colour_Window, 0x00f1f1f1)
NSOPTION_COLOUR(sys_colour_WindowFrame, 0x004e4e4e)
NSOPTION_COLOUR(sys_colour_WindowText, 0x00000000)
+
+/** Filter for non-verbose logging */
+NSOPTION_STRING(log_filter, "level:WARNING")
+/** Filter for verbose logging */
+NSOPTION_STRING(verbose_filter, "level:VERBOSE")
diff --git a/desktop/print.c b/desktop/print.c
index 37172b7c1..54cc5451a 100644
--- a/desktop/print.c
+++ b/desktop/print.c
@@ -126,8 +126,10 @@ print_apply_settings(hlcache_handle *content, struct print_settings *settings)
content_reformat(content, false, page_content_width, 0);
- LOG("New layout applied.New height = %d ; New width = %d ",
- content_get_height(content), content_get_width(content));
+ NSLOG(netsurf, INFO,
+ "New layout applied.New height = %d ; New width = %d ",
+ content_get_height(content),
+ content_get_width(content));
return true;
}
diff --git a/desktop/save_complete.c b/desktop/save_complete.c
index d6fb2feb1..9a88ad180 100644
--- a/desktop/save_complete.c
+++ b/desktop/save_complete.c
@@ -168,7 +168,7 @@ static bool save_complete_save_buffer(save_complete_ctx *ctx,
fp = fopen(fname, "wb");
if (fp == NULL) {
free(fname);
- LOG("fopen(): errno = %i", errno);
+ NSLOG(netsurf, INFO, "fopen(): errno = %i", errno);
guit->misc->warning("SaveError", strerror(errno));
return false;
}
@@ -195,10 +195,12 @@ static bool save_complete_save_buffer(save_complete_ctx *ctx,
* \param osize updated with the size of the result.
* \return converted source, or NULL on out of memory.
*/
-
-static char *save_complete_rewrite_stylesheet_urls(save_complete_ctx *ctx,
- const char *source, unsigned long size, const nsurl *base,
- unsigned long *osize)
+static char *
+save_complete_rewrite_stylesheet_urls(save_complete_ctx *ctx,
+ const char *source,
+ unsigned long size,
+ const nsurl *base,
+ unsigned long *osize)
{
char *rewritten;
unsigned long offset = 0;
@@ -207,8 +209,9 @@ static char *save_complete_rewrite_stylesheet_urls(save_complete_ctx *ctx,
/* count number occurrences of @import to (over)estimate result size */
/* can't use strstr because source is not 0-terminated string */
- for (offset = 0; SLEN("@import") < size &&
- offset <= size - SLEN("@import"); offset++) {
+ for (offset = 0;
+ (SLEN("@import") < size) && (offset <= (size - SLEN("@import")));
+ offset++) {
if (source[offset] == '@' &&
ascii_to_lower(source[offset + 1]) == 'i' &&
ascii_to_lower(source[offset + 2]) == 'm' &&
@@ -1044,7 +1047,7 @@ static bool save_complete_node_handler(dom_node *node,
} else if (type == DOM_DOCUMENT_NODE) {
/* Do nothing */
} else {
- LOG("Unhandled node type: %d", type);
+ NSLOG(netsurf, INFO, "Unhandled node type: %d", type);
}
return true;
@@ -1075,7 +1078,7 @@ static bool save_complete_save_html_document(save_complete_ctx *ctx,
fp = fopen(fname, "wb");
if (fp == NULL) {
free(fname);
- LOG("fopen(): errno = %i", errno);
+ NSLOG(netsurf, INFO, "fopen(): errno = %i", errno);
guit->misc->warning("SaveError", strerror(errno));
return false;
}
@@ -1154,7 +1157,7 @@ static bool save_complete_inventory(save_complete_ctx *ctx)
fp = fopen(fname, "w");
free(fname);
if (fp == NULL) {
- LOG("fopen(): errno = %i", errno);
+ NSLOG(netsurf, INFO, "fopen(): errno = %i", errno);
guit->misc->warning("SaveError", strerror(errno));
return false;
}
@@ -1182,7 +1185,8 @@ static nserror regcomp_wrapper(regex_t *preg, const char *regex, int cflags)
if (r) {
char errbuf[200];
regerror(r, preg, errbuf, sizeof errbuf);
- LOG("Failed to compile regexp '%s': %s\n", regex, errbuf);
+ NSLOG(netsurf, INFO, "Failed to compile regexp '%s': %s\n",
+ regex, errbuf);
return NSERROR_INIT_FAILED;
}
return NSERROR_OK;
diff --git a/desktop/save_pdf.c b/desktop/save_pdf.c
index d303eca7c..83e3d4f31 100644
--- a/desktop/save_pdf.c
+++ b/desktop/save_pdf.c
@@ -171,7 +171,8 @@ bool pdf_plot_rectangle(int x0, int y0, int x1, int y1, const plot_style_t *psty
{
DashPattern_e dash;
#ifdef PDF_DEBUG
- LOG("%d %d %d %d %f %X", x0, y0, x1, y1, page_height - y0, pstyle->fill_colour);
+ NSLOG(netsurf, INFO, "%d %d %d %d %f %X", x0, y0, x1, y1,
+ page_height - y0, pstyle->fill_colour);
#endif
if (pstyle->fill_type != PLOT_OP_TYPE_NONE) {
@@ -262,7 +263,7 @@ bool pdf_plot_polygon(const int *p, unsigned int n, const plot_style_t *style)
#ifdef PDF_DEBUG
int pmaxx = p[0], pmaxy = p[1];
int pminx = p[0], pminy = p[1];
- LOG(".");
+ NSLOG(netsurf, INFO, ".");
#endif
if (n == 0)
return true;
@@ -281,7 +282,8 @@ bool pdf_plot_polygon(const int *p, unsigned int n, const plot_style_t *style)
}
#ifdef PDF_DEBUG
- LOG("%d %d %d %d %f", pminx, pminy, pmaxx, pmaxy, page_height - pminy);
+ NSLOG(netsurf, INFO, "%d %d %d %d %f", pminx, pminy, pmaxx, pmaxy,
+ page_height - pminy);
#endif
HPDF_Page_Fill(pdf_page);
@@ -294,7 +296,8 @@ bool pdf_plot_polygon(const int *p, unsigned int n, const plot_style_t *style)
bool pdf_plot_clip(const struct rect *clip)
{
#ifdef PDF_DEBUG
- LOG("%d %d %d %d", clip->x0, clip->y0, clip->x1, clip->y1);
+ NSLOG(netsurf, INFO, "%d %d %d %d", clip->x0, clip->y0, clip->x1,
+ clip->y1);
#endif
/*Normalize cllipping area - to prevent overflows.
@@ -314,7 +317,7 @@ bool pdf_plot_text(int x, int y, const char *text, size_t length,
const plot_font_style_t *fstyle)
{
#ifdef PDF_DEBUG
- LOG(". %d %d %.*s", x, y, (int)length, text);
+ NSLOG(netsurf, INFO, ". %d %d %.*s", x, y, (int)length, text);
#endif
char *word;
HPDF_Font pdf_font;
@@ -347,7 +350,7 @@ bool pdf_plot_text(int x, int y, const char *text, size_t length,
bool pdf_plot_disc(int x, int y, int radius, const plot_style_t *style)
{
#ifdef PDF_DEBUG
- LOG(".");
+ NSLOG(netsurf, INFO, ".");
#endif
if (style->fill_type != PLOT_OP_TYPE_NONE) {
apply_clip_and_mode(false,
@@ -378,7 +381,8 @@ bool pdf_plot_disc(int x, int y, int radius, const plot_style_t *style)
bool pdf_plot_arc(int x, int y, int radius, int angle1, int angle2, const plot_style_t *style)
{
#ifdef PDF_DEBUG
- LOG("%d %d %d %d %d %X", x, y, radius, angle1, angle2, style->stroke_colour);
+ NSLOG(netsurf, INFO, "%d %d %d %d %d %X", x, y, radius, angle1,
+ angle2, style->stroke_colour);
#endif
/* FIXME: line width 1 is ok ? */
@@ -406,7 +410,8 @@ bool pdf_plot_bitmap_tile(int x, int y, int width, int height,
HPDF_REAL max_width, max_height;
#ifdef PDF_DEBUG
- LOG("%d %d %d %d %p 0x%x", x, y, width, height, bitmap, bg);
+ NSLOG(netsurf, INFO, "%d %d %d %d %p 0x%x", x, y, width, height,
+ bitmap, bg);
#endif
if (width == 0 || height == 0)
return true;
@@ -483,7 +488,8 @@ HPDF_Image pdf_extract_image(struct bitmap *bitmap)
rgb_buffer = (unsigned char *)malloc(3 * img_width * img_height);
alpha_buffer = (unsigned char *)malloc(img_width * img_height);
if (rgb_buffer == NULL || alpha_buffer == NULL) {
- LOG("Not enough memory to create RGB buffer");
+ NSLOG(netsurf, INFO,
+ "Not enough memory to create RGB buffer");
free(rgb_buffer);
free(alpha_buffer);
return NULL;
@@ -607,7 +613,7 @@ bool pdf_plot_path(const float *p, unsigned int n, colour fill, float width,
bool empty_path;
#ifdef PDF_DEBUG
- LOG(".");
+ NSLOG(netsurf, INFO, ".");
#endif
if (n == 0)
@@ -649,7 +655,7 @@ bool pdf_plot_path(const float *p, unsigned int n, colour fill, float width,
i += 7;
empty_path = false;
} else {
- LOG("bad path command %f", p[i]);
+ NSLOG(netsurf, INFO, "bad path command %f", p[i]);
return false;
}
}
@@ -685,7 +691,7 @@ bool pdf_begin(struct print_settings *print_settings)
HPDF_Free(pdf_doc);
pdf_doc = HPDF_New(error_handler, NULL);
if (!pdf_doc) {
- LOG("Error creating pdf_doc");
+ NSLOG(netsurf, INFO, "Error creating pdf_doc");
return false;
}
@@ -708,7 +714,7 @@ bool pdf_begin(struct print_settings *print_settings)
pdf_page = NULL;
#ifdef PDF_DEBUG
- LOG("pdf_begin finishes");
+ NSLOG(netsurf, INFO, "pdf_begin finishes");
#endif
return true;
}
@@ -717,7 +723,7 @@ bool pdf_begin(struct print_settings *print_settings)
bool pdf_next_page(void)
{
#ifdef PDF_DEBUG
- LOG("pdf_next_page begins");
+ NSLOG(netsurf, INFO, "pdf_next_page begins");
#endif
clip_update_needed = false;
if (pdf_page != NULL) {
@@ -745,7 +751,7 @@ bool pdf_next_page(void)
pdfw_gs_save(pdf_page);
#ifdef PDF_DEBUG
- LOG("%f %f", page_width, page_height);
+ NSLOG(netsurf, INFO, "%f %f", page_width, page_height);
#endif
return true;
@@ -755,7 +761,7 @@ bool pdf_next_page(void)
void pdf_end(void)
{
#ifdef PDF_DEBUG
- LOG("pdf_end begins");
+ NSLOG(netsurf, INFO, "pdf_end begins");
#endif
clip_update_needed = false;
if (pdf_page != NULL) {
@@ -780,7 +786,7 @@ void pdf_end(void)
else
save_pdf(settings->output);
#ifdef PDF_DEBUG
- LOG("pdf_end finishes");
+ NSLOG(netsurf, INFO, "pdf_end finishes");
#endif
}
@@ -819,7 +825,8 @@ nserror save_pdf(const char *path)
static void error_handler(HPDF_STATUS error_no, HPDF_STATUS detail_no,
void *user_data)
{
- LOG("ERROR:\n\terror_no=%x\n\tdetail_no=%d\n", (HPDF_UINT)error_no, (HPDF_UINT)detail_no);
+ NSLOG(netsurf, INFO, "ERROR:\n\terror_no=%x\n\tdetail_no=%d\n",
+ (HPDF_UINT)error_no, (HPDF_UINT)detail_no);
#ifdef PDF_DEBUG
exit(1);
#endif
diff --git a/desktop/save_text.c b/desktop/save_text.c
index e63c96eb9..791ae9201 100644
--- a/desktop/save_text.c
+++ b/desktop/save_text.c
@@ -75,7 +75,8 @@ void save_as_text(struct hlcache_handle *c, char *path)
free(save.block);
if (ret != NSERROR_OK) {
- LOG("failed to convert to local encoding, return %d", ret);
+ NSLOG(netsurf, INFO,
+ "failed to convert to local encoding, return %d", ret);
return;
}
@@ -84,12 +85,13 @@ void save_as_text(struct hlcache_handle *c, char *path)
int res = fputs(result, out);
if (res < 0) {
- LOG("Warning: write failed");
+ NSLOG(netsurf, INFO, "Warning: write failed");
}
res = fputs("\n", out);
if (res < 0) {
- LOG("Warning: failed writing trailing newline");
+ NSLOG(netsurf, INFO,
+ "Warning: failed writing trailing newline");
}
fclose(out);
diff --git a/desktop/searchweb.c b/desktop/searchweb.c
index 29a998eb2..c07cac9d5 100644
--- a/desktop/searchweb.c
+++ b/desktop/searchweb.c
@@ -289,13 +289,19 @@ search_web_ico_callback(hlcache_handle *ico,
switch (event->type) {
case CONTENT_MSG_DONE:
- LOG("icon '%s' retrieved", nsurl_access(hlcache_handle_get_url(ico)));
+ NSLOG(netsurf, INFO, "icon '%s' retrieved",
+ nsurl_access(hlcache_handle_get_url(ico)));
guit->search_web->provider_update(provider->name,
content_get_bitmap(ico));
break;
case CONTENT_MSG_ERROR:
- LOG("icon %s error: %s", nsurl_access(hlcache_handle_get_url(ico)), event->data.error);
+ NSLOG(netsurf, INFO, "icon %s error: %s",
+ nsurl_access(hlcache_handle_get_url(ico)),
+ event->data.error);
+ /* fall through */
+
+ case CONTENT_MSG_ERRORCODE:
hlcache_handle_release(ico);
/* clear reference to released handle */
provider->ico_handle = NULL;
@@ -438,7 +444,8 @@ default_ico_callback(hlcache_handle *ico,
switch (event->type) {
case CONTENT_MSG_DONE:
- LOG("default icon '%s' retrieved", nsurl_access(hlcache_handle_get_url(ico)));
+ NSLOG(netsurf, INFO, "default icon '%s' retrieved",
+ nsurl_access(hlcache_handle_get_url(ico)));
/* only set to default icon if providers icon has no handle */
if (ctx->providers[search_web_ctx.current].ico_handle == NULL) {
@@ -449,7 +456,12 @@ default_ico_callback(hlcache_handle *ico,
break;
case CONTENT_MSG_ERROR:
- LOG("icon %s error: %s", nsurl_access(hlcache_handle_get_url(ico)), event->data.error);
+ NSLOG(netsurf, INFO, "icon %s error: %s",
+ nsurl_access(hlcache_handle_get_url(ico)),
+ event->data.error);
+ /* fall through */
+
+ case CONTENT_MSG_ERRORCODE:
hlcache_handle_release(ico);
/* clear reference to released handle */
ctx->default_ico_handle = NULL;
diff --git a/desktop/sslcert_viewer.c b/desktop/sslcert_viewer.c
index e7f87bd9d..f40af5968 100644
--- a/desktop/sslcert_viewer.c
+++ b/desktop/sslcert_viewer.c
@@ -391,7 +391,7 @@ sslcert_viewer_init(struct core_window_callback_table *cw_t,
return err;
}
- LOG("Building certificate viewer");
+ NSLOG(netsurf, INFO, "Building certificate viewer");
/* Init. certificate chain treeview entry fields */
err = sslcert_init_entry_fields(ssl_d);
@@ -417,7 +417,7 @@ sslcert_viewer_init(struct core_window_callback_table *cw_t,
}
}
- LOG("Built certificate viewer");
+ NSLOG(netsurf, INFO, "Built certificate viewer");
return NSERROR_OK;
}
@@ -452,7 +452,7 @@ nserror sslcert_viewer_fini(struct sslcert_session_data *ssl_d)
int i;
nserror err;
- LOG("Finalising ssl certificate viewer");
+ NSLOG(netsurf, INFO, "Finalising ssl certificate viewer");
/* Destroy the treeview */
err = treeview_destroy(ssl_d->tree);
@@ -470,7 +470,7 @@ nserror sslcert_viewer_fini(struct sslcert_session_data *ssl_d)
return err;
}
- LOG("Finalised ssl certificate viewer");
+ NSLOG(netsurf, INFO, "Finalised ssl certificate viewer");
return err;
}
diff --git a/desktop/textarea.c b/desktop/textarea.c
index 65ee8b82f..149ca26b1 100644
--- a/desktop/textarea.c
+++ b/desktop/textarea.c
@@ -828,7 +828,7 @@ static bool textarea_reflow_singleline(struct textarea *ta, size_t b_off,
ta->lines =
malloc(LINE_CHUNK_SIZE * sizeof(struct line_info));
if (ta->lines == NULL) {
- LOG("malloc failed");
+ NSLOG(netsurf, INFO, "malloc failed");
return false;
}
ta->lines_alloc_size = LINE_CHUNK_SIZE;
@@ -852,7 +852,7 @@ static bool textarea_reflow_singleline(struct textarea *ta, size_t b_off,
char *temp = realloc(ta->password.data,
b_len + TA_ALLOC_STEP);
if (temp == NULL) {
- LOG("realloc failed");
+ NSLOG(netsurf, INFO, "realloc failed");
return false;
}
@@ -936,7 +936,8 @@ static bool textarea_reflow_multiline(struct textarea *ta,
if (ta->lines == NULL) {
ta->lines = calloc(sizeof(struct line_info), LINE_CHUNK_SIZE);
if (ta->lines == NULL) {
- LOG("Failed to allocate memory for textarea lines");
+ NSLOG(netsurf, INFO,
+ "Failed to allocate memory for textarea lines");
return false;
}
ta->lines_alloc_size = LINE_CHUNK_SIZE;
@@ -1053,7 +1054,7 @@ static bool textarea_reflow_multiline(struct textarea *ta,
(line + 2 + LINE_CHUNK_SIZE) *
sizeof(struct line_info));
if (temp == NULL) {
- LOG("realloc failed");
+ NSLOG(netsurf, INFO, "realloc failed");
return false;
}
@@ -1334,7 +1335,7 @@ static bool textarea_insert_text(struct textarea *ta, const char *text,
char *temp = realloc(ta->text.data, b_len + ta->text.len +
TA_ALLOC_STEP);
if (temp == NULL) {
- LOG("realloc failed");
+ NSLOG(netsurf, INFO, "realloc failed");
return false;
}
@@ -1484,7 +1485,7 @@ static bool textarea_replace_text_internal(struct textarea *ta, size_t b_start,
rep_len + ta->text.len - (b_end - b_start) +
TA_ALLOC_STEP);
if (temp == NULL) {
- LOG("realloc failed");
+ NSLOG(netsurf, INFO, "realloc failed");
return false;
}
@@ -1561,7 +1562,7 @@ static bool textarea_copy_to_undo_buffer(struct textarea *ta,
char *temp = realloc(undo->text.data,
b_offset + len + TA_ALLOC_STEP);
if (temp == NULL) {
- LOG("realloc failed");
+ NSLOG(netsurf, INFO, "realloc failed");
return false;
}
@@ -1575,7 +1576,7 @@ static bool textarea_copy_to_undo_buffer(struct textarea *ta,
(undo->next_detail + 128) *
sizeof(struct textarea_undo_detail));
if (temp == NULL) {
- LOG("realloc failed");
+ NSLOG(netsurf, INFO, "realloc failed");
return false;
}
@@ -1835,13 +1836,13 @@ struct textarea *textarea_create(const textarea_flags flags,
flags & TEXTAREA_PASSWORD));
if (callback == NULL) {
- LOG("no callback provided");
+ NSLOG(netsurf, INFO, "no callback provided");
return NULL;
}
ret = malloc(sizeof(struct textarea));
if (ret == NULL) {
- LOG("malloc failed");
+ NSLOG(netsurf, INFO, "malloc failed");
return NULL;
}
@@ -1888,7 +1889,7 @@ struct textarea *textarea_create(const textarea_flags flags,
ret->text.data = malloc(TA_ALLOC_STEP);
if (ret->text.data == NULL) {
- LOG("malloc failed");
+ NSLOG(netsurf, INFO, "malloc failed");
free(ret);
return NULL;
}
@@ -1900,7 +1901,7 @@ struct textarea *textarea_create(const textarea_flags flags,
if (flags & TEXTAREA_PASSWORD) {
ret->password.data = malloc(TA_ALLOC_STEP);
if (ret->password.data == NULL) {
- LOG("malloc failed");
+ NSLOG(netsurf, INFO, "malloc failed");
free(ret->text.data);
free(ret);
return NULL;
@@ -1975,7 +1976,7 @@ bool textarea_set_text(struct textarea *ta, const char *text)
if (len >= ta->text.alloc) {
char *temp = realloc(ta->text.data, len + TA_ALLOC_STEP);
if (temp == NULL) {
- LOG("realloc failed");
+ NSLOG(netsurf, INFO, "realloc failed");
return false;
}
ta->text.data = temp;
@@ -2062,7 +2063,7 @@ int textarea_get_text(struct textarea *ta, char *buf, unsigned int len)
}
if (len < ta->text.len) {
- LOG("buffer too small");
+ NSLOG(netsurf, INFO, "buffer too small");
return -1;
}
@@ -2073,6 +2074,17 @@ int textarea_get_text(struct textarea *ta, char *buf, unsigned int len)
/* exported interface, documented in textarea.h */
+const char * textarea_data(struct textarea *ta, unsigned int *len)
+{
+ if (len != NULL) {
+ *len = ta->text.len;
+ }
+
+ return ta->text.data;
+}
+
+
+/* exported interface, documented in textarea.h */
bool textarea_set_caret(struct textarea *ta, int caret)
{
int b_off;
@@ -2849,7 +2861,7 @@ bool textarea_keypress(struct textarea *ta, uint32_t key)
return false;
}
- redraw &= ~textarea_set_caret_internal(ta, caret);
+ redraw &= !textarea_set_caret_internal(ta, caret);
/* TODO: redraw only the bit that changed */
msg.ta = ta;
diff --git a/desktop/textarea.h b/desktop/textarea.h
index 898609730..b386e50e8 100644
--- a/desktop/textarea.h
+++ b/desktop/textarea.h
@@ -213,6 +213,16 @@ int textarea_get_text(struct textarea *ta, char *buf, unsigned int len);
/**
+ * Access text data in a text area
+ *
+ * \param[in] ta Text area
+ * \param[out] len Returns byte length of returned text, if passed non-NULL.
+ * \return textarea string data.
+ */
+const char * textarea_data(struct textarea *ta, unsigned int *len);
+
+
+/**
* Set the caret's position
*
* \param ta Text area
diff --git a/desktop/treeview.c b/desktop/treeview.c
index fe3aa94c3..1651ff5ef 100644
--- a/desktop/treeview.c
+++ b/desktop/treeview.c
@@ -22,10 +22,13 @@
* Treeview handling implementation.
*/
+#include <string.h>
+
#include "utils/utils.h"
#include "utils/log.h"
#include "utils/nsurl.h"
#include "utils/nsoption.h"
+#include "utils/config.h"
#include "netsurf/bitmap.h"
#include "netsurf/content.h"
#include "netsurf/plotters.h"
@@ -104,7 +107,8 @@ enum treeview_node_flags {
TV_NFLAGS_NONE = 0, /**< No node flags set */
TV_NFLAGS_EXPANDED = (1 << 0), /**< Whether node is expanded */
TV_NFLAGS_SELECTED = (1 << 1), /**< Whether node is selected */
- TV_NFLAGS_SPECIAL = (1 << 2) /**< Render as special node */
+ TV_NFLAGS_SPECIAL = (1 << 2), /**< Render as special node */
+ TV_NFLAGS_MATCHED = (1 << 3), /**< Whether node matches search */
};
@@ -171,7 +175,8 @@ struct treeview_drag {
TV_DRAG_NONE,
TV_DRAG_SELECTION,
TV_DRAG_MOVE,
- TV_DRAG_TEXTAREA
+ TV_DRAG_TEXTAREA,
+ TV_DRAG_SEARCH,
} type; /**< Drag type */
treeview_node *start_node; /**< Start node */
bool selected; /**< Start node is selected */
@@ -207,6 +212,17 @@ struct treeview_edit {
/**
+ * Treeview search box details
+ */
+struct treeview_search {
+ struct textarea *textarea; /**< Search box. */
+ bool active; /**< Whether the search box has focus. */
+ bool search; /**< Whether we have a search term. */
+ int height; /**< Current search display height. */
+};
+
+
+/**
* The treeview context
*/
struct treeview {
@@ -224,6 +240,8 @@ struct treeview {
struct treeview_move move; /**< Move drag details */
struct treeview_edit edit; /**< Edit details */
+ struct treeview_search search; /**< Treeview search box */
+
const struct treeview_callback_table *callbacks; /**< For node events */
const struct core_window_callback_table *cw_t; /**< Window cb table */
@@ -310,14 +328,28 @@ static struct treeview_resource treeview_res[TREE_RES_LAST] = {
/**
+ * Get the display height of the treeview data component of the display.
+ *
+ * \param[in] tree Treeview to get the height of.
+ * \return the display height in pixels.
+ */
+static inline int treeview__get_display_height(treeview *tree)
+{
+ return (tree->search.search == false) ?
+ tree->root->height :
+ tree->search.height;
+}
+
+
+/**
* Corewindow callback wrapper: Request a redraw of the window
*
* \param[in] tree The treeview to request redraw on.
* \param[in] r rectangle to redraw
*/
-static inline
-void cw_invalidate_area(const struct treeview *tree,
- const struct rect *r)
+static inline void treeview__cw_invalidate_area(
+ const struct treeview *tree,
+ const struct rect *r)
{
if (tree->cw_t != NULL) {
tree->cw_t->invalidate(tree->cw_h, r);
@@ -336,8 +368,33 @@ static inline void treeview__cw_update_size(
const struct treeview *tree,
int width, int height)
{
+ int search_height = (tree->flags & TREEVIEW_SEARCHABLE) ?
+ tree_g.line_height : 0;
+
+ if (tree->cw_t != NULL) {
+ tree->cw_t->update_size(tree->cw_h, width,
+ height + search_height);
+ }
+}
+
+
+/**
+ * Corewindow callback_wrapper: Scroll to top of window.
+ *
+ * \param[in] tree The treeview to scroll.
+ */
+static inline void treeview__cw_scroll_top(
+ const struct treeview *tree)
+{
+ struct rect r = {
+ .x0 = 0,
+ .y0 = 0,
+ .x1 = tree_g.window_padding,
+ .y1 = tree_g.line_height,
+ };
+
if (tree->cw_t != NULL) {
- tree->cw_t->update_size(tree->cw_h, width, height);
+ tree->cw_t->scroll_visible(tree->cw_h, &r);
}
}
@@ -496,10 +553,35 @@ static int treeview_node_y(treeview *tree, treeview_node *node)
/**
+ * The treeview walk mode. Controls which nodes are visited in a walk.
+ */
+enum treeview_walk_mode {
+ /**
+ * Walk to all nodes in the (sub)tree.
+ */
+ TREEVIEW_WALK_MODE_LOGICAL_COMPLETE,
+
+ /**
+ * Walk to expanded nodes in the (sub)tree only. Children of
+ * collapsed nodes are not visited.
+ */
+ TREEVIEW_WALK_MODE_LOGICAL_EXPANDED,
+
+ /**
+ * Walk displayed nodes. This differs from the
+ * `TREEVIEW_WALK_MODE_LOGICAL_EXPANDED` mode when there is
+ * an active search filter display.
+ */
+ TREEVIEW_WALK_MODE_DISPLAY,
+};
+
+
+/**
* Walk a treeview subtree, calling a callback at each node (depth first)
*
+ * \param tree Treeview being walked.
* \param root Root to walk tree from (doesn't get a callback call)
- * \param full Iff true, visit children of collapsed nodes
+ * \param mode The treeview walk mode to use.
* \param callback_bwd Function to call on each node in backwards order
* \param callback_fwd Function to call on each node in forwards order
* \param ctx Context to pass to callback
@@ -507,30 +589,46 @@ static int treeview_node_y(treeview *tree, treeview_node *node)
*
* \note Any node deletion must happen in callback_bwd.
*/
-static nserror
-treeview_walk_internal(treeview_node *root,
- bool full,
- nserror (*callback_bwd)(treeview_node *n, void *ctx, bool *end),
- nserror (*callback_fwd)(treeview_node *n, void *ctx, bool *skip_children, bool *end),
- void *ctx)
+static nserror treeview_walk_internal(
+ treeview *tree,
+ treeview_node *root,
+ enum treeview_walk_mode mode,
+ nserror (*callback_bwd)(
+ treeview_node *n,
+ void *ctx,
+ bool *end),
+ nserror (*callback_fwd)(
+ treeview_node *n,
+ void *ctx,
+ bool *skip_children,
+ bool *end),
+ void *ctx)
{
treeview_node *node, *child, *parent, *next_sibling;
- bool abort = false;
+ bool walking_search = (mode == TREEVIEW_WALK_MODE_DISPLAY &&
+ tree->search.search == true);
bool skip_children = false;
+ bool abort = false;
+ bool full = false;
nserror err;
+ bool entry;
assert(root != NULL);
+ if (mode == TREEVIEW_WALK_MODE_LOGICAL_COMPLETE || walking_search) {
+ /* We need to visit children of collapsed folders. */
+ full = true;
+ }
+
node = root;
parent = node->parent;
next_sibling = node->next_sib;
- child = (!skip_children &&
- (full || (node->flags & TV_NFLAGS_EXPANDED))) ?
+ child = (full || (node->flags & TV_NFLAGS_EXPANDED)) ?
node->children : NULL;
while (node != NULL) {
- if (child != NULL) {
+ if (child != NULL && !skip_children) {
/* Down to children */
node = child;
} else {
@@ -538,9 +636,10 @@ treeview_walk_internal(treeview_node *root,
* go to next sibling if present, or nearest ancestor
* with a next sibling. */
- while (node != root &&
- next_sibling == NULL) {
- if (callback_bwd != NULL) {
+ while (node != root && next_sibling == NULL) {
+ entry = (node->type == TREE_NODE_ENTRY);
+ if (callback_bwd != NULL &&
+ (entry || !walking_search)) {
/* Backwards callback */
err = callback_bwd(node, ctx, &abort);
@@ -580,11 +679,18 @@ treeview_walk_internal(treeview_node *root,
assert(node != NULL);
assert(node != root);
+ entry = (node->type == TREE_NODE_ENTRY);
+
parent = node->parent;
next_sibling = node->next_sib;
child = (full || (node->flags & TV_NFLAGS_EXPANDED)) ?
node->children : NULL;
+ if (walking_search && (!entry ||
+ !(node->flags & TV_NFLAGS_MATCHED))) {
+ continue;
+ }
+
if (callback_fwd != NULL) {
/* Forwards callback */
err = callback_fwd(node, ctx, &skip_children, &abort);
@@ -597,13 +703,248 @@ treeview_walk_internal(treeview_node *root,
return NSERROR_OK;
}
}
- child = skip_children ? NULL : child;
}
return NSERROR_OK;
}
/**
+ * Data used when doing a treeview walk for search.
+ */
+struct treeview_search_walk_data {
+ treeview *tree; /**< The treeview to search. */
+ const char *text; /**< The string being searched for. */
+ const unsigned int len; /**< Length of string being searched for. */
+ int window_height; /**< Accumulate height for matching entries. */
+};
+
+
+/**
+ * Treewalk node callback for handling search.
+ *
+ * \param[in] n Current node.
+ * \param[in] ctx Treeview search context.
+ * \param[in,out] skip_children Flag to allow children to be skipped.
+ * \param[in,out] end Flag to allow iteration to be finished early.
+ * \return NSERROR_OK on success else error code.
+ */
+static nserror treeview__search_walk_cb(
+ treeview_node *n,
+ void *ctx,
+ bool *skip_children,
+ bool *end)
+{
+ struct treeview_search_walk_data *sw = ctx;
+
+ if (n->type != TREE_NODE_ENTRY) {
+ return NSERROR_OK;
+ }
+
+ if (sw->len == 0) {
+ n->flags &= ~TV_NFLAGS_MATCHED;
+ } else {
+ struct treeview_node_entry *entry =
+ (struct treeview_node_entry *)n;
+ bool matched = false;
+
+ for (int i = 0; i < sw->tree->n_fields; i++) {
+ struct treeview_field *ef = &(sw->tree->fields[i + 1]);
+ if (ef->flags & TREE_FLAG_SEARCHABLE) {
+ if (strcasestr(entry->fields[i].value.data,
+ sw->text) != NULL) {
+ matched = true;
+ break;
+ }
+ }
+ }
+
+ if (!matched && strcasestr(n->text.data, sw->text) != NULL) {
+ matched = true;
+ }
+
+ if (matched) {
+ n->flags |= TV_NFLAGS_MATCHED;
+ sw->window_height += n->height;
+ } else {
+ n->flags &= ~TV_NFLAGS_MATCHED;
+ }
+ }
+
+ return NSERROR_OK;
+}
+
+
+/**
+ * Search treeview for text.
+ *
+ * \param[in] tree Treeview to search.
+ * \param[in] text UTF-8 string to search for. (NULL-terminated.)
+ * \param[in] len Byte length of UTF-8 string.
+ * \return NSERROR_OK on success, appropriate error otherwise.
+ */
+static nserror treeview__search(
+ treeview *tree,
+ const char *text,
+ unsigned int len)
+{
+ nserror err;
+ uint32_t height;
+ uint32_t prev_height = treeview__get_display_height(tree);
+ int search_height = (tree->flags & TREEVIEW_SEARCHABLE) ?
+ tree_g.line_height : 0;
+ struct treeview_search_walk_data sw = {
+ .len = len,
+ .text = text,
+ .tree = tree,
+ .window_height = 0,
+ };
+ struct rect r = {
+ .x0 = 0,
+ .y0 = search_height,
+ .x1 = REDRAW_MAX,
+ };
+
+ assert(text[len] == '\0');
+
+ if (tree->root == NULL) {
+ return NSERROR_OK;
+ }
+
+ err = treeview_walk_internal(tree, tree->root,
+ TREEVIEW_WALK_MODE_LOGICAL_COMPLETE, NULL,
+ treeview__search_walk_cb, &sw);
+ if (err != NSERROR_OK) {
+ return err;
+ }
+
+ if (len > 0) {
+ tree->search.height = sw.window_height;
+ tree->search.search = true;
+ height = sw.window_height;
+ } else {
+ tree->search.search = false;
+ height = tree->root->height;
+ }
+
+ r.y1 = ((height > prev_height) ? height : prev_height) + search_height;
+ treeview__cw_invalidate_area(tree, &r);
+ treeview__cw_update_size(tree, -1, height);
+ treeview__cw_scroll_top(tree);
+
+ return NSERROR_OK;
+}
+
+
+/**
+ * Cancel a treeview search, optionally droping focus from search widget.
+ *
+ * \param[in] tree Treeview to cancel search in.
+ * \param[in] drop_focus Iff true, drop input focus from search widget.
+ */
+static void treeview__search_cancel(treeview *tree, bool drop_focus)
+{
+ struct rect r = {
+ .x0 = tree_g.window_padding + tree_g.icon_size,
+ .x1 = 600,
+ .y0 = 0,
+ .y1 = tree_g.line_height,
+ };
+
+ tree->search.search = false;
+ if (tree->search.active == false) {
+ return;
+ }
+
+ if (drop_focus) {
+ tree->search.active = false;
+ textarea_set_caret(tree->search.textarea, -1);
+ } else {
+ textarea_set_caret(tree->search.textarea, 0);
+ }
+
+ textarea_set_text(tree->search.textarea, "");
+ treeview__cw_invalidate_area(tree, &r);
+}
+
+
+/**
+ * Callback for textarea_create, in desktop/treeview.h
+ *
+ * \param data treeview context
+ * \param msg textarea message
+ */
+static void treeview_textarea_search_callback(void *data,
+ struct textarea_msg *msg)
+{
+ treeview *tree = data;
+ struct rect *r;
+
+ if (tree->search.active == false || tree->root == NULL) {
+ return;
+ }
+
+ switch (msg->type) {
+ case TEXTAREA_MSG_DRAG_REPORT:
+ if (msg->data.drag == TEXTAREA_DRAG_NONE) {
+ /* Textarea drag finished */
+ tree->drag.type = TV_DRAG_NONE;
+ } else {
+ /* Textarea drag started */
+ tree->drag.type = TV_DRAG_SEARCH;
+ }
+ treeview__cw_drag_status(tree, tree->drag.type);
+ break;
+
+ case TEXTAREA_MSG_REDRAW_REQUEST:
+ r = &msg->data.redraw;
+ r->x0 += tree_g.window_padding + tree_g.icon_size;
+ r->y0 += 0;
+ r->x1 += 600;
+ r->y1 += tree_g.line_height;
+
+ /* Redraw the textarea */
+ treeview__cw_invalidate_area(tree, r);
+ break;
+
+ case TEXTAREA_MSG_TEXT_MODIFIED:
+ /* Textarea length includes trailing NULL, so subtract it. */
+ treeview__search(tree,
+ msg->data.modified.text,
+ msg->data.modified.len - 1);
+ break;
+
+ default:
+ break;
+ }
+}
+
+
+/**
+ * Update the layout for any active search.
+ *
+ * \param[in] tree The tree to update.
+ */
+static void treeview__search_update_display(
+ treeview *tree)
+{
+ const char *string;
+ unsigned int len;
+
+ if (tree->search.search == false) {
+ /* No active search to update view for. */
+ return;
+ }
+
+ string = textarea_data(tree->search.textarea, &len);
+ if (string == NULL || len == 0) {
+ return;
+ }
+
+ treeview__search(tree, string, len - 1);
+}
+
+
+/**
* Create treeview's root node
*
* \param[out] root Returns root node
@@ -668,14 +1009,17 @@ treeview_set_inset_from_parent(treeview_node *n,
/**
* Insert a treeview node into a treeview
*
- * \param a parentless node to insert
- * \param b tree node to insert a as a relation of
+ * \param tree the treeview to insert node into.
+ * \param a parentless node to insert
+ * \param b tree node to insert a as a relation of
* \param rel The relationship between \a a and \a b
*/
static inline void
-treeview_insert_node(treeview_node *a,
- treeview_node *b,
- enum treeview_relationship rel)
+treeview_insert_node(
+ treeview *tree,
+ treeview_node *a,
+ treeview_node *b,
+ enum treeview_relationship rel)
{
assert(a != NULL);
assert(a->parent == NULL);
@@ -710,8 +1054,9 @@ treeview_insert_node(treeview_node *a,
a->inset = a->parent->inset + tree_g.step_width;
if (a->children != NULL) {
- treeview_walk_internal(a, true, NULL,
- treeview_set_inset_from_parent, NULL);
+ treeview_walk_internal(tree, a,
+ TREEVIEW_WALK_MODE_LOGICAL_COMPLETE, NULL,
+ treeview_set_inset_from_parent, NULL);
}
if (a->parent->flags & TV_NFLAGS_EXPANDED) {
@@ -776,7 +1121,7 @@ treeview_create_node_folder(treeview *tree,
n->client_data = data;
- treeview_insert_node(n, relation, rel);
+ treeview_insert_node(tree, n, relation, rel);
if (n->parent->flags & TV_NFLAGS_EXPANDED) {
/* Inform front end of change in dimensions */
@@ -791,7 +1136,7 @@ treeview_create_node_folder(treeview *tree,
r.y0 = treeview_node_y(tree, n);
r.x1 = REDRAW_MAX;
r.y1 = tree->root->height;
- cw_invalidate_area(tree, &r);
+ treeview__cw_invalidate_area(tree, &r);
}
}
@@ -842,7 +1187,7 @@ treeview_update_node_folder(treeview *tree,
r.y0 = treeview_node_y(tree, folder);
r.x1 = REDRAW_MAX;
r.y1 = r.y0 + tree_g.line_height;
- cw_invalidate_area(tree, &r);
+ treeview__cw_invalidate_area(tree, &r);
}
return NSERROR_OK;
@@ -907,6 +1252,8 @@ treeview_update_node_entry(treeview *tree,
}
}
+ treeview__search_update_display(tree);
+
/* Redraw */
if (entry->parent->flags & TV_NFLAGS_EXPANDED) {
struct rect r;
@@ -914,7 +1261,7 @@ treeview_update_node_entry(treeview *tree,
r.y0 = treeview_node_y(tree, entry);
r.x1 = REDRAW_MAX;
r.y1 = r.y0 + entry->height;
- cw_invalidate_area(tree, &r);
+ treeview__cw_invalidate_area(tree, &r);
}
return NSERROR_OK;
@@ -946,7 +1293,7 @@ treeview_create_node_entry(treeview *tree,
}
e = malloc(sizeof(struct treeview_node_entry) +
- (tree->n_fields - 1) * sizeof(struct treeview_field));
+ (tree->n_fields - 1) * sizeof(struct treeview_field));
if (e == NULL) {
return NSERROR_NOMEM;
}
@@ -962,8 +1309,8 @@ treeview_create_node_entry(treeview *tree,
assert(fields != NULL);
assert(fields[0].field != NULL);
assert(lwc_string_isequal(tree->fields[0].field,
- fields[0].field, &match) == lwc_error_ok &&
- match == true);
+ fields[0].field, &match) == lwc_error_ok &&
+ match == true);
n->text.data = fields[0].value;
n->text.len = fields[0].value_len;
n->text.width = 0;
@@ -978,15 +1325,15 @@ treeview_create_node_entry(treeview *tree,
for (i = 1; i < tree->n_fields; i++) {
assert(fields[i].field != NULL);
assert(lwc_string_isequal(tree->fields[i].field,
- fields[i].field, &match) == lwc_error_ok &&
- match == true);
+ fields[i].field, &match) == lwc_error_ok &&
+ match == true);
e->fields[i - 1].value.data = fields[i].value;
e->fields[i - 1].value.len = fields[i].value_len;
e->fields[i - 1].value.width = 0;
}
- treeview_insert_node(n, relation, rel);
+ treeview_insert_node(tree, n, relation, rel);
if (n->parent->flags & TV_NFLAGS_EXPANDED) {
/* Inform front end of change in dimensions */
@@ -1001,10 +1348,12 @@ treeview_create_node_entry(treeview *tree,
r.y0 = treeview_node_y(tree, n);
r.x1 = REDRAW_MAX;
r.y1 = tree->root->height;
- cw_invalidate_area(tree, &r);
+ treeview__cw_invalidate_area(tree, &r);
}
}
+ treeview__search_update_display(tree);
+
*entry = n;
return NSERROR_OK;
@@ -1087,11 +1436,11 @@ treeview_walk(treeview *tree,
if (root == NULL)
root = tree->root;
- return treeview_walk_internal(root,
- true,
- (leave_cb != NULL) ? treeview_walk_bwd_cb : NULL,
- (enter_cb != NULL) ? treeview_walk_fwd_cb : NULL,
- &tw);
+ return treeview_walk_internal(tree, root,
+ TREEVIEW_WALK_MODE_LOGICAL_COMPLETE,
+ (leave_cb != NULL) ? treeview_walk_bwd_cb : NULL,
+ (enter_cb != NULL) ? treeview_walk_fwd_cb : NULL,
+ &tw);
}
@@ -1154,7 +1503,7 @@ static void treeview_edit_cancel(treeview *tree, bool redraw)
r.y0 = tree->edit.y;
r.x1 = tree->edit.x + tree->edit.w;
r.y1 = tree->edit.y + tree->edit.h;
- cw_invalidate_area(tree, &r);
+ treeview__cw_invalidate_area(tree, &r);
}
}
@@ -1316,8 +1665,9 @@ treeview_delete_node_internal(treeview *tree,
}
/* Delete any children first */
- err = treeview_walk_internal(n, true, treeview_delete_node_walk_cb,
- NULL, &nd);
+ err = treeview_walk_internal(tree, n,
+ TREEVIEW_WALK_MODE_LOGICAL_COMPLETE,
+ treeview_delete_node_walk_cb, NULL, &nd);
if (err != NSERROR_OK) {
return err;
}
@@ -1345,6 +1695,8 @@ treeview_delete_node_internal(treeview *tree,
tree->root->height);
}
+ treeview__search_update_display(tree);
+
return NSERROR_OK;
}
@@ -1496,13 +1848,60 @@ treeview_delete_node(treeview *tree,
if (visible && !(flags & TREE_OPTION_SUPPRESS_REDRAW)) {
r.x0 = 0;
r.x1 = REDRAW_MAX;
- cw_invalidate_area(tree, &r);
+ treeview__cw_invalidate_area(tree, &r);
}
return NSERROR_OK;
}
+/**
+ * Helper to create a textarea.
+ *
+ * \param[in] tree The treeview we're creating the textarea for.
+ * \param[in] width The width of the textarea.
+ * \param[in] height The height of the textarea.
+ * \param[in] border The border colour to use.
+ * \param[in] background The background colour to use.
+ * \param[in] foreground The foreground colour to use.
+ * \param[in] text The text style to use for the text area.
+ * \param[in] ta_callback The textarea callback function to give the textarea.
+ * \return the textarea pointer on success, or NULL on failure.
+ */
+static struct textarea *treeview__create_textarea(
+ treeview *tree,
+ int width,
+ int height,
+ colour border,
+ colour background,
+ colour foreground,
+ plot_font_style_t text,
+ textarea_client_callback ta_callback)
+{
+ /* Configure the textarea */
+ textarea_flags ta_flags = TEXTAREA_INTERNAL_CARET;
+ textarea_setup ta_setup = {
+ .text = text,
+ .width = width,
+ .height = height,
+ .pad_top = 0,
+ .pad_left = 2,
+ .pad_right = 2,
+ .pad_bottom = 0,
+ .border_width = 1,
+ .border_col = border,
+ .selected_bg = foreground,
+ .selected_text = background,
+ };
+
+ ta_setup.text.foreground = foreground;
+ ta_setup.text.background = background;
+
+ /* Create text area */
+ return textarea_create(ta_flags, &ta_setup, ta_callback, tree);
+}
+
+
/* Exported interface, documented in treeview.h */
nserror
treeview_create(treeview **tree,
@@ -1582,6 +1981,24 @@ treeview_create(treeview **tree,
(*tree)->edit.textarea = NULL;
(*tree)->edit.node = NULL;
+ if (flags & TREEVIEW_SEARCHABLE) {
+ (*tree)->search.textarea = treeview__create_textarea(
+ *tree, 600, tree_g.line_height,
+ plot_style_even.text.background,
+ plot_style_even.text.background,
+ plot_style_even.text.foreground,
+ plot_style_odd.text,
+ treeview_textarea_search_callback);
+ if ((*tree)->search.textarea == NULL) {
+ treeview_destroy(*tree);
+ return NSERROR_NOMEM;
+ }
+ } else {
+ (*tree)->search.textarea = NULL;
+ }
+ (*tree)->search.active = false;
+ (*tree)->search.search = false;
+
(*tree)->flags = flags;
(*tree)->cw_t = cw_t;
@@ -1601,7 +2018,7 @@ treeview_cw_attach(treeview *tree,
assert(cw != NULL);
if (tree->cw_t != NULL || tree->cw_h != NULL) {
- LOG("Treeview already attached.");
+ NSLOG(netsurf, INFO, "Treeview already attached.");
return NSERROR_UNKNOWN;
}
tree->cw_t = cw_t;
@@ -1617,6 +2034,8 @@ nserror treeview_cw_detach(treeview *tree)
tree->cw_t = NULL;
tree->cw_h = NULL;
+ treeview__search_cancel(tree, true);
+
return NSERROR_OK;
}
@@ -1628,6 +2047,12 @@ nserror treeview_destroy(treeview *tree)
assert(tree != NULL);
+ if (tree->search.textarea != NULL) {
+ tree->search.active = false;
+ tree->search.search = false;
+ textarea_destroy(tree->search.textarea);
+ }
+
/* Destroy nodes */
treeview_delete_node_internal(tree, tree->root, false,
TREE_OPTION_SUPPRESS_RESIZE |
@@ -1666,7 +2091,7 @@ treeview_node_expand_internal(treeview *tree, treeview_node *node)
if (node->flags & TV_NFLAGS_EXPANDED) {
/* What madness is this? */
- LOG("Tried to expand an expanded node.");
+ NSLOG(netsurf, INFO, "Tried to expand an expanded node.");
return NSERROR_OK;
}
@@ -1679,7 +2104,6 @@ treeview_node_expand_internal(treeview *tree, treeview_node *node)
}
do {
- assert((child->flags & TV_NFLAGS_EXPANDED) == false);
if (child->text.width == 0) {
guit->layout->width(&plot_style_odd.text,
child->text.data,
@@ -1724,17 +2148,23 @@ treeview_node_expand_internal(treeview *tree, treeview_node *node)
/* Update the node */
node->flags |= TV_NFLAGS_EXPANDED;
- /* And parent's heights */
- do {
- node->height += additional_height;
- node = node->parent;
- } while (node->parent != NULL);
+ /* And node heights */
+ for (struct treeview_node *n = node;
+ (n != NULL) && (n->flags & TV_NFLAGS_EXPANDED);
+ n = n->parent) {
+ n->height += additional_height;
+ }
- node->height += additional_height;
+ if (tree->search.search &&
+ node->type == TREE_NODE_ENTRY &&
+ node->flags & TV_NFLAGS_MATCHED) {
+ tree->search.height += additional_height;
+ }
/* Inform front end of change in dimensions */
if (additional_height != 0) {
- treeview__cw_update_size(tree, -1, tree->root->height);
+ treeview__cw_update_size(tree, -1,
+ treeview__get_display_height(tree));
}
return NSERROR_OK;
@@ -1753,9 +2183,9 @@ nserror treeview_node_expand(treeview *tree, treeview_node *node)
r.x0 = 0;
r.y0 = treeview_node_y(tree, node);
r.x1 = REDRAW_MAX;
- r.y1 = tree->root->height;
+ r.y1 = treeview__get_display_height(tree);
- cw_invalidate_area(tree, &r);
+ treeview__cw_invalidate_area(tree, &r);
}
return res;
@@ -1766,6 +2196,7 @@ nserror treeview_node_expand(treeview *tree, treeview_node *node)
* context for treeview contraction callback
*/
struct treeview_contract_data {
+ treeview *tree;
bool only_entries;
};
@@ -1794,15 +2225,20 @@ static nserror treeview_node_contract_cb(treeview_node *n, void *ctx, bool *end)
return NSERROR_OK;
}
- n->flags ^= TV_NFLAGS_EXPANDED;
h_reduction = n->height - tree_g.line_height;
assert(h_reduction >= 0);
+ for (struct treeview_node *node = n;
+ (node != NULL) && (node->flags & TV_NFLAGS_EXPANDED);
+ node = node->parent) {
+ node->height -= h_reduction;
+ }
- do {
- n->height -= h_reduction;
- n = n->parent;
- } while (n != NULL);
+ if (data->tree->search.search) {
+ data->tree->search.height -= h_reduction;
+ }
+
+ n->flags ^= TV_NFLAGS_EXPANDED;
return NSERROR_OK;
}
@@ -1824,16 +2260,17 @@ treeview_node_contract_internal(treeview *tree, treeview_node *node)
if ((node->flags & TV_NFLAGS_EXPANDED) == false) {
/* What madness is this? */
- LOG("Tried to contract a contracted node.");
+ NSLOG(netsurf, INFO, "Tried to contract a contracted node.");
return NSERROR_OK;
}
+ data.tree = tree;
data.only_entries = false;
selected = node->flags & TV_NFLAGS_SELECTED;
/* Contract children. */
- treeview_walk_internal(node, false, treeview_node_contract_cb,
- NULL, &data);
+ treeview_walk_internal(tree, node, TREEVIEW_WALK_MODE_LOGICAL_EXPANDED,
+ treeview_node_contract_cb, NULL, &data);
/* Contract node */
treeview_node_contract_cb(node, &data, false);
@@ -1842,7 +2279,7 @@ treeview_node_contract_internal(treeview *tree, treeview_node *node)
node->flags |= TV_NFLAGS_SELECTED;
/* Inform front end of change in dimensions */
- treeview__cw_update_size(tree, -1, tree->root->height);
+ treeview__cw_update_size(tree, -1, treeview__get_display_height(tree));
return NSERROR_OK;
}
@@ -1864,7 +2301,7 @@ nserror treeview_node_contract(treeview *tree, treeview_node *node)
r.x1 = REDRAW_MAX;
r.y1 = tree->root->height;
- cw_invalidate_area(tree, &r);
+ treeview__cw_invalidate_area(tree, &r);
}
return res;
@@ -1887,6 +2324,7 @@ nserror treeview_contract(treeview *tree, bool all)
r.x1 = REDRAW_MAX;
r.y1 = tree->root->height;
+ data.tree = tree;
data.only_entries = !all;
for (n = tree->root->children; n != NULL; n = n->next_sib) {
@@ -1897,8 +2335,9 @@ nserror treeview_contract(treeview *tree, bool all)
selected = n->flags & TV_NFLAGS_SELECTED;
/* Contract children. */
- treeview_walk_internal(n, false,
- treeview_node_contract_cb, NULL, &data);
+ treeview_walk_internal(tree, n,
+ TREEVIEW_WALK_MODE_LOGICAL_EXPANDED,
+ treeview_node_contract_cb, NULL, &data);
/* Contract node */
treeview_node_contract_cb(n, &data, false);
@@ -1911,7 +2350,7 @@ nserror treeview_contract(treeview *tree, bool all)
treeview__cw_update_size(tree, -1, tree->root->height);
/* Redraw */
- cw_invalidate_area(tree, &r);
+ treeview__cw_invalidate_area(tree, &r);
return NSERROR_OK;
}
@@ -1972,11 +2411,9 @@ nserror treeview_expand(treeview *tree, bool only_folders)
data.tree = tree;
data.only_folders = only_folders;
- res = treeview_walk_internal(tree->root,
- true,
- NULL,
- treeview_expand_cb,
- &data);
+ res = treeview_walk_internal(tree, tree->root,
+ TREEVIEW_WALK_MODE_LOGICAL_COMPLETE,
+ NULL, treeview_expand_cb, &data);
if (res == NSERROR_OK) {
/* expansion succeeded, schedule redraw */
@@ -1985,44 +2422,46 @@ nserror treeview_expand(treeview *tree, bool only_folders)
r.x1 = REDRAW_MAX;
r.y1 = tree->root->height;
- cw_invalidate_area(tree, &r);
+ treeview__cw_invalidate_area(tree, &r);
}
return res;
}
-/* Exported interface, documented in treeview.h */
-void
-treeview_redraw(treeview *tree,
+/**
+ * Draw a treeview normally, in tree mode.
+ *
+ * \param[in] tree The treeview we're rendering.
+ * \param[in] x X coordinate we're rendering the treeview at.
+ * \param[in] y Y coordinate we're rendering the treeview at.
+ * \param[in,out] render_y Current vertical position in tree, updated on exit.
+ * \param[in] r Clip rectangle.
+ * \param[in] data Redraw data for rendering contents.
+ * \param[in] ctx Current render context.
+ */
+static void treeview_redraw_tree(
+ treeview *tree,
const int x,
const int y,
- struct rect *clip,
+ int *render_y_in_out,
+ struct rect *r,
+ struct content_redraw_data *data,
const struct redraw_context *ctx)
{
- struct redraw_context new_ctx = *ctx;
- treeview_node *node, *root, *next;
- struct treeview_node_entry *entry;
struct treeview_node_style *style = &plot_style_odd;
- struct content_redraw_data data;
- struct rect r;
- struct rect rect;
- uint32_t count = 0;
- int render_y = y;
- int inset;
- int x0;
- int baseline = (tree_g.line_height * 3 + 2) / 4;
enum treeview_resource_id res = TREE_RES_CONTENT;
- plot_style_t *bg_style;
- plot_font_style_t *text_style;
+ int baseline = (tree_g.line_height * 3 + 2) / 4;
plot_font_style_t *infotext_style;
- struct bitmap *furniture;
- int height;
+ treeview_node *root = tree->root;
+ treeview_node *node = tree->root;
+ int render_y = *render_y_in_out;
+ plot_font_style_t *text_style;
+ plot_style_t *bg_style;
int sel_min, sel_max;
- bool invert_selection;
-
- assert(tree != NULL);
- assert(tree->root != NULL);
- assert(tree->root->flags & TV_NFLAGS_EXPANDED);
+ uint32_t count = 0;
+ struct rect rect;
+ int inset;
+ int x0;
if (tree->drag.start.y > tree->drag.prev.y) {
sel_min = tree->drag.prev.y;
@@ -2032,30 +2471,14 @@ treeview_redraw(treeview *tree,
sel_max = tree->drag.prev.y;
}
- /* Start knockout rendering if it's available for this plotter */
- if (ctx->plot->option_knockout) {
- knockout_plot_start(ctx, &new_ctx);
- }
-
- /* Set up clip rectangle */
- r.x0 = clip->x0 + x;
- r.y0 = clip->y0 + y;
- r.x1 = clip->x1 + x;
- r.y1 = clip->y1 + y;
- new_ctx.plot->clip(&new_ctx, &r);
-
- /* Draw the tree */
- node = root = tree->root;
-
- /* Setup common content redraw data */
- data.width = tree_g.icon_size;
- data.height = tree_g.icon_size;
- data.scale = 1;
- data.repeat_x = false;
- data.repeat_y = false;
-
while (node != NULL) {
+ struct treeview_node_entry *entry;
+ struct bitmap *furniture;
+ bool invert_selection;
+ treeview_node *next;
+ int height;
int i;
+
next = (node->flags & TV_NFLAGS_EXPANDED) ?
node->children : NULL;
@@ -2088,7 +2511,7 @@ treeview_redraw(treeview *tree,
height = (node->type == TREE_NODE_ENTRY) ? node->height :
tree_g.line_height;
- if ((render_y + height) < r.y0) {
+ if ((render_y + height) < r->y0) {
/* This node's line is above clip region */
render_y += height;
continue;
@@ -2121,21 +2544,243 @@ treeview_redraw(treeview *tree,
}
/* Render background */
- rect.x0 = r.x0;
+ rect.x0 = r->x0;
rect.y0 = render_y;
- rect.x1 = r.x1;
+ rect.x1 = r->x1;
+ rect.y1 = render_y + height;
+ ctx->plot->rectangle(ctx, bg_style, &rect);
+
+ /* Render toggle */
+ ctx->plot->bitmap(ctx,
+ furniture,
+ inset,
+ render_y + tree_g.line_height / 4,
+ style->furn[TREE_FURN_EXPAND].size,
+ style->furn[TREE_FURN_EXPAND].size,
+ bg_style->fill_colour,
+ BITMAPF_NONE);
+
+ /* Render icon */
+ if (node->type == TREE_NODE_ENTRY) {
+ res = TREE_RES_CONTENT;
+ } else if (node->flags & TV_NFLAGS_SPECIAL) {
+ res = TREE_RES_FOLDER_SPECIAL;
+ } else {
+ res = TREE_RES_FOLDER;
+ }
+
+ if (treeview_res[res].ready) {
+ /* Icon resource is available */
+ data->x = inset + tree_g.step_width;
+ data->y = render_y + ((tree_g.line_height -
+ treeview_res[res].height + 1) / 2);
+ data->background_colour = bg_style->fill_colour;
+
+ content_redraw(treeview_res[res].c, data, r, ctx);
+ }
+
+ /* Render text */
+ x0 = inset + tree_g.step_width + tree_g.icon_step;
+ ctx->plot->text(ctx,
+ text_style,
+ x0, render_y + baseline,
+ node->text.data,
+ node->text.len);
+
+ /* Rendered the node */
+ render_y += tree_g.line_height;
+ if (render_y > r->y1) {
+ /* Passed the bottom of what's in the clip region.
+ * Done. */
+ break;
+ }
+
+
+ if (node->type != TREE_NODE_ENTRY ||
+ !(node->flags & TV_NFLAGS_EXPANDED))
+ /* Done everything for this node */
+ continue;
+
+ /* Render expanded entry fields */
+ entry = (struct treeview_node_entry *)node;
+ for (i = 0; i < tree->n_fields - 1; i++) {
+ struct treeview_field *ef = &(tree->fields[i + 1]);
+
+ if (ef->flags & TREE_FLAG_SHOW_NAME) {
+ int max_width = tree->field_width;
+
+ ctx->plot->text(ctx,
+ infotext_style,
+ x0 + max_width - ef->value.width - tree_g.step_width,
+ render_y + baseline,
+ ef->value.data,
+ ef->value.len);
+
+ ctx->plot->text(ctx,
+ infotext_style,
+ x0 + max_width,
+ render_y + baseline,
+ entry->fields[i].value.data,
+ entry->fields[i].value.len);
+ } else {
+ ctx->plot->text(ctx,
+ infotext_style,
+ x0, render_y + baseline,
+ entry->fields[i].value.data,
+ entry->fields[i].value.len);
+ }
+
+ /* Rendered the expanded entry field */
+ render_y += tree_g.line_height;
+ }
+
+ /* Finished rendering expanded entry */
+
+ if (render_y > r->y1) {
+ /* Passed the bottom of what's in the clip region.
+ * Done. */
+ break;
+ }
+ }
+
+ *render_y_in_out = render_y;
+}
+
+
+/**
+ * Draw a treeview normally, in tree mode.
+ *
+ * \param[in] tree The treeview we're rendering.
+ * \param[in] x X coordinate we're rendering the treeview at.
+ * \param[in] y Y coordinate we're rendering the treeview at.
+ * \param[in,out] render_y Current vertical position in tree, updated on exit.
+ * \param[in] r Clip rectangle.
+ * \param[in] data Redraw data for rendering contents.
+ * \param[in] ctx Current render context.
+ */
+static void treeview_redraw_search(
+ treeview *tree,
+ const int x,
+ const int y,
+ int *render_y_in_out,
+ struct rect *r,
+ struct content_redraw_data *data,
+ const struct redraw_context *ctx)
+{
+ struct treeview_node_style *style = &plot_style_odd;
+ enum treeview_resource_id res = TREE_RES_CONTENT;
+ int baseline = (tree_g.line_height * 3 + 2) / 4;
+ plot_font_style_t *infotext_style;
+ treeview_node *root = tree->root;
+ treeview_node *node = tree->root;
+ int render_y = *render_y_in_out;
+ plot_font_style_t *text_style;
+ plot_style_t *bg_style;
+ int sel_min, sel_max;
+ uint32_t count = 0;
+ struct rect rect;
+ int inset;
+ int x0;
+
+ if (tree->drag.start.y > tree->drag.prev.y) {
+ sel_min = tree->drag.prev.y;
+ sel_max = tree->drag.start.y;
+ } else {
+ sel_min = tree->drag.start.y;
+ sel_max = tree->drag.prev.y;
+ }
+
+ while (node != NULL) {
+ struct treeview_node_entry *entry;
+ struct bitmap *furniture;
+ bool invert_selection;
+ treeview_node *next;
+ int height;
+ int i;
+
+ next = node->children;
+
+ if (next != NULL) {
+ /* down to children */
+ node = next;
+ } else {
+ /* No children. As long as we're not at the root,
+ * go to next sibling if present, or nearest ancestor
+ * with a next sibling. */
+
+ while (node != root &&
+ node->next_sib == NULL) {
+ node = node->parent;
+ }
+
+ if (node == root)
+ break;
+
+ node = node->next_sib;
+ }
+
+ assert(node != NULL);
+ assert(node != root);
+ assert(node->type == TREE_NODE_FOLDER ||
+ node->type == TREE_NODE_ENTRY);
+
+ if (node->type == TREE_NODE_FOLDER ||
+ !(node->flags & TV_NFLAGS_MATCHED)) {
+ continue;
+ }
+
+ count++;
+ inset = x + tree_g.window_padding;
+ height = node->height;
+
+ if ((render_y + height) < r->y0) {
+ /* This node's line is above clip region */
+ render_y += height;
+ continue;
+ }
+
+ style = (count & 0x1) ? &plot_style_odd : &plot_style_even;
+ if (tree->drag.type == TV_DRAG_SELECTION &&
+ (render_y + height >= sel_min &&
+ render_y < sel_max)) {
+ invert_selection = true;
+ } else {
+ invert_selection = false;
+ }
+ if ((node->flags & TV_NFLAGS_SELECTED && !invert_selection) ||
+ (!(node->flags & TV_NFLAGS_SELECTED) &&
+ invert_selection)) {
+ bg_style = &style->sbg;
+ text_style = &style->stext;
+ infotext_style = &style->sitext;
+ furniture = (node->flags & TV_NFLAGS_EXPANDED) ?
+ style->furn[TREE_FURN_CONTRACT].sel :
+ style->furn[TREE_FURN_EXPAND].sel;
+ } else {
+ bg_style = &style->bg;
+ text_style = &style->text;
+ infotext_style = &style->itext;
+ furniture = (node->flags & TV_NFLAGS_EXPANDED) ?
+ style->furn[TREE_FURN_CONTRACT].bmp :
+ style->furn[TREE_FURN_EXPAND].bmp;
+ }
+
+ /* Render background */
+ rect.x0 = r->x0;
+ rect.y0 = render_y;
+ rect.x1 = r->x1;
rect.y1 = render_y + height;
- new_ctx.plot->rectangle(&new_ctx, bg_style, &rect);
+ ctx->plot->rectangle(ctx, bg_style, &rect);
/* Render toggle */
- new_ctx.plot->bitmap(&new_ctx,
- furniture,
- inset,
- render_y + tree_g.line_height / 4,
- style->furn[TREE_FURN_EXPAND].size,
- style->furn[TREE_FURN_EXPAND].size,
- bg_style->fill_colour,
- BITMAPF_NONE);
+ ctx->plot->bitmap(ctx,
+ furniture,
+ inset,
+ render_y + tree_g.line_height / 4,
+ style->furn[TREE_FURN_EXPAND].size,
+ style->furn[TREE_FURN_EXPAND].size,
+ bg_style->fill_colour,
+ BITMAPF_NONE);
/* Render icon */
if (node->type == TREE_NODE_ENTRY) {
@@ -2148,26 +2793,25 @@ treeview_redraw(treeview *tree,
if (treeview_res[res].ready) {
/* Icon resource is available */
- data.x = inset + tree_g.step_width;
- data.y = render_y + ((tree_g.line_height -
+ data->x = inset + tree_g.step_width;
+ data->y = render_y + ((tree_g.line_height -
treeview_res[res].height + 1) / 2);
- data.background_colour = bg_style->fill_colour;
+ data->background_colour = bg_style->fill_colour;
- content_redraw(treeview_res[res].c,
- &data, &r, &new_ctx);
+ content_redraw(treeview_res[res].c, data, r, ctx);
}
/* Render text */
x0 = inset + tree_g.step_width + tree_g.icon_step;
- new_ctx.plot->text(&new_ctx,
- text_style,
- x0, render_y + baseline,
- node->text.data,
- node->text.len);
+ ctx->plot->text(ctx,
+ text_style,
+ x0, render_y + baseline,
+ node->text.data,
+ node->text.len);
/* Rendered the node */
render_y += tree_g.line_height;
- if (render_y > r.y1) {
+ if (render_y > r->y1) {
/* Passed the bottom of what's in the clip region.
* Done. */
break;
@@ -2187,25 +2831,25 @@ treeview_redraw(treeview *tree,
if (ef->flags & TREE_FLAG_SHOW_NAME) {
int max_width = tree->field_width;
- new_ctx.plot->text(&new_ctx,
- infotext_style,
- x0 + max_width - ef->value.width - tree_g.step_width,
- render_y + baseline,
- ef->value.data,
- ef->value.len);
-
- new_ctx.plot->text(&new_ctx,
- infotext_style,
- x0 + max_width,
- render_y + baseline,
- entry->fields[i].value.data,
- entry->fields[i].value.len);
+ ctx->plot->text(ctx,
+ infotext_style,
+ x0 + max_width - ef->value.width - tree_g.step_width,
+ render_y + baseline,
+ ef->value.data,
+ ef->value.len);
+
+ ctx->plot->text(ctx,
+ infotext_style,
+ x0 + max_width,
+ render_y + baseline,
+ entry->fields[i].value.data,
+ entry->fields[i].value.len);
} else {
- new_ctx.plot->text(&new_ctx,
- infotext_style,
- x0, render_y + baseline,
- entry->fields[i].value.data,
- entry->fields[i].value.len);
+ ctx->plot->text(ctx,
+ infotext_style,
+ x0, render_y + baseline,
+ entry->fields[i].value.data,
+ entry->fields[i].value.len);
}
/* Rendered the expanded entry field */
@@ -2214,13 +2858,97 @@ treeview_redraw(treeview *tree,
/* Finished rendering expanded entry */
- if (render_y > r.y1) {
+ if (render_y > r->y1) {
/* Passed the bottom of what's in the clip region.
* Done. */
break;
}
}
+ *render_y_in_out = render_y;
+}
+
+
+/* Exported interface, documented in treeview.h */
+void
+treeview_redraw(treeview *tree,
+ const int x,
+ const int y,
+ struct rect *clip,
+ const struct redraw_context *ctx)
+{
+ struct redraw_context new_ctx = *ctx;
+ struct content_redraw_data data;
+ struct rect r;
+ struct rect rect;
+ int render_y = y;
+
+ assert(tree != NULL);
+ assert(tree->root != NULL);
+ assert(tree->root->flags & TV_NFLAGS_EXPANDED);
+
+ /* Start knockout rendering if it's available for this plotter */
+ if (ctx->plot->option_knockout) {
+ knockout_plot_start(ctx, &new_ctx);
+ }
+
+ /* Set up clip rectangle */
+ r.x0 = clip->x0 + x;
+ r.y0 = clip->y0 + y;
+ r.x1 = clip->x1 + x;
+ r.y1 = clip->y1 + y;
+ new_ctx.plot->clip(&new_ctx, &r);
+
+ /* Setup common content redraw data */
+ data.width = tree_g.icon_size;
+ data.height = tree_g.icon_size;
+ data.scale = 1;
+ data.repeat_x = false;
+ data.repeat_y = false;
+
+ if (tree->flags & TREEVIEW_SEARCHABLE) {
+ if (render_y < r.y1) {
+ enum treeview_resource_id icon = TREE_RES_SEARCH;
+
+ /* Fill the blank area at the bottom */
+ rect.x0 = r.x0;
+ rect.y0 = render_y;
+ rect.x1 = r.x1;
+ rect.y1 = render_y + tree_g.line_height;
+ new_ctx.plot->rectangle(&new_ctx, &plot_style_even.bg,
+ &rect);
+
+ if (treeview_res[icon].ready) {
+ /* Icon resource is available */
+ data.x = tree_g.window_padding;
+ data.y = render_y + ((tree_g.line_height -
+ treeview_res[icon].height + 1) /
+ 2);
+ data.background_colour = plot_style_even.bg.
+ fill_colour;
+
+ content_redraw(treeview_res[icon].c,
+ &data, &r, &new_ctx);
+ }
+
+ textarea_redraw(tree->search.textarea,
+ x + tree_g.window_padding +
+ tree_g.icon_step, y,
+ plot_style_even.bg.fill_colour, 1.0,
+ &r, &new_ctx);
+ }
+ render_y += tree_g.line_height;
+ }
+
+ /* Render the treeview data */
+ if (tree->search.search == true) {
+ treeview_redraw_search(tree, x, y,
+ &render_y, &r, &data, &new_ctx);
+ } else {
+ treeview_redraw_tree(tree, x, y,
+ &render_y, &r, &data, &new_ctx);
+ }
+
if (render_y < r.y1) {
/* Fill the blank area at the bottom */
rect.x0 = r.x0;
@@ -2474,8 +3202,9 @@ bool treeview_has_selection(treeview *tree)
sw.purpose = TREEVIEW_WALK_HAS_SELECTION;
sw.data.has_selection = false;
- treeview_walk_internal(tree->root, false, NULL,
- treeview_node_selection_walk_cb, &sw);
+ treeview_walk_internal(tree, tree->root,
+ TREEVIEW_WALK_MODE_DISPLAY, NULL,
+ treeview_node_selection_walk_cb, &sw);
return sw.data.has_selection;
}
@@ -2494,8 +3223,9 @@ static treeview_node * treeview_get_first_selected(treeview *tree)
sw.purpose = TREEVIEW_WALK_GET_FIRST_SELECTED;
sw.data.first.n = NULL;
- treeview_walk_internal(tree->root, false, NULL,
- treeview_node_selection_walk_cb, &sw);
+ treeview_walk_internal(tree, tree->root,
+ TREEVIEW_WALK_MODE_DISPLAY, NULL,
+ treeview_node_selection_walk_cb, &sw);
return sw.data.first.n;
}
@@ -2540,10 +3270,12 @@ static bool treeview_clear_selection(treeview *tree, struct rect *rect)
sw.purpose = TREEVIEW_WALK_CLEAR_SELECTION;
sw.data.redraw.required = false;
sw.data.redraw.rect = rect;
- sw.current_y = 0;
+ sw.current_y = (tree->flags & TREEVIEW_SEARCHABLE) ?
+ tree_g.line_height : 0;
- treeview_walk_internal(tree->root, false, NULL,
- treeview_node_selection_walk_cb, &sw);
+ treeview_walk_internal(tree, tree->root,
+ TREEVIEW_WALK_MODE_DISPLAY, NULL,
+ treeview_node_selection_walk_cb, &sw);
return sw.data.redraw.required;
}
@@ -2568,10 +3300,12 @@ static bool treeview_select_all(treeview *tree, struct rect *rect)
sw.purpose = TREEVIEW_WALK_SELECT_ALL;
sw.data.redraw.required = false;
sw.data.redraw.rect = rect;
- sw.current_y = 0;
+ sw.current_y = (tree->flags & TREEVIEW_SEARCHABLE) ?
+ tree_g.line_height : 0;
- treeview_walk_internal(tree->root, false, NULL,
- treeview_node_selection_walk_cb, &sw);
+ treeview_walk_internal(tree, tree->root,
+ TREEVIEW_WALK_MODE_DISPLAY, NULL,
+ treeview_node_selection_walk_cb, &sw);
return sw.data.redraw.required;
}
@@ -2587,7 +3321,8 @@ static void treeview_commit_selection_drag(treeview *tree)
struct treeview_selection_walk_data sw;
sw.purpose = TREEVIEW_WALK_COMMIT_SELECT_DRAG;
- sw.current_y = 0;
+ sw.current_y = (tree->flags & TREEVIEW_SEARCHABLE) ?
+ tree_g.line_height : 0;
if (tree->drag.start.y > tree->drag.prev.y) {
sw.data.drag.sel_min = tree->drag.prev.y;
@@ -2597,8 +3332,9 @@ static void treeview_commit_selection_drag(treeview *tree)
sw.data.drag.sel_max = tree->drag.prev.y;
}
- treeview_walk_internal(tree->root, false, NULL,
- treeview_node_selection_walk_cb, &sw);
+ treeview_walk_internal(tree, tree->root,
+ TREEVIEW_WALK_MODE_DISPLAY, NULL,
+ treeview_node_selection_walk_cb, &sw);
}
@@ -2615,8 +3351,9 @@ static void treeview_move_yank_selection(treeview *tree)
sw.data.yank.prev = NULL;
sw.tree = tree;
- treeview_walk_internal(tree->root, false, NULL,
- treeview_node_selection_walk_cb, &sw);
+ treeview_walk_internal(tree, tree->root,
+ TREEVIEW_WALK_MODE_DISPLAY, NULL,
+ treeview_node_selection_walk_cb, &sw);
}
@@ -2635,8 +3372,9 @@ static void treeview_copy_selection(treeview *tree)
sw.data.copy.len = 0;
sw.tree = tree;
- err = treeview_walk_internal(tree->root, false, NULL,
- treeview_node_selection_walk_cb, &sw);
+ err = treeview_walk_internal(tree, tree->root,
+ TREEVIEW_WALK_MODE_DISPLAY, NULL,
+ treeview_node_selection_walk_cb, &sw);
if (err != NSERROR_OK) {
return;
}
@@ -2674,8 +3412,9 @@ static bool treeview_delete_selection(treeview *tree, struct rect *rect)
sw.current_y = 0;
sw.tree = tree;
- treeview_walk_internal(tree->root, false, NULL,
- treeview_node_selection_walk_cb, &sw);
+ treeview_walk_internal(tree, tree->root,
+ TREEVIEW_WALK_MODE_DISPLAY, NULL,
+ treeview_node_selection_walk_cb, &sw);
return sw.data.redraw.required;
}
@@ -2706,8 +3445,9 @@ static bool treeview_propagate_selection(treeview *tree, struct rect *rect)
sw.current_y = 0;
sw.tree = tree;
- treeview_walk_internal(tree->root, false, NULL,
- treeview_node_selection_walk_cb, &sw);
+ treeview_walk_internal(tree, tree->root,
+ TREEVIEW_WALK_MODE_DISPLAY, NULL,
+ treeview_node_selection_walk_cb, &sw);
return sw.data.redraw.required;
}
@@ -2771,7 +3511,7 @@ static nserror treeview_move_selection(treeview *tree, struct rect *rect)
break;
default:
- LOG("Bad drop target for move.");
+ NSLOG(netsurf, INFO, "Bad drop target for move.");
return NSERROR_BAD_PARAMETER;
}
@@ -2797,7 +3537,7 @@ static nserror treeview_move_selection(treeview *tree, struct rect *rect)
node->flags &= ~TV_NFLAGS_SELECTED;
}
- treeview_insert_node(node, relation, relationship);
+ treeview_insert_node(tree, node, relation, relationship);
relation = node;
relationship = TREE_REL_NEXT_SIBLING;
@@ -2896,9 +3636,10 @@ static nserror treeview_launch_selection(treeview *tree)
lw.selected_depth = 0;
lw.tree = tree;
- return treeview_walk_internal(tree->root, true,
- treeview_node_launch_walk_bwd_cb,
- treeview_node_launch_walk_fwd_cb, &lw);
+ return treeview_walk_internal(tree, tree->root,
+ TREEVIEW_WALK_MODE_LOGICAL_COMPLETE,
+ treeview_node_launch_walk_bwd_cb,
+ treeview_node_launch_walk_fwd_cb, &lw);
}
@@ -3033,18 +3774,25 @@ treeview_keyboard_navigation(treeview *tree, uint32_t key, struct rect *rect)
/* Fill out the nav. state struct, by examining the current selection
* state */
- treeview_walk_internal(tree->root, false, NULL,
- treeview_node_nav_cb, &ns);
- if (ns.next == NULL)
- ns.next = tree->root->children;
- if (ns.prev == NULL)
- ns.prev = ns.last;
+ treeview_walk_internal(tree, tree->root,
+ TREEVIEW_WALK_MODE_DISPLAY, NULL,
+ treeview_node_nav_cb, &ns);
+
+ if (tree->search.search == false) {
+ if (ns.next == NULL)
+ ns.next = tree->root->children;
+ if (ns.prev == NULL)
+ ns.prev = ns.last;
+ }
/* Clear any existing selection */
redraw = treeview_clear_selection(tree, rect);
switch (key) {
case NS_KEY_LEFT:
+ if (tree->search.search == true) {
+ break;
+ }
if (ns.curr != NULL &&
ns.curr->parent != NULL &&
ns.curr->parent->type != TREE_NODE_ROOT) {
@@ -3123,7 +3871,7 @@ bool treeview_keypress(treeview *tree, uint32_t key)
assert(tree != NULL);
- /* Pass to textarea, if editing in progress */
+ /* Pass to any textarea, if editing in progress */
if (tree->edit.textarea != NULL) {
switch (key) {
case NS_KEY_ESCAPE:
@@ -3136,6 +3884,17 @@ bool treeview_keypress(treeview *tree, uint32_t key)
default:
return textarea_keypress(tree->edit.textarea, key);
}
+ } else if (tree->search.active == true) {
+ switch (key) {
+ case NS_KEY_ESCAPE:
+ treeview__search_cancel(tree, false);
+ return true;
+ case NS_KEY_NL:
+ case NS_KEY_CR:
+ return true;
+ default:
+ return textarea_keypress(tree->search.textarea, key);
+ }
}
/* Keypress to be handled by treeview */
@@ -3182,7 +3941,7 @@ bool treeview_keypress(treeview *tree, uint32_t key)
}
if (redraw) {
- cw_invalidate_area(tree, &r);
+ treeview__cw_invalidate_area(tree, &r);
}
return true;
@@ -3358,7 +4117,7 @@ static void treeview_textarea_callback(void *data, struct textarea_msg *msg)
r->y1 += tree->edit.y;
/* Redraw the textarea */
- cw_invalidate_area(tree, r);
+ treeview__cw_invalidate_area(tree, r);
break;
default:
@@ -3392,8 +4151,6 @@ treeview_edit_node_at_point(treeview *tree,
int field_y = node_y;
int field_x;
int width, height;
- textarea_setup ta_setup;
- textarea_flags ta_flags;
bool success;
/* If the main field is editable, make field_data point to it */
@@ -3435,31 +4192,15 @@ treeview_edit_node_at_point(treeview *tree,
/* Get window width/height */
treeview__cw_get_window_dimensions(tree, &width, &height);
- /* Anow textarea width/height */
+ /* Calculate textarea width/height */
field_x = n->inset + tree_g.step_width + tree_g.icon_step - 3;
width -= field_x;
height = tree_g.line_height;
- /* Configure the textarea */
- ta_flags = TEXTAREA_INTERNAL_CARET;
-
- ta_setup.width = width;
- ta_setup.height = height;
- ta_setup.pad_top = 0;
- ta_setup.pad_right = 2;
- ta_setup.pad_bottom = 0;
- ta_setup.pad_left = 2;
- ta_setup.border_width = 1;
- ta_setup.border_col = 0x000000;
- ta_setup.selected_text = 0xffffff;
- ta_setup.selected_bg = 0x000000;
- ta_setup.text = plot_style_odd.text;
- ta_setup.text.foreground = 0x000000;
- ta_setup.text.background = 0xffffff;
-
/* Create text area */
- tree->edit.textarea = textarea_create(ta_flags, &ta_setup,
- treeview_textarea_callback, tree);
+ tree->edit.textarea = treeview__create_textarea(tree, width, height,
+ 0x000000, 0xffffff, 0x000000, plot_style_odd.text,
+ treeview_textarea_callback);
if (tree->edit.textarea == NULL) {
return false;
}
@@ -3536,7 +4277,7 @@ void treeview_edit_selection(treeview *tree)
rect.y0 = y;
rect.x1 = REDRAW_MAX;
rect.y1 = y + tree_g.line_height;
- cw_invalidate_area(tree, &rect);
+ treeview__cw_invalidate_area(tree, &rect);
}
@@ -3593,14 +4334,18 @@ treeview_node_mouse_action_cb(treeview_node *node,
/* Find where the mouse is */
if (ma->y <= ma->current_y + tree_g.line_height) {
- if (ma->x >= node->inset - 1 &&
- ma->x < node->inset + tree_g.step_width) {
+ int inset = node->inset;
+ if (ma->tree->search.search == true) {
+ inset = tree_g.window_padding;
+ }
+ if (ma->x >= inset - 1 &&
+ ma->x < inset + tree_g.step_width) {
/* Over expansion toggle */
part = TV_NODE_PART_TOGGLE;
- } else if (ma->x >= node->inset + tree_g.step_width &&
- ma->x < node->inset + tree_g.step_width +
- tree_g.icon_step + node->text.width) {
+ } else if (ma->x >= inset + tree_g.step_width &&
+ ma->x < inset + tree_g.step_width +
+ tree_g.icon_step + node->text.width) {
/* On node */
part = TV_NODE_PART_ON_NODE;
}
@@ -3674,7 +4419,8 @@ treeview_node_mouse_action_cb(treeview_node *node,
treeview__cw_drag_status(ma->tree,
CORE_WINDOW_DRAG_SELECTION);
- } else if (!(ma->tree->flags & TREEVIEW_NO_MOVES) &&
+ } else if (ma->tree->search.search == false &&
+ !(ma->tree->flags & TREEVIEW_NO_MOVES) &&
ma->mouse & BROWSER_MOUSE_DRAG_1 &&
(ma->tree->drag.selected == true ||
ma->tree->drag.part == TV_NODE_PART_ON_NODE)) {
@@ -3714,7 +4460,7 @@ treeview_node_mouse_action_cb(treeview_node *node,
ma->tree->drag.prev.node_y = ma->current_y;
ma->tree->drag.prev.node_h = height;
}
- break;
+ break;
case TV_DRAG_MOVE:
redraw |= treeview_set_move_indicator(ma->tree, redraw,
@@ -3816,7 +4562,7 @@ treeview_node_mouse_action_cb(treeview_node *node,
}
if (redraw) {
- cw_invalidate_area(ma->tree, &r);
+ treeview__cw_invalidate_area(ma->tree, &r);
}
*end = true; /* Reached line with click; stop walking tree */
@@ -3830,15 +4576,45 @@ treeview_mouse_action(treeview *tree, browser_mouse_state mouse, int x, int y)
{
struct rect r;
bool redraw = false;
+ int search_height = (tree->flags & TREEVIEW_SEARCHABLE) ?
+ tree_g.line_height : 0;
assert(tree != NULL);
assert(tree->root != NULL);
+ /* Not interested in whether mouse leaves window. */
+ if (mouse == BROWSER_MOUSE_LEAVE) {
+ return;
+ }
+
/* Handle mouse drag captured by textarea */
if (tree->drag.type == TV_DRAG_TEXTAREA) {
textarea_mouse_action(tree->edit.textarea, mouse,
x - tree->edit.x, y - tree->edit.y);
return;
+ } else if (tree->drag.type == TV_DRAG_SEARCH ||
+ (y < search_height &&
+ tree->drag.type == TV_DRAG_NONE)) {
+ if (tree->search.active == false) {
+ tree->search.active = true;
+ if (treeview_clear_selection(tree, &r)) {
+ treeview__cw_invalidate_area(tree, &r);
+ }
+ }
+ textarea_mouse_action(tree->search.textarea, mouse,
+ x - tree_g.window_padding - tree_g.icon_size,
+ y);
+ return;
+ } else if (mouse & (BROWSER_MOUSE_PRESS_1 | BROWSER_MOUSE_PRESS_2) &&
+ tree->search.active == true) {
+
+ tree->search.active = false;
+ textarea_set_caret(tree->search.textarea, -1);
+ r.x0 = 0;
+ r.y0 = 0;
+ r.x1 = REDRAW_MAX;
+ r.y1 = tree_g.line_height;
+ treeview__cw_invalidate_area(tree, &r);
}
/* Handle textarea related mouse action */
@@ -3878,7 +4654,7 @@ treeview_mouse_action(treeview *tree, browser_mouse_state mouse, int x, int y)
tree->move.target_pos = TV_TARGET_NONE;
treeview__cw_drag_status(tree, CORE_WINDOW_DRAG_NONE);
- cw_invalidate_area(tree, &r);
+ treeview__cw_invalidate_area(tree, &r);
return;
default:
/* No drag to end */
@@ -3886,7 +4662,7 @@ treeview_mouse_action(treeview *tree, browser_mouse_state mouse, int x, int y)
}
}
- if (y > tree->root->height) {
+ if (y > treeview__get_display_height(tree) + search_height) {
/* Below tree */
r.x0 = 0;
@@ -3953,7 +4729,7 @@ treeview_mouse_action(treeview *tree, browser_mouse_state mouse, int x, int y)
}
if (redraw) {
- cw_invalidate_area(tree, &r);
+ treeview__cw_invalidate_area(tree, &r);
}
} else {
@@ -3964,10 +4740,11 @@ treeview_mouse_action(treeview *tree, browser_mouse_state mouse, int x, int y)
ma.mouse = mouse;
ma.x = x;
ma.y = y;
- ma.current_y = 0;
+ ma.current_y = search_height;
- treeview_walk_internal(tree->root, false, NULL,
- treeview_node_mouse_action_cb, &ma);
+ treeview_walk_internal(tree, tree->root,
+ TREEVIEW_WALK_MODE_DISPLAY, NULL,
+ treeview_node_mouse_action_cb, &ma);
}
}
@@ -3975,12 +4752,16 @@ treeview_mouse_action(treeview *tree, browser_mouse_state mouse, int x, int y)
/* Exported interface, documented in treeview.h */
int treeview_get_height(treeview *tree)
{
+ int search_height = (tree->flags & TREEVIEW_SEARCHABLE) ?
+ tree_g.line_height : 0;
+ int height = treeview__get_display_height(tree);
+
assert(tree != NULL);
assert(tree->root != NULL);
- treeview__cw_update_size(tree, -1, tree->root->height);
+ treeview__cw_update_size(tree, -1, height);
- return tree->root->height;
+ return height + search_height;
}
@@ -4403,7 +5184,7 @@ nserror treeview_init(void)
return NSERROR_OK;
}
- LOG("Initialising treeview module");
+ NSLOG(netsurf, INFO, "Initialising treeview module");
font_pt_size = nsoption_int(treeview_font_size);
if (font_pt_size <= 0) {
@@ -4434,7 +5215,7 @@ nserror treeview_init(void)
tree_g.initialised++;
- LOG("Initialised treeview module");
+ NSLOG(netsurf, INFO, "Initialised treeview module");
return NSERROR_OK;
}
@@ -4450,11 +5231,12 @@ nserror treeview_fini(void)
return NSERROR_OK;
} else if (tree_g.initialised == 0) {
- LOG("Warning: tried to finalise uninitialised treeview module");
+ NSLOG(netsurf, INFO,
+ "Warning: tried to finalise uninitialised treeview module");
return NSERROR_OK;
}
- LOG("Finalising treeview module");
+ NSLOG(netsurf, INFO, "Finalising treeview module");
for (i = 0; i < TREE_RES_LAST; i++) {
hlcache_handle_release(treeview_res[i].c);
@@ -4471,7 +5253,7 @@ nserror treeview_fini(void)
tree_g.initialised--;
- LOG("Finalised treeview module");
+ NSLOG(netsurf, INFO, "Finalised treeview module");
return NSERROR_OK;
}
diff --git a/desktop/treeview.h b/desktop/treeview.h
index 45469b77f..a8cf29ac5 100644
--- a/desktop/treeview.h
+++ b/desktop/treeview.h
@@ -76,7 +76,8 @@ typedef enum {
TREEVIEW_NO_MOVES = (1 << 0), /**< No node drags */
TREEVIEW_NO_DELETES = (1 << 1), /**< No node deletes */
TREEVIEW_READ_ONLY = TREEVIEW_NO_MOVES | TREEVIEW_NO_DELETES,
- TREEVIEW_DEL_EMPTY_DIRS = (1 << 2) /**< Delete dirs on empty */
+ TREEVIEW_DEL_EMPTY_DIRS = (1 << 2), /**< Delete dirs on empty */
+ TREEVIEW_SEARCHABLE = (1 << 3), /**< Treeview has search bar */
} treeview_flags;
/**
@@ -113,11 +114,12 @@ struct treeview_node_msg {
* treeview field flags
*/
enum treeview_field_flags {
- TREE_FLAG_NONE = 0, /**< No flags set */
- TREE_FLAG_ALLOW_EDIT = (1 << 0), /**< Whether allow edit field */
- TREE_FLAG_DEFAULT = (1 << 1), /**< Whether field is default */
- TREE_FLAG_SHOW_NAME = (1 << 2), /**< Whether field name shown */
- TREE_FLAG_COPY_TEXT = (1 << 3) /**< Whether to copy to clipb */
+ TREE_FLAG_NONE = 0, /**< No flags set */
+ TREE_FLAG_ALLOW_EDIT = (1 << 0), /**< Whether allow edit field */
+ TREE_FLAG_DEFAULT = (1 << 1), /**< Whether field is default */
+ TREE_FLAG_SHOW_NAME = (1 << 2), /**< Whether field name shown */
+ TREE_FLAG_COPY_TEXT = (1 << 3), /**< Whether to copy to clipb */
+ TREE_FLAG_SEARCHABLE = (1 << 4), /**< Whether field is searchable */
};
diff --git a/desktop/version.c b/desktop/version.c
index 6126c5b99..bbe759f2e 100644
--- a/desktop/version.c
+++ b/desktop/version.c
@@ -20,11 +20,11 @@
#include "desktop/version.h"
-const char * const netsurf_version = "3.7 (Dev"
+const char * const netsurf_version = "3.8 (Dev"
#if defined(CI_BUILD)
" CI #" CI_BUILD
#endif
")"
;
const int netsurf_version_major = 3;
-const int netsurf_version_minor = 7;
+const int netsurf_version_minor = 8;
diff --git a/docs/env.sh b/docs/env.sh
index 518123e2f..bb2cbabea 100644
--- a/docs/env.sh
+++ b/docs/env.sh
@@ -1,57 +1,220 @@
#!/bin/sh
#
-# NetSurf Library, tool and browser support script
+# NetSurf Library, tool and browser development support script
#
-# Usage: source env.sh
-# TARGET_ABI / HOST sets the target for library builds
-# TARGET_WORKSPACE is the workspace directory to keep the sandboxes
+# Copyright 2013-2017 Vincent Sanders <vince@netsurf-browser.org>
+# Released under the MIT Licence
#
# This script allows NetSurf and its libraries to be built without
# requiring installation into a system.
#
-# Copyright 2013 Vincent Sanders <vince@netsurf-browser.org>
-# Released under the MIT Licence
+# Usage: source env.sh
+#
+# Controlling variables
+# HOST sets the target architecture for library builds
+# BUILD sets the building machines architecture
+# TARGET_WORKSPACE is the workspace directory to keep the sandboxes
+#
+# The use of HOST and BUILD here is directly comprable to the GCC
+# usage as described at:
+# http://gcc.gnu.org/onlinedocs/gccint/Configure-Terms.html
+#
+
+###############################################################################
+# OS Package installation
+###############################################################################
+
+# deb packages for dpkg based systems
+NS_DEV_DEB="build-essential pkg-config git gperf libcurl3-dev libssl-dev libpng-dev libjpeg-dev"
+NS_TOOL_DEB="flex bison libhtml-parser-perl"
+if [ "x${NETSURF_GTK_MAJOR}" = "x3" ]; then
+ NS_GTK_DEB="libgtk-3-dev librsvg2-dev"
+else
+ NS_GTK_DEB="libgtk2.0-dev librsvg2-dev"
+fi
+
+# apt get commandline to install necessary dev packages
+ns-apt-get-install()
+{
+ sudo apt-get install $(echo ${NS_DEV_DEB} ${NS_TOOL_DEB} ${NS_GTK_DEB})
+}
-# parameters
+
+# packages for yum installer RPM based systems (tested on fedora 20)
+NS_DEV_YUM_RPM="git gcc pkgconfig libexpat-devel openssl-devel libcurl-devel perl-Digest-MD5-File libjpeg-devel libpng-devel"
+NS_TOOL_YUM_RPM="flex bison"
+if [ "x${NETSURF_GTK_MAJOR}" = "x3" ]; then
+ NS_GTK_YUM_RPM="gtk3-devel librsvg2-devel"
+else
+ NS_GTK_YUM_RPM="gtk2-devel librsvg2-devel"
+fi
+
+# yum commandline to install necessary dev packages
+ns-yum-install()
+{
+ sudo yum -y install $(echo ${NS_DEV_YUM_RPM} ${NS_TOOL_YUM_RPM} ${NS_GTK_YUM_RPM})
+}
+
+
+# packages for dnf installer RPM based systems (tested on fedora 25)
+NS_DEV_DNF_RPM="java-1.8.0-openjdk-headless gcc clang pkgconfig libcurl-devel libjpeg-devel expat-devel libpng-devel openssl-devel gperf perl-HTML-Parser"
+NS_TOOL_DNF_RPM="git flex bison ccache screen"
+if [ "x${NETSURF_GTK_MAJOR}" = "x3" ]; then
+ NS_GTK_DNF_RPM="gtk3-devel"
+else
+ NS_GTK_DNF_RPM="gtk2-devel"
+fi
+
+# dnf commandline to install necessary dev packages
+ns-dnf-install()
+{
+ sudo dnf install $(echo ${NS_DEV_DNF_RPM} ${NS_TOOL_DNF_RPM} ${NS_GTK_DNF_RPM})
+}
+
+
+# packages for zypper installer RPM based systems (tested on openSUSE leap 42)
+NS_DEV_ZYP_RPM="java-1_8_0-openjdk-headless gcc clang pkgconfig libcurl-devel libjpeg-devel libexpat-devel libpng-devel openssl-devel gperf perl-HTML-Parser"
+NS_TOOL_ZYP_RPM="git flex bison gperf ccache screen"
+if [ "x${NETSURF_GTK_MAJOR}" = "x3" ]; then
+ NS_GTK_ZYP_RPM="gtk3-devel"
+else
+ NS_GTK_ZYP_RPM="gtk2-devel"
+fi
+
+# zypper commandline to install necessary dev packages
+ns-zypper-install()
+{
+ sudo zypper install -y $(echo ${NS_DEV_ZYP_RPM} ${NS_TOOL_ZYP_RPM} ${NS_GTK_ZYP_RPM})
+}
+
+
+# Packages for Haiku install
+
+# Haiku secondary arch suffix:
+# empty for primary (gcc2 on x86) or "_x86" for gcc4 secondary.
+HA=_x86
+
+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()
+{
+ pkgman install $(echo ${NS_DEV_HPKG})
+}
+
+
+# MAC OS X
+NS_DEV_MACPORT="git expat openssl curl libjpeg-turbo libpng"
+
+ns-macport-install()
+{
+ PATH=/opt/local/bin:/opt/local/sbin:$PATH sudo /opt/local/bin/port install $(echo ${NS_DEV_MACPORT})
+}
+
+
+# packages for FreeBSD install
+NS_DEV_FREEBSDPKG="gmake curl"
+
+# FreeBSD package install
+ns-freebsdpkg-install()
+{
+ pkg install $(echo ${NS_DEV_FREEBSDPKG})
+}
+
+
+# generic for help text
+NS_DEV_GEN="git, gcc, pkgconfig, expat library, openssl library, libcurl, perl, perl MD5 digest, libjpeg library, libpng library"
+NS_TOOL_GEN="flex tool, bison tool"
+if [ "x${NETSURF_GTK_MAJOR}" = "x3" ]; then
+ NS_GTK_GEN="gtk+ 3 toolkit library, librsvg2 library"
+else
+ NS_GTK_GEN="gtk+ 2 toolkit library, librsvg2 library"
+fi
+
+# Generic OS package install
+# looks for package managers and tries to use them if present
+ns-package-install()
+{
+ if [ -x "/usr/bin/zypper" ]; then
+ ns-zypper-install
+ elif [ -x "/usr/bin/apt-get" ]; then
+ ns-apt-get-install
+ elif [ -x "/usr/bin/dnf" ]; then
+ ns-dnf-install
+ elif [ -x "/usr/bin/yum" ]; then
+ ns-yum-install
+ elif [ -x "/bin/pkgman" ]; then
+ ns-pkgman-install
+ elif [ -x "/opt/local/bin/port" ]; then
+ ns-macport-install
+ elif [ -x "/usr/sbin/pkg" ]; then
+ ns-freebsdpkg-install
+ else
+ echo "Unable to determine OS packaging system in use."
+ echo "Please ensure development packages are installed for:"
+ echo ${NS_DEV_GEN}"," ${NS_TOOL_GEN}"," ${NS_GTK_GEN}
+ fi
+}
+
+###############################################################################
+# Setup environment
+###############################################################################
+
+# find which command used to find everything else on path
+if [ -x /usr/bin/which ]; then
+ WHICH_CMD=/usr/bin/which
+else
+ WHICH_CMD=/bin/which
+fi
+
+# environment parameters
# The system doing the building
if [ "x${BUILD}" = "x" ]; then
- BUILD=$(cc -dumpmachine)
+ BUILD_CC=$(${WHICH_CMD} cc)
+ if [ $? -eq 0 ];then
+ BUILD=$(cc -dumpmachine)
+ else
+ echo "Unable to locate a compiler. Perhaps run ns-package-install"
+ return 1
+ fi
fi
# Get the host build if unset
if [ "x${HOST}" = "x" ]; then
if [ "x${TARGET_ABI}" = "x" ]; then
- HOST=${BUILD}
+ HOST=${BUILD}
else
- HOST=${TARGET_ABI}
+ HOST=${TARGET_ABI}
fi
else
HOST_CC_LIST="${HOST}-cc ${HOST}-gcc /opt/netsurf/${HOST}/cross/bin/${HOST}-cc /opt/netsurf/${HOST}/cross/bin/${HOST}-gcc"
for HOST_CC_V in $(echo ${HOST_CC_LIST});do
- HOST_CC=$(/bin/which ${HOST_CC_V})
- if [ "x${HOST_CC}" != "x" ];then
- break
- fi
+ HOST_CC=$(${WHICH_CMD} ${HOST_CC_V})
+ if [ "x${HOST_CC}" != "x" ];then
+ break
+ fi
done
if [ "x${HOST_CC}" = "x" ];then
- echo "Unable to execute host compiler for HOST=${HOST}. is it set correctly?"
- return 1
+ echo "Unable to execute host compiler for HOST=${HOST}. is it set correctly?"
+ return 1
fi
HOST_CC_MACHINE=$(${HOST_CC} -dumpmachine 2>/dev/null)
if [ "${HOST_CC_MACHINE}" != "${HOST}" ];then
- echo "Compiler dumpmachine differes from HOST setting"
- return 2
+ echo "Compiler dumpmachine differes from HOST setting"
+ return 2
fi
unset HOST_CC_LIST HOST_CC_V HOST_CC HOST_CC_MACHINE
fi
+# set up a default target workspace
if [ "x${TARGET_WORKSPACE}" = "x" ]; then
TARGET_WORKSPACE=${HOME}/dev-netsurf/workspace
fi
+# set up default parallelism
if [ "x${USE_CPUS}" = "x" ]; then
NCPUS=$(getconf _NPROCESSORS_ONLN 2>/dev/null || getconf NPROCESSORS_ONLN 2>/dev/null)
NCPUS="${NCPUS:-1}"
@@ -64,20 +227,17 @@ if [ "x${NETSURF_GTK_MAJOR}" = "x" ]; then
NETSURF_GTK_MAJOR=2
fi
-
-###############################################################################
-# Setup environment
-###############################################################################
-
+# report to user
echo "BUILD=${BUILD}"
echo "HOST=${HOST}"
echo "TARGET_WORKSPACE=${TARGET_WORKSPACE}"
echo "USE_CPUS=${USE_CPUS}"
export PREFIX=${TARGET_WORKSPACE}/inst-${HOST}
+export BUILD_PREFIX=${TARGET_WORKSPACE}/inst-${BUILD}
export PKG_CONFIG_PATH=${PREFIX}/lib/pkgconfig:${PKG_CONFIG_PATH}::
export LD_LIBRARY_PATH=${LD_LIBRARY_PATH}:${PREFIX}/lib
-export PATH=${PATH}:${PREFIX}/bin
+export PATH=${PATH}:${BUILD_PREFIX}/bin
export NETSURF_GTK_MAJOR
# make tool
@@ -90,7 +250,7 @@ NS_GIT="git://git.netsurf-browser.org"
NS_BUILDSYSTEM="buildsystem"
# internal libraries all frontends require (order is important)
-NS_INTERNAL_LIBS="libwapcaplet libparserutils libhubbub libdom libcss libnsgif libnsbmp libutf8proc libnsutils libnspsl"
+NS_INTERNAL_LIBS="libwapcaplet libparserutils libhubbub libdom libcss libnsgif libnsbmp libutf8proc libnsutils libnspsl libnslog"
# The browser itself
NS_BROWSER="netsurf"
@@ -139,8 +299,8 @@ case "${HOST}" in
NS_TOOLS=""
# libraries required for the freebsd frontend
NS_FRONTEND_LIBS=""
- # select gnu make
- MAKE=gmake
+ # select gnu make
+ MAKE=gmake
;;
*)
# default tools required to build the browser
@@ -152,109 +312,18 @@ esac
export MAKE
-################ OS Package installation ################
-
-# deb packages for dpkg based systems
-NS_DEV_DEB="build-essential pkg-config git gperf libcurl3-dev libssl-dev libpng-dev libjpeg-dev"
-NS_TOOL_DEB="flex bison libhtml-parser-perl"
-if [ "x${NETSURF_GTK_MAJOR}" = "x3" ]; then
- NS_GTK_DEB="libgtk-3-dev librsvg2-dev"
-else
- NS_GTK_DEB="libgtk2.0-dev librsvg2-dev"
-fi
-
-# apt get commandline to install necessary dev packages
-ns-apt-get-install()
-{
- sudo apt-get install $(echo ${NS_DEV_DEB} ${NS_TOOL_DEB} ${NS_GTK_DEB})
-}
-
-# RPM packages for rpm based systems (tested on fedora 20)
-NS_DEV_RPM="git gcc pkgconfig libexpat-devel openssl-devel libcurl-devel perl-Digest-MD5-File libjpeg-devel libpng-devel"
-NS_TOOL_RPM="flex bison"
-if [ "x${NETSURF_GTK_MAJOR}" = "x3" ]; then
- NS_GTK_RPM="gtk3-devel librsvg2-devel"
-else
- NS_GTK_RPM="gtk2-devel librsvg2-devel"
-fi
-
-# yum commandline to install necessary dev packages
-ns-yum-install()
-{
- sudo yum -y install $(echo ${NS_DEV_RPM} ${NS_TOOL_RPM} ${NS_GTK_RPM})
-}
-
-# Haiku secondary arch suffix:
-# empty for primary (gcc2 on x86),
-# "_x86" for gcc4 secondary.
-HA=_x86
-# Haiku packages
-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()
-{
- pkgman install $(echo ${NS_DEV_HPKG})
-}
-
-# MAC OS X
-NS_DEV_MACPORT="git expat openssl curl libjpeg-turbo libpng"
-
-ns-macport-install()
-{
- PATH=/opt/local/bin:/opt/local/sbin:$PATH sudo /opt/local/bin/port install $(echo ${NS_DEV_MACPORT})
-}
-
-NS_DEV_FREEBSDPKG="gmake curl"
-
-# FreeBSD package install
-ns-freebsdpkg-install()
-{
- pkg install $(echo ${NS_DEV_FREEBSDPKG})
-}
-
-# generic for help text
-NS_DEV_GEN="git, gcc, pkgconfig, expat library, openssl library, libcurl, perl, perl MD5 digest, libjpeg library, libpng library"
-NS_TOOL_GEN="flex tool, bison tool"
-if [ "x${NETSURF_GTK_MAJOR}" = "x3" ]; then
- NS_GTK_GEN="gtk+ 3 toolkit library, librsvg2 library"
-else
- NS_GTK_GEN="gtk+ 2 toolkit library, librsvg2 library"
-fi
-
-# Genertic OS package install
-# looks for package managers and tries to use them if present
-ns-package-install()
-{
- if [ -x "/usr/bin/apt-get" ]; then
- ns-apt-get-install
- elif [ -x "/usr/bin/yum" ]; then
- ns-yum-install
- elif [ -x "/bin/pkgman" ]; then
- ns-pkgman-install
- elif [ -x "/opt/local/bin/port" ]; then
- ns-macport-install
- elif [ -x "/usr/sbin/pkg" ]; then
- ns-freebsdpkg-install
- else
- echo "Unable to determine OS packaging system in use."
- echo "Please ensure development packages are installed for:"
- echo ${NS_DEV_GEN}"," ${NS_TOOL_GEN}"," ${NS_GTK_GEN}
- fi
-}
-
################ Development helpers ################
# git pull in all repos parameters are passed to git pull
ns-pull()
{
- 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 $*; )
- else
- echo "Repository not present"
- fi
+ 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 $*; )
+ else
+ echo "Repository not present"
+ fi
done
}
@@ -262,38 +331,42 @@ ns-pull()
ns-clone()
{
mkdir -p ${TARGET_WORKSPACE}
- for REPO in $(echo ${NS_BUILDSYSTEM} ${NS_INTERNAL_LIBS} ${NS_FRONTEND_LIBS} ${NS_RISCOS_LIBS} ${NS_TOOLS} ${NS_BROWSER}) ; do
- echo -n " GIT: Cloning ${REPO}: "
- if [ -f ${TARGET_WORKSPACE}/${REPO}/.git/config ]; then
- echo "Repository already present"
- else
- (cd ${TARGET_WORKSPACE} && git clone ${NS_GIT}/${REPO}.git; )
- fi
+ for REPO in $(echo ${NS_BUILDSYSTEM} ${NS_INTERNAL_LIBS} ${NS_FRONTEND_LIBS} ${NS_RISCOS_LIBS} ${NS_TOOLS} ${NS_BROWSER}) ; do
+ echo -n " GIT: Cloning ${REPO}: "
+ if [ -f ${TARGET_WORKSPACE}/${REPO}/.git/config ]; then
+ echo "Repository already present"
+ else
+ (cd ${TARGET_WORKSPACE} && git clone ${NS_GIT}/${REPO}.git; )
+ fi
done
# put current env.sh in place in workspace
if [ ! -f "${TARGET_WORKSPACE}/env.sh" -a -f ${TARGET_WORKSPACE}/${NS_BROWSER}/docs/env.sh ]; then
- cp ${TARGET_WORKSPACE}/${NS_BROWSER}/docs/env.sh ${TARGET_WORKSPACE}/env.sh
+ cp ${TARGET_WORKSPACE}/${NS_BROWSER}/docs/env.sh ${TARGET_WORKSPACE}/env.sh
fi
}
# issues a make command to all libraries
ns-make-libs()
{
- for REPO in $(echo ${NS_BUILDSYSTEM} ${NS_TOOLS}); do
- echo " MAKE: make -C ${REPO} $USE_CPUS $*"
- ${MAKE} -C ${TARGET_WORKSPACE}/${REPO} $USE_CPUS $*
- if [ $? -ne 0 ]; then
- return $?
- fi
+ for REPO in $(echo ${NS_BUILDSYSTEM} ${NS_INTERNAL_LIBS} ${NS_FRONTEND_LIBS}); do
+ echo " MAKE: make -C ${REPO} $USE_CPUS $*"
+ ${MAKE} -C ${TARGET_WORKSPACE}/${REPO} HOST=${HOST} $USE_CPUS $*
+ if [ $? -ne 0 ]; then
+ return $?
+ fi
done
+}
- for REPO in $(echo ${NS_INTERNAL_LIBS} ${NS_FRONTEND_LIBS}); do
- echo " MAKE: make -C ${REPO} $USE_CPUS $*"
- ${MAKE} -C ${TARGET_WORKSPACE}/${REPO} HOST=${HOST} $USE_CPUS $*
- if [ $? -ne 0 ]; then
- return $?
- fi
+# issues make command for all tools
+ns-make-tools()
+{
+ for REPO in $(echo ${NS_BUILDSYSTEM} ${NS_TOOLS}); do
+ echo " MAKE: make -C ${REPO} $USE_CPUS $*"
+ ${MAKE} -C ${TARGET_WORKSPACE}/${REPO} PREFIX=${BUILD_PREFIX} HOST=${BUILD} $USE_CPUS $*
+ if [ $? -ne 0 ]; then
+ return $?
+ fi
done
}
@@ -309,6 +382,7 @@ ns-pull-install()
{
ns-pull $*
+ ns-make-tools install
ns-make-libs install
}
@@ -317,4 +391,3 @@ ns-make()
{
${MAKE} $USE_CPUS "$@"
}
-
diff --git a/docs/logging.md b/docs/logging.md
new file mode 100644
index 000000000..41c7ea1bd
--- /dev/null
+++ b/docs/logging.md
@@ -0,0 +1,90 @@
+NetSurf logging
+===============
+
+NetSurf has a large number of internal diagnostic messages which can
+be viewed by the developer (or user if they wish)
+
+Each message has a category and a level which can be used to control
+which messages are displayed.
+
+The message category is used to allow filters to separate messages of
+the same level from different sources.
+
+The logging levels, from low to high, are:
+
+ - DEEPDEBUG
+ - DEBUG
+ - VERBOSE
+ - INFO
+ - WARNING
+ - ERROR
+ - CRITICAL
+
+Compilation control
+-------------------
+
+At compilation time the logging behaviour can be controlled by using
+configuration overrides in a Makefile.config The parameters are:
+
+ - NETSURF_USE_NSLOG
+ This controls if the NetSurf logging library (nslog) is used to
+ allow comprehensive filtering of messages. The value defaults to
+ AUTO which will use pkg-config to locate the library and enable if
+ present. If set to NO or the library cannot be located the browsers
+ logging will revert to simple boolean enabled/disabled logging
+ controlled by the -v command line switch.
+
+ - NETSURF_LOG_LEVEL
+ This controls what level of message is compiled into the NetSurf
+ binary. The default value is VERBOSE and when not using nslog this
+ value is also used to select what level of logging is shown with the
+ -v command line switch.
+
+ - NETSURF_BUILTIN_LOG_FILTER
+ When using nslog this sets the default non-verbose filter. The
+ default value ("level:WARNING") shows all messages of level WARNING
+ and above
+
+ - NETSURF_BUILTIN_VERBOSE_FILTER
+ When using nslog this sets the default verbose filter. The default
+ value ("level:VERBOSE") shows all messages of level VERBOSE and
+ above. The verbose level is selected from the commandline with the
+ -v switch
+
+Command line
+------------
+
+The main command line switches that control logging are:
+
+ - -v
+ switches between the normal and verbose levels
+
+ - -V <file>
+ Send the logging to a file instead of standard output
+
+ - -log_filter=<filter>
+ Set the non verbose filter
+
+ - -log_verbose_filter=<filter>
+ Set the verbose filter
+
+Options
+-------
+
+The logging filters can be configured by setting the log_filter and
+log_verbose_filter options.
+
+Adding messages
+---------------
+
+Messages can be easily added by including the utils/log.h header and
+he NSLOG() macro. for example
+
+ NSLOG(netsurf, INFO, "An example message %d", example_func());
+
+nslog
+-----
+
+If the nslog library is used it allows for application of a filter to
+control which messages are output. The nslog filter syntax is best
+viewed in its [documentation](http://source.netsurf-browser.org/libnslog.git/tree/docs/mainpage.md)
diff --git a/docs/mainpage.md b/docs/mainpage.md
index 41f26d441..fa72d1464 100644
--- a/docs/mainpage.md
+++ b/docs/mainpage.md
@@ -15,6 +15,11 @@ There are some basic user guides for the
The [core user options](docs/netsurf-options.md) of the browser are
documented which are augmented by each frontend in a specific manner.
+### Logging
+
+The [logging](docs/logging.md) interface controls debug and error
+messages not output through the GUI.
+
Documented API
--------------
diff --git a/frontends/amiga/Makefile b/frontends/amiga/Makefile
index f57b4ef8a..5089b4a46 100644
--- a/frontends/amiga/Makefile
+++ b/frontends/amiga/Makefile
@@ -5,7 +5,7 @@
CFLAGS += -std=c99 -Dnsamiga
ifneq ($(SUBTARGET),os3)
- CFLAGS += -O2 -finline-functions -U__STRICT_ANSI__ -D__USE_INLINE__ -D__USE_BASETYPE__
+ CFLAGS += -O2 -mstrict-align -finline-functions -U__STRICT_ANSI__ -D__USE_INLINE__ -D__USE_BASETYPE__
else
CFLAGS += -O2 -DPATH_MAX=1024 -D__m68k__ -m68020
endif
diff --git a/frontends/amiga/arexx.c b/frontends/amiga/arexx.c
index 7bb2f5882..9484ee92b 100644
--- a/frontends/amiga/arexx.c
+++ b/frontends/amiga/arexx.c
@@ -173,7 +173,7 @@ void ami_arexx_execute(char *script)
if((lock = Lock(script, ACCESS_READ))) {
DevNameFromLock(lock, full_script_path, 1024, DN_FULLPATH);
- LOG("Executing script: %s", full_script_path);
+ NSLOG(netsurf, INFO, "Executing script: %s", full_script_path);
ami_arexx_command(full_script_path, NULL);
UnLock(lock);
}
diff --git a/frontends/amiga/bitmap.c b/frontends/amiga/bitmap.c
index 533b416fa..0fde677ae 100644
--- a/frontends/amiga/bitmap.c
+++ b/frontends/amiga/bitmap.c
@@ -161,7 +161,10 @@ static void amiga_bitmap_unmap_buffer(void *p)
struct bitmap *bm = p;
if((nsoption_bool(use_extmem) == true) && (bm->pixdata != NULL)) {
- LOG("Unmapping ExtMem object %p for bitmap %p", bm->iextmem, bm);
+ NSLOG(netsurf, INFO,
+ "Unmapping ExtMem object %p for bitmap %p",
+ bm->iextmem,
+ bm);
bm->iextmem->Unmap(bm->pixdata, bm->size);
bm->pixdata = NULL;
}
@@ -176,7 +179,10 @@ unsigned char *amiga_bitmap_get_buffer(void *bitmap)
#ifdef __amigaos4__
if(nsoption_bool(use_extmem) == true) {
if(bm->pixdata == NULL) {
- LOG("Mapping ExtMem object %p for bitmap %p", bm->iextmem, bm);
+ NSLOG(netsurf, INFO,
+ "Mapping ExtMem object %p for bitmap %p",
+ bm->iextmem,
+ bm);
bm->pixdata = bm->iextmem->Map(NULL, bm->size, 0LL, 0);
}
@@ -596,8 +602,12 @@ static inline struct BitMap *ami_bitmap_get_generic(struct bitmap *bitmap,
TAG_DONE);
if (err != COMPERR_Success) {
- LOG("Composite error %ld - falling back", err);
- /* If it failed, do it again the way which works in software */
+ NSLOG(netsurf, INFO,
+ "Composite error %ld - falling back",
+ err);
+ /* If it failed, do it again the way
+ * which works in software
+ */
#else
{
#endif
@@ -611,7 +621,8 @@ static inline struct BitMap *ami_bitmap_get_generic(struct bitmap *bitmap,
COMPTAG_FriendBitMap, scrn->RastPort.BitMap,
TAG_DONE);
/* If it still fails... it's non-fatal */
- LOG("Fallback returned error %ld", err);
+ NSLOG(netsurf, INFO,
+ "Fallback returned error %ld", err);
}
} else /* Do it the old-fashioned way. This is pretty slow, even on OS4.1 */
#endif
@@ -723,7 +734,7 @@ void ami_bitmap_fini(void)
static nserror bitmap_render(struct bitmap *bitmap, struct hlcache_handle *content)
{
#ifdef __amigaos4__
- LOG("Entering bitmap_render");
+ NSLOG(netsurf, INFO, "Entering bitmap_render");
int plot_width;
int plot_height;
diff --git a/frontends/amiga/cookies.c b/frontends/amiga/cookies.c
index fd71a9c2a..45e883fde 100644
--- a/frontends/amiga/cookies.c
+++ b/frontends/amiga/cookies.c
@@ -364,7 +364,7 @@ nserror ami_cookies_present(void)
res = ami_cookies_create_window(ncwin);
if (res != NSERROR_OK) {
- LOG("SSL UI builder init failed");
+ NSLOG(netsurf, INFO, "SSL UI builder init failed");
ami_utf8_free(ncwin->core.wintitle);
free(ncwin);
return res;
diff --git a/frontends/amiga/corewindow.c b/frontends/amiga/corewindow.c
index 1a94dd3b2..42ee866ea 100644
--- a/frontends/amiga/corewindow.c
+++ b/frontends/amiga/corewindow.c
@@ -315,7 +315,7 @@ static void ami_cw_redraw_queue(struct ami_corewindow *ami_cw, bool draw)
if(IsMinListEmpty(ami_cw->deferred_rects)) return;
if(draw == false) {
- LOG("Ignoring deferred box redraw queue");
+ NSLOG(netsurf, INFO, "Ignoring deferred box redraw queue");
} // else should probably show busy pointer
node = (struct nsObject *)GetHead((struct List *)ami_cw->deferred_rects);
@@ -378,7 +378,8 @@ ami_cw_redraw(struct ami_corewindow *ami_cw, const struct rect *restrict r)
nsobj = AddObject(ami_cw->deferred_rects, AMINS_RECT);
nsobj->objstruct = deferred_rect;
} else {
- LOG("Ignoring duplicate or subset of queued box redraw");
+ NSLOG(netsurf, INFO,
+ "Ignoring duplicate or subset of queued box redraw");
}
ami_schedule(1, ami_cw_redraw_cb, ami_cw);
}
@@ -525,7 +526,8 @@ HOOKF(void, ami_cw_idcmp_hook, Object *, object, struct IntuiMessage *)
break;
default:
- LOG("IDCMP hook unhandled event: %ld", msg->Class);
+ NSLOG(netsurf, INFO,
+ "IDCMP hook unhandled event: %ld", msg->Class);
break;
}
}
diff --git a/frontends/amiga/dist/NetSurf.guide b/frontends/amiga/dist/NetSurf.guide
index d628a1c3b..0bdd90076 100755
--- a/frontends/amiga/dist/NetSurf.guide
+++ b/frontends/amiga/dist/NetSurf.guide
@@ -144,7 +144,7 @@ There are a couple of Amiga-specific options which can only be changed directly
@{b}redraw_tile_size_x@{ub}/@{b}redraw_tile_size_y@{ub} Specify the size of the off-screen bitmap. Higher will speed up redraws at the expense of memory. 0 disables tiling (will use a bitmap at least the size of the screen NetSurf is running on)
@{b}web_search_width@{ub} Defaults to 0. Larger values will increase the size of the web search gadget next to the URL bar.
@{b}mask_alpha@{ub} Threshold to use when determining which alpha values to convert to full transparency (0 - 255, where 255 will convert even opaque pixels to transparent). Defaults to 0. This is only used in palette-mapped modes where alpha blending is not currently supported.
-@{b}tab_new_session{ub} If NetSurf is already running, this will cause any passed URLs to open in a new tab rather than a new window.
+@{b}tab_new_session@{ub} If NetSurf is already running, this will cause any passed URLs to open in a new tab rather than a new window.
@{b}use_extmem@{ub} Defaults to 1 (enabled). Setting to 0 will prevent NetSurf using Extended Memory to store uncompressed images - this may have a performance benefit and no disadvantage for <2GB configurations. OS4.1FEU1 only.
@{b}download_notify_progress@{ub} Defaults to 0 (disabled). Display download progress in a Ringhio notification. Requires Enhancer Pack (Ringhio 53.65+), behaviour without it is undefined.
@{b}url_file@{ub} Path to URL database file
diff --git a/frontends/amiga/drag.c b/frontends/amiga/drag.c
index a8d3aa9f9..ec0ee3c6a 100644
--- a/frontends/amiga/drag.c
+++ b/frontends/amiga/drag.c
@@ -188,7 +188,8 @@ void ami_drag_save(struct Window *win)
break;
default:
- LOG("Unsupported drag save operation %d", drag_save);
+ NSLOG(netsurf, INFO,
+ "Unsupported drag save operation %d", drag_save);
break;
}
diff --git a/frontends/amiga/dt_anim.c b/frontends/amiga/dt_anim.c
index 2f998d299..bd049206c 100644
--- a/frontends/amiga/dt_anim.c
+++ b/frontends/amiga/dt_anim.c
@@ -162,7 +162,7 @@ nserror amiga_dt_anim_create(const content_handler *handler,
bool amiga_dt_anim_convert(struct content *c)
{
- LOG("amiga_dt_anim_convert");
+ NSLOG(netsurf, INFO, "amiga_dt_anim_convert");
amiga_dt_anim_content *plugin = (amiga_dt_anim_content *) c;
union content_msg_data msg_data;
@@ -190,7 +190,7 @@ bool amiga_dt_anim_convert(struct content *c)
plugin->bitmap = amiga_bitmap_create(width, height, bm_flags);
if (!plugin->bitmap) {
msg_data.error = messages_get("NoMemory");
- content_broadcast(c, CONTENT_MSG_ERROR, msg_data);
+ content_broadcast(c, CONTENT_MSG_ERROR, &msg_data);
return false;
}
@@ -246,7 +246,7 @@ void amiga_dt_anim_destroy(struct content *c)
{
amiga_dt_anim_content *plugin = (amiga_dt_anim_content *) c;
- LOG("amiga_dt_anim_destroy");
+ NSLOG(netsurf, INFO, "amiga_dt_anim_destroy");
if (plugin->bitmap != NULL)
amiga_bitmap_destroy(plugin->bitmap);
@@ -263,7 +263,7 @@ bool amiga_dt_anim_redraw(struct content *c,
amiga_dt_anim_content *plugin = (amiga_dt_anim_content *) c;
bitmap_flags_t flags = BITMAPF_NONE;
- LOG("amiga_dt_anim_redraw");
+ NSLOG(netsurf, INFO, "amiga_dt_anim_redraw");
if (data->repeat_x)
flags |= BITMAPF_REPEAT_X;
@@ -290,20 +290,20 @@ bool amiga_dt_anim_redraw(struct content *c,
void amiga_dt_anim_open(struct content *c, struct browser_window *bw,
struct content *page, struct object_params *params)
{
- LOG("amiga_dt_anim_open");
+ NSLOG(netsurf, INFO, "amiga_dt_anim_open");
return;
}
void amiga_dt_anim_close(struct content *c)
{
- LOG("amiga_dt_anim_close");
+ NSLOG(netsurf, INFO, "amiga_dt_anim_close");
return;
}
void amiga_dt_anim_reformat(struct content *c, int width, int height)
{
- LOG("amiga_dt_anim_reformat");
+ NSLOG(netsurf, INFO, "amiga_dt_anim_reformat");
return;
}
@@ -312,7 +312,7 @@ nserror amiga_dt_anim_clone(const struct content *old, struct content **newc)
amiga_dt_anim_content *plugin;
nserror error;
- LOG("amiga_dt_anim_clone");
+ NSLOG(netsurf, INFO, "amiga_dt_anim_clone");
plugin = calloc(1, sizeof(amiga_dt_anim_content));
if (plugin == NULL)
diff --git a/frontends/amiga/dt_picture.c b/frontends/amiga/dt_picture.c
index e7f1c9724..88ce1c834 100644
--- a/frontends/amiga/dt_picture.c
+++ b/frontends/amiga/dt_picture.c
@@ -174,7 +174,7 @@ static char *amiga_dt_picture_datatype(struct content *c)
static struct bitmap *amiga_dt_picture_cache_convert(struct content *c)
{
- LOG("amiga_dt_picture_cache_convert");
+ NSLOG(netsurf, INFO, "amiga_dt_picture_cache_convert");
union content_msg_data msg_data;
UBYTE *bm_buffer;
@@ -187,7 +187,7 @@ static struct bitmap *amiga_dt_picture_cache_convert(struct content *c)
bitmap = amiga_bitmap_create(c->width, c->height, BITMAP_NEW);
if (!bitmap) {
msg_data.error = messages_get("NoMemory");
- content_broadcast(c, CONTENT_MSG_ERROR, msg_data);
+ content_broadcast(c, CONTENT_MSG_ERROR, &msg_data);
return NULL;
}
@@ -210,7 +210,7 @@ static struct bitmap *amiga_dt_picture_cache_convert(struct content *c)
bool amiga_dt_picture_convert(struct content *c)
{
- LOG("amiga_dt_picture_convert");
+ NSLOG(netsurf, INFO, "amiga_dt_picture_convert");
int width, height;
char *title;
@@ -256,7 +256,7 @@ nserror amiga_dt_picture_clone(const struct content *old, struct content **newc)
struct content *adt;
nserror error;
- LOG("amiga_dt_picture_clone");
+ NSLOG(netsurf, INFO, "amiga_dt_picture_clone");
adt = calloc(1, sizeof(struct content));
if (adt == NULL)
diff --git a/frontends/amiga/dt_sound.c b/frontends/amiga/dt_sound.c
index eda60edc1..e0f48da83 100644
--- a/frontends/amiga/dt_sound.c
+++ b/frontends/amiga/dt_sound.c
@@ -76,7 +76,7 @@ static const content_handler amiga_dt_sound_content_handler = {
static void amiga_dt_sound_play(Object *dto)
{
- LOG("Playing...");
+ NSLOG(netsurf, INFO, "Playing...");
IDoMethod(dto, DTM_TRIGGER, NULL, STM_PLAY, NULL);
}
@@ -126,7 +126,7 @@ nserror amiga_dt_sound_create(const content_handler *handler,
amiga_dt_sound_content *plugin;
nserror error;
- LOG("amiga_dt_sound_create");
+ NSLOG(netsurf, INFO, "amiga_dt_sound_create");
plugin = calloc(1, sizeof(amiga_dt_sound_content));
if (plugin == NULL)
@@ -146,7 +146,7 @@ nserror amiga_dt_sound_create(const content_handler *handler,
bool amiga_dt_sound_convert(struct content *c)
{
- LOG("amiga_dt_sound_convert");
+ NSLOG(netsurf, INFO, "amiga_dt_sound_convert");
amiga_dt_sound_content *plugin = (amiga_dt_sound_content *) c;
int width = 50, height = 50;
@@ -180,7 +180,7 @@ void amiga_dt_sound_destroy(struct content *c)
{
amiga_dt_sound_content *plugin = (amiga_dt_sound_content *) c;
- LOG("amiga_dt_sound_destroy");
+ NSLOG(netsurf, INFO, "amiga_dt_sound_destroy");
DisposeDTObject(plugin->dto);
@@ -199,7 +199,7 @@ bool amiga_dt_sound_redraw(struct content *c,
};
struct rect rect;
- LOG("amiga_dt_sound_redraw");
+ NSLOG(netsurf, INFO, "amiga_dt_sound_redraw");
rect.x0 = data->x;
rect.y0 = data->y;
@@ -226,7 +226,7 @@ void amiga_dt_sound_open(struct content *c, struct browser_window *bw,
amiga_dt_sound_content *plugin = (amiga_dt_sound_content *) c;
struct object_param *param;
- LOG("amiga_dt_sound_open");
+ NSLOG(netsurf, INFO, "amiga_dt_sound_open");
plugin->immediate = false;
@@ -234,7 +234,8 @@ void amiga_dt_sound_open(struct content *c, struct browser_window *bw,
{
do
{
- LOG("%s = %s", param->name, param->value);
+ NSLOG(netsurf, INFO, "%s = %s", param->name,
+ param->value);
if((strcmp(param->name, "autoplay") == 0) &&
(strcmp(param->value, "true") == 0)) plugin->immediate = true;
if((strcmp(param->name, "autoStart") == 0) &&
@@ -255,7 +256,7 @@ nserror amiga_dt_sound_clone(const struct content *old, struct content **newc)
amiga_dt_sound_content *plugin;
nserror error;
- LOG("amiga_dt_sound_clone");
+ NSLOG(netsurf, INFO, "amiga_dt_sound_clone");
plugin = calloc(1, sizeof(amiga_dt_sound_content));
if (plugin == NULL)
diff --git a/frontends/amiga/filetype.c b/frontends/amiga/filetype.c
index a0449d848..0e535de07 100644
--- a/frontends/amiga/filetype.c
+++ b/frontends/amiga/filetype.c
@@ -185,7 +185,7 @@ nserror ami_mime_init(const char *mimefile)
struct nsObject *node;
struct ami_mime_entry *mimeentry;
- LOG("mimetypes file: %s", mimefile);
+ NSLOG(netsurf, INFO, "mimetypes file: %s", mimefile);
if(ami_mime_list == NULL)
ami_mime_list = NewObjList();
@@ -642,6 +642,10 @@ void ami_mime_dump(void)
struct ami_mime_entry *mimeentry;
while((mimeentry = ami_mime_entry_locate(NULL, AMI_MIME_MIMETYPE, &node))) {
- LOG("%s DT=\"%s\" TYPE=\"%s\" CMD=\"%s\"", mimeentry->mimetype ? lwc_string_data(mimeentry->mimetype) : "", mimeentry->datatype ? lwc_string_data(mimeentry->datatype) : "", mimeentry->filetype ? lwc_string_data(mimeentry->filetype) : "", mimeentry->plugincmd ? lwc_string_data(mimeentry->plugincmd) : "");
+ NSLOG(netsurf, INFO, "%s DT=\"%s\" TYPE=\"%s\" CMD=\"%s\"",
+ mimeentry->mimetype ? lwc_string_data(mimeentry->mimetype) : "",
+ mimeentry->datatype ? lwc_string_data(mimeentry->datatype) : "",
+ mimeentry->filetype ? lwc_string_data(mimeentry->filetype) : "",
+ mimeentry->plugincmd ? lwc_string_data(mimeentry->plugincmd) : "");
};
}
diff --git a/frontends/amiga/font.c b/frontends/amiga/font.c
index 22a0f4a4a..e69ff55f0 100644
--- a/frontends/amiga/font.c
+++ b/frontends/amiga/font.c
@@ -37,7 +37,7 @@ static ULONG ami_xdpi = 72;
ULONG ami_font_dpi_get_devicedpi(void)
{
- return ami_devicedpi;
+ return (ami_xdpi << 16) | ami_devicedpi;
}
ULONG ami_font_dpi_get_xdpi(void)
@@ -51,7 +51,8 @@ void ami_font_setdevicedpi(int id)
struct DisplayInfo dinfo;
if(nsoption_bool(bitmap_fonts) == true) {
- LOG("WARNING: Using diskfont.library for text. Forcing DPI to 72.");
+ NSLOG(netsurf, INFO,
+ "WARNING: Using diskfont.library for text. Forcing DPI to 72.");
nsoption_set_int(screen_ydpi, 72);
}
@@ -79,7 +80,14 @@ void ami_font_setdevicedpi(int id)
xdpi = (yres * ydpi) / xres;
- LOG("XDPI = %ld, YDPI = %ld (DisplayInfo resolution %d x %d, corrected %d x %d)", xdpi, ydpi, dinfo.Resolution.x, dinfo.Resolution.y, xres, yres);
+ NSLOG(netsurf, INFO,
+ "XDPI = %ld, YDPI = %ld (DisplayInfo resolution %d x %d, corrected %d x %d)",
+ xdpi,
+ ydpi,
+ dinfo.Resolution.x,
+ dinfo.Resolution.y,
+ xres,
+ yres);
}
}
}
diff --git a/frontends/amiga/font_bullet.c b/frontends/amiga/font_bullet.c
index fd41c29a2..c8ad34c04 100644
--- a/frontends/amiga/font_bullet.c
+++ b/frontends/amiga/font_bullet.c
@@ -361,7 +361,7 @@ static struct ami_font_cache_node *ami_font_open(const char *font, bool critical
if(!nodedata->font)
{
- LOG("Requested font not found: %s", font);
+ NSLOG(netsurf, INFO, "Requested font not found: %s", font);
if(critical == true) amiga_warn_user("CompError", font);
free(nodedata);
return NULL;
@@ -369,21 +369,28 @@ static struct ami_font_cache_node *ami_font_open(const char *font, bool critical
nodedata->bold = (char *)GetTagData(OT_BName, 0, nodedata->font->olf_OTagList);
if(nodedata->bold)
- LOG("Bold font defined for %s is %s", font, nodedata->bold);
+ NSLOG(netsurf, INFO, "Bold font defined for %s is %s", font,
+ nodedata->bold);
else
- LOG("Warning: No designed bold font defined for %s", font);
+ NSLOG(netsurf, INFO,
+ "Warning: No designed bold font defined for %s", font);
nodedata->italic = (char *)GetTagData(OT_IName, 0, nodedata->font->olf_OTagList);
if(nodedata->italic)
- LOG("Italic font defined for %s is %s", font, nodedata->italic);
+ NSLOG(netsurf, INFO, "Italic font defined for %s is %s",
+ font, nodedata->italic);
else
- LOG("Warning: No designed italic font defined for %s", font);
+ NSLOG(netsurf, INFO,
+ "Warning: No designed italic font defined for %s", font);
nodedata->bolditalic = (char *)GetTagData(OT_BIName, 0, nodedata->font->olf_OTagList);
if(nodedata->bolditalic)
- LOG("Bold-italic font defined for %s is %s", font, nodedata->bolditalic);
+ NSLOG(netsurf, INFO, "Bold-italic font defined for %s is %s",
+ font, nodedata->bolditalic);
else
- LOG("Warning: No designed bold-italic font defined for %s", font);
+ NSLOG(netsurf, INFO,
+ "Warning: No designed bold-italic font defined for %s",
+ font);
ami_font_cache_insert(nodedata, font);
return nodedata;
diff --git a/frontends/amiga/font_cache.c b/frontends/amiga/font_cache.c
index 3d8330979..86e2381c0 100644
--- a/frontends/amiga/font_cache.c
+++ b/frontends/amiga/font_cache.c
@@ -69,7 +69,10 @@ static void ami_font_cache_cleanup(struct SkipList *skiplist)
SubTime(&curtime, &node->lastused);
if(curtime.Seconds > 300)
{
- LOG("Freeing font %p not used for %ld seconds", node->skip_node.sn_Key, curtime.Seconds);
+ NSLOG(netsurf, INFO,
+ "Freeing font %p not used for %ld seconds",
+ node->skip_node.sn_Key,
+ curtime.Seconds);
ami_font_bullet_close(node);
RemoveSkipNode(skiplist, node->skip_node.sn_Key);
}
@@ -98,7 +101,10 @@ static void ami_font_cache_cleanup(struct MinList *ami_font_cache_list)
SubTime(&curtime, &fnode->lastused);
if(curtime.Seconds > 300)
{
- LOG("Freeing %s not used for %ld seconds", node->dtz_Node.ln_Name, curtime.Seconds);
+ NSLOG(netsurf, INFO,
+ "Freeing %s not used for %ld seconds",
+ node->dtz_Node.ln_Name,
+ curtime.Seconds);
DelObject(node);
}
} while((node=nnode));
@@ -146,7 +152,7 @@ struct ami_font_cache_node *ami_font_cache_locate(const char *font)
return nodedata;
}
- LOG("Font cache miss: %s (%lx)", font, hash);
+ NSLOG(netsurf, INFO, "Font cache miss: %s (%lx)", font, hash);
return NULL;
}
@@ -180,7 +186,7 @@ void ami_font_cache_insert(struct ami_font_cache_node *nodedata, const char *fon
void ami_font_cache_fini(void)
{
- LOG("Cleaning up font cache");
+ NSLOG(netsurf, INFO, "Cleaning up font cache");
ami_schedule(-1, (void *)ami_font_cache_cleanup, ami_font_cache_list);
#ifdef __amigaos4__
ami_font_cache_del_skiplist(ami_font_cache_list);
diff --git a/frontends/amiga/font_diskfont.c b/frontends/amiga/font_diskfont.c
index 7abc4379b..2da3f0038 100644
--- a/frontends/amiga/font_diskfont.c
+++ b/frontends/amiga/font_diskfont.c
@@ -55,7 +55,6 @@ static struct TextFont *ami_font_bm_open(struct RastPort *rp, const plot_font_st
(fstyle->size == prev_fstyle->size) &&
(fstyle->flags == prev_fstyle->flags) &&
(fstyle->weight == prev_fstyle->weight)) {
- LOG("(using current font)");
return prev_font;
}
@@ -99,7 +98,7 @@ static struct TextFont *ami_font_bm_open(struct RastPort *rp, const plot_font_st
snprintf(font, MAX_FONT_NAME_SIZE, "%s.font", fontname);
tattr.ta_Name = font;
tattr.ta_YSize = fstyle->size / FONT_SIZE_SCALE;
- LOG("font: %s/%d", tattr.ta_Name, tattr.ta_YSize);
+ NSLOG(netsurf, INFO, "font: %s/%d", tattr.ta_Name, tattr.ta_YSize);
if(prev_font != NULL) CloseFont(prev_font);
diff --git a/frontends/amiga/font_scan.c b/frontends/amiga/font_scan.c
index 932179e3e..cb37f97fa 100644
--- a/frontends/amiga/font_scan.c
+++ b/frontends/amiga/font_scan.c
@@ -255,7 +255,8 @@ static ULONG ami_font_scan_font(const char *fontname, lwc_string **glypharray)
#ifdef __amigaos4__
if(EObtainInfo(AMI_OFONT_ENGINE, OT_UnicodeRanges, &unicoderanges, TAG_END) == 0) {
if(unicoderanges & UCR_SURROGATES) {
- LOG("%s supports UTF-16 surrogates", fontname);
+ NSLOG(netsurf, INFO, "%s supports UTF-16 surrogates",
+ fontname);
if (nsoption_charp(font_surrogate) == NULL) {
nsoption_set_charp(font_surrogate, (char *)strdup(fontname));
}
@@ -292,10 +293,11 @@ static ULONG ami_font_scan_fonts(struct MinList *list,
do {
nnode = (struct nsObject *)GetSucc((struct Node *)node);
ami_font_scan_gui_update(win, node->dtz_Node.ln_Name, font_num, total);
- LOG("Scanning %s", node->dtz_Node.ln_Name);
+ NSLOG(netsurf, INFO, "Scanning %s", node->dtz_Node.ln_Name);
found = ami_font_scan_font(node->dtz_Node.ln_Name, glypharray);
total += found;
- LOG("Found %ld new glyphs (total = %ld)", found, total);
+ NSLOG(netsurf, INFO, "Found %ld new glyphs (total = %ld)",
+ found, total);
font_num++;
} while((node = nnode));
@@ -344,7 +346,9 @@ static ULONG ami_font_scan_list(struct MinList *list)
if(node) {
node->dtz_Node.ln_Name = strdup(af[i].af_Attr.ta_Name);
found++;
- LOG("Added %s", af[i].af_Attr.ta_Name);
+ NSLOG(netsurf, INFO,
+ "Added %s",
+ af[i].af_Attr.ta_Name);
}
}
}
@@ -382,7 +386,8 @@ static ULONG ami_font_scan_load(const char *filename, lwc_string **glypharray)
rargs = AllocDosObjectTags(DOS_RDARGS, TAG_DONE);
if((fh = FOpen(filename, MODE_OLDFILE, 0))) {
- LOG("Loading font glyph cache from %s", filename);
+ NSLOG(netsurf, INFO, "Loading font glyph cache from %s",
+ filename);
while(FGets(fh, (STRPTR)&buffer, 256) != 0)
{
@@ -423,7 +428,8 @@ void ami_font_scan_save(const char *filename, lwc_string **glypharray)
BPTR fh = 0;
if((fh = FOpen(filename, MODE_NEWFILE, 0))) {
- LOG("Writing font glyph cache to %s", filename);
+ NSLOG(netsurf, INFO, "Writing font glyph cache to %s",
+ filename);
FPrintf(fh, "; This file is auto-generated. To re-create the cache, delete this file.\n");
FPrintf(fh, "; This file is parsed using ReadArgs() with the following template:\n");
FPrintf(fh, "; CODE/A,FONT/A\n;\n");
@@ -482,7 +488,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");
+ NSLOG(netsurf, INFO, "Creating new font glyph cache");
if((list = NewObjList())) {
/* add preferred fonts list */
@@ -504,7 +510,7 @@ void ami_font_scan_init(const char *filename, bool force_scan, bool save,
if(nsoption_bool(font_unicode_only) == false)
entries += ami_font_scan_list(list);
- LOG("Found %ld fonts", entries);
+ NSLOG(netsurf, INFO, "Found %ld fonts", entries);
win = ami_font_scan_gui_open(entries);
found = ami_font_scan_fonts(list, win, glypharray);
@@ -517,6 +523,6 @@ void ami_font_scan_init(const char *filename, bool force_scan, bool save,
}
}
- LOG("Initialised with %ld glyphs", found);
+ NSLOG(netsurf, INFO, "Initialised with %ld glyphs", found);
}
diff --git a/frontends/amiga/gui.c b/frontends/amiga/gui.c
index 44bba2d90..8e822f3ac 100644
--- a/frontends/amiga/gui.c
+++ b/frontends/amiga/gui.c
@@ -342,7 +342,9 @@ bool ami_gui_map_filename(char **remapped, const char *restrict path,
}
if(found == false) *remapped = strdup(file);
- else LOG("Remapped %s to %s in path %s using %s", file, *remapped, path, map);
+ else NSLOG(netsurf, INFO,
+ "Remapped %s to %s in path %s using %s", file,
+ *remapped, path, map);
free(mapfile);
@@ -365,7 +367,7 @@ static bool ami_gui_check_resource(char *fullpath, const char *file)
found = true;
}
- if(found) LOG("Found %s", fullpath);
+ if(found) NSLOG(netsurf, INFO, "Found %s", fullpath);
free(remapped);
return found;
@@ -842,7 +844,7 @@ static void ami_openscreen(void)
}
if(screen_signal == -1) screen_signal = AllocSignal(-1);
- LOG("Screen signal %d", screen_signal);
+ NSLOG(netsurf, INFO, "Screen signal %d", screen_signal);
scrn = OpenScreenTags(NULL,
/**\todo specify screen depth */
SA_DisplayID, id,
@@ -918,19 +920,22 @@ static struct RDArgs *ami_gui_commandline(int *restrict argc, char ** argv,
if((args = ReadArgs(template, rarray, NULL))) {
if(rarray[A_URL]) {
- LOG("URL %s specified on command line",
- (char *)rarray[A_URL]);
+ NSLOG(netsurf, INFO,
+ "URL %s specified on command line",
+ (char *)rarray[A_URL]);
temp_homepage_url = strdup((char *)rarray[A_URL]); /**\todo allow IDNs */
}
if(rarray[A_USERSDIR]) {
- LOG("USERSDIR %s specified on command line",
- (char *)rarray[A_USERSDIR]);
+ NSLOG(netsurf, INFO,
+ "USERSDIR %s specified on command line",
+ (char *)rarray[A_USERSDIR]);
users_dir = ASPrintf("%s", rarray[A_USERSDIR]);
}
if(rarray[A_FORCE]) {
- LOG("FORCE specified on command line");
+ NSLOG(netsurf, INFO,
+ "FORCE specified on command line");
cli_force = true;
}
@@ -950,7 +955,7 @@ static struct RDArgs *ami_gui_commandline(int *restrict argc, char ** argv,
*/
}
} else {
- LOG("ReadArgs failed to parse command line");
+ NSLOG(netsurf, INFO, "ReadArgs failed to parse command line");
}
FreeArgs(args);
@@ -1220,12 +1225,10 @@ static void ami_update_buttons(struct gui_window_2 *gwin)
}
}
-#ifdef __amigaos4__
GetAttr(GA_Disabled, gwin->objects[GID_BACK], (uint32 *)&s_back);
GetAttr(GA_Disabled, gwin->objects[GID_FORWARD], (uint32 *)&s_forward);
GetAttr(GA_Disabled, gwin->objects[GID_RELOAD], (uint32 *)&s_reload);
GetAttr(GA_Disabled, gwin->objects[GID_STOP], (uint32 *)&s_stop);
-#endif
if(BOOL_MISMATCH(s_back, back))
SetGadgetAttrs((struct Gadget *)gwin->objects[GID_BACK],
@@ -1245,9 +1248,9 @@ static void ami_update_buttons(struct gui_window_2 *gwin)
if(ClickTabBase->lib_Version < 53) {
if(gwin->tabs <= 1) tabclose = TRUE;
-#ifdef __amigaos4__
+
GetAttr(GA_Disabled, gwin->objects[GID_CLOSETAB], (uint32 *)&s_tabclose);
-#endif
+
if(BOOL_MISMATCH(s_tabclose, tabclose))
SetGadgetAttrs((struct Gadget *)gwin->objects[GID_CLOSETAB],
gwin->win, NULL, GA_Disabled, tabclose, TAG_DONE);
@@ -2522,10 +2525,9 @@ static BOOL ami_gui_event(void *w)
#ifdef __amigaos4__
case WMHI_ICONIFY:
{
- struct bitmap *bm;
-
- bm = urldb_get_thumbnail(browser_window_get_url(gwin->gw->bw));
- if(!bm) bm = content_get_bitmap(browser_window_get_content(gwin->gw->bw));
+ struct bitmap *bm = NULL;
+ browser_window_history_get_thumbnail(gwin->gw->bw,
+ &bm);
gwin->dobj = amiga_icon_from_bitmap(bm);
amiga_icon_superimpose_favicon_internal(gwin->gw->favicon,
gwin->dobj);
@@ -2790,7 +2792,9 @@ static void ami_handle_applib(void)
{
struct ApplicationCustomMsg *applibcustmsg =
(struct ApplicationCustomMsg *)applibmsg;
- LOG("Ringhio BackMsg received: %s", applibcustmsg->customMsg);
+ NSLOG(netsurf, INFO,
+ "Ringhio BackMsg received: %s",
+ applibcustmsg->customMsg);
ami_download_parse_backmsg(applibcustmsg->customMsg);
}
@@ -2826,7 +2830,7 @@ void ami_get_msg(void)
NULL, (unsigned int *)&signalmask) != -1) {
signal = signalmask;
} else {
- LOG("waitselect() returned error");
+ NSLOG(netsurf, INFO, "waitselect() returned error");
/* \todo Fix Ctrl-C handling.
* WaitSelect() from bsdsocket.library returns -1 if the task was
* signalled with a Ctrl-C. waitselect() from newlib.library does not.
@@ -3035,11 +3039,13 @@ static void ami_gui_close_screen(struct Screen *scrn, BOOL locked_screen, BOOL d
if(donotwait == TRUE) return;
ULONG scrnsig = 1 << screen_signal;
- LOG("Waiting for visitor windows to close... (signal)");
+ NSLOG(netsurf, INFO,
+ "Waiting for visitor windows to close... (signal)");
Wait(scrnsig);
while (CloseScreen(scrn) == FALSE) {
- LOG("Waiting for visitor windows to close... (polling)");
+ NSLOG(netsurf, INFO,
+ "Waiting for visitor windows to close... (polling)");
Delay(50);
}
@@ -3081,11 +3087,11 @@ static void gui_quit(void)
ami_font_fini();
ami_help_free();
- LOG("Freeing menu items");
+ NSLOG(netsurf, INFO, "Freeing menu items");
ami_ctxmenu_free();
ami_menu_free_glyphs();
- LOG("Freeing mouse pointers");
+ NSLOG(netsurf, INFO, "Freeing mouse pointers");
ami_mouse_pointers_free();
ami_file_req_free();
@@ -3099,7 +3105,7 @@ static void gui_quit(void)
ami_clipboard_free();
ami_gui_resources_free();
- LOG("Closing screen");
+ NSLOG(netsurf, INFO, "Closing screen");
ami_gui_close_screen(scrn, locked_screen, FALSE);
if(nsscreentitle) FreeVec(nsscreentitle);
}
@@ -3109,7 +3115,7 @@ char *ami_gui_get_cache_favicon_name(nsurl *url, bool only_if_avail)
STRPTR filename = NULL;
if ((filename = ASPrintf("%s/%x", current_user_faviconcache, nsurl_hash(url)))) {
- LOG("favicon cache location: %s", filename);
+ NSLOG(netsurf, INFO, "favicon cache location: %s", filename);
if (only_if_avail == true) {
BPTR lock = 0;
@@ -3723,7 +3729,8 @@ static nserror amiga_window_invalidate_area(struct gui_window *g,
nsobj = AddObject(g->deferred_rects, AMINS_RECT);
nsobj->objstruct = deferred_rect;
} else {
- LOG("Ignoring duplicate or subset of queued box redraw");
+ NSLOG(netsurf, INFO,
+ "Ignoring duplicate or subset of queued box redraw");
}
}
ami_schedule_redraw(g->shared, false);
@@ -3853,7 +3860,8 @@ HOOKF(void, ami_scroller_hook, Object *, object, struct IntuiMessage *)
break;
default:
- LOG("IDCMP hook unhandled event: %ld", msg->Class);
+ NSLOG(netsurf, INFO,
+ "IDCMP hook unhandled event: %ld", msg->Class);
break;
}
// ReplyMsg((struct Message *)msg);
@@ -3912,7 +3920,7 @@ gui_window_create(struct browser_window *bw,
ULONG defer_layout = TRUE;
ULONG idcmp_sizeverify = IDCMP_SIZEVERIFY;
- LOG("Creating window");
+ NSLOG(netsurf, INFO, "Creating window");
if (!scrn) ami_openscreenfirst();
@@ -4051,12 +4059,14 @@ gui_window_create(struct browser_window *bw,
ULONG addtabclosegadget = TAG_IGNORE;
ULONG iconifygadget = FALSE;
+#ifdef __amigaos4__
if (nsoption_charp(pubscreen_name) &&
(locked_screen == TRUE) &&
(strcmp(nsoption_charp(pubscreen_name), "Workbench") == 0))
iconifygadget = TRUE;
+#endif
- LOG("Creating menu");
+ NSLOG(netsurf, INFO, "Creating menu");
struct Menu *menu = ami_gui_menu_create(g->shared);
NewList(&g->shared->tab_list);
@@ -4178,7 +4188,7 @@ gui_window_create(struct browser_window *bw,
BitMapEnd;
}
- LOG("Creating window object");
+ NSLOG(netsurf, INFO, "Creating window object");
g->shared->objects[OID_MAIN] = WindowObj,
WA_ScreenTitle, ami_gui_get_screen_title(),
@@ -4456,11 +4466,11 @@ gui_window_create(struct browser_window *bw,
EndWindow;
}
- LOG("Opening window");
+ NSLOG(netsurf, INFO, "Opening window");
g->shared->win = (struct Window *)RA_OpenWindow(g->shared->objects[OID_MAIN]);
- LOG("Window opened, adding border gadgets");
+ NSLOG(netsurf, INFO, "Window opened, adding border gadgets");
if(!g->shared->win)
{
@@ -4796,7 +4806,7 @@ static void ami_gui_window_update_box_deferred(struct gui_window *g, bool draw)
if(draw == true) {
ami_set_pointer(g->shared, GUI_POINTER_WAIT, false);
} else {
- LOG("Ignoring deferred box redraw queue");
+ NSLOG(netsurf, INFO, "Ignoring deferred box redraw queue");
}
node = (struct nsObject *)GetHead((struct List *)g->deferred_rects);
@@ -4841,7 +4851,8 @@ bool ami_gui_window_update_box_deferred_check(struct MinList *deferred_rects,
(new_rect->y0 <= rect->y0) &&
(new_rect->x1 >= rect->x1) &&
(new_rect->y1 >= rect->y1)) {
- LOG("Removing queued redraw that is a subset of new box redraw");
+ NSLOG(netsurf, INFO,
+ "Removing queued redraw that is a subset of new box redraw");
ami_memory_itempool_free(mempool, node->objstruct, sizeof(struct rect));
DelObjectNoFree(node);
/* Don't return - we might find more */
@@ -5414,20 +5425,20 @@ Object *ami_gui_splash_open(void)
EndWindow;
if(win_obj == NULL) {
- LOG("Splash window object not created");
+ NSLOG(netsurf, INFO, "Splash window object not created");
return NULL;
}
- LOG("Attempting to open splash window...");
+ NSLOG(netsurf, INFO, "Attempting to open splash window...");
win = RA_OpenWindow(win_obj);
if(win == NULL) {
- LOG("Splash window did not open");
+ NSLOG(netsurf, INFO, "Splash window did not open");
return NULL;
}
if(bm_obj == NULL) {
- LOG("BitMap object not created");
+ NSLOG(netsurf, INFO, "BitMap object not created");
return NULL;
}
@@ -5489,14 +5500,14 @@ void ami_gui_splash_close(Object *win_obj)
{
if(win_obj == NULL) return;
- LOG("Closing splash window");
+ NSLOG(netsurf, INFO, "Closing splash window");
DisposeObject(win_obj);
}
static void gui_file_gadget_open(struct gui_window *g, struct hlcache_handle *hl,
struct form_control *gadget)
{
- LOG("File open dialog request for %p/%p", g, gadget);
+ NSLOG(netsurf, INFO, "File open dialog request for %p/%p", g, gadget);
if(AslRequestTags(filereq,
ASLFR_Window, g->shared->win,
@@ -5531,7 +5542,7 @@ static char *ami_gui_get_user_dir(STRPTR current_user)
user = GetVar("user", temp, 1024, GVF_GLOBAL_ONLY);
current_user = ASPrintf("%s", (user == -1) ? "Default" : temp);
}
- LOG("User: %s", current_user);
+ NSLOG(netsurf, INFO, "User: %s", current_user);
if(users_dir == NULL) {
users_dir = ASPrintf("%s", USERS_DIR);
@@ -5583,7 +5594,7 @@ static char *ami_gui_get_user_dir(STRPTR current_user)
FreeVec(users_dir);
FreeVec(current_user);
- LOG("User dir: %s", current_user_dir);
+ NSLOG(netsurf, INFO, "User dir: %s", current_user_dir);
if((lock = CreateDirTree(current_user_dir)))
UnLock(lock);
@@ -5810,7 +5821,7 @@ int main(int argc, char** argv)
AddPart(script, nsoption_charp(arexx_startup), 1024);
ami_arexx_execute(script);
- LOG("Entering main loop");
+ NSLOG(netsurf, INFO, "Entering main loop");
while (!ami_quit) {
ami_get_msg();
@@ -5829,6 +5840,9 @@ int main(int argc, char** argv)
free(current_user_dir);
FreeVec(current_user_faviconcache);
+ /* finalise logging */
+ nslog_finalise();
+
#ifndef __amigaos4__
/* OS3 low memory handler */
ami_memory_fini(memhandler);
diff --git a/frontends/amiga/gui_menu.c b/frontends/amiga/gui_menu.c
index 6ee0800f8..756f5e66c 100644
--- a/frontends/amiga/gui_menu.c
+++ b/frontends/amiga/gui_menu.c
@@ -584,7 +584,8 @@ ULONG ami_gui_menu_number(int item)
break;
default:
- LOG("WARNING: Unrecognised menu item %d", item);
+ NSLOG(netsurf, INFO,
+ "WARNING: Unrecognised menu item %d", item);
menu_num = 0;
break;
}
diff --git a/frontends/amiga/gui_options.c b/frontends/amiga/gui_options.c
index 48228407f..cc3a915df 100755
--- a/frontends/amiga/gui_options.c
+++ b/frontends/amiga/gui_options.c
@@ -270,9 +270,8 @@ static void ami_gui_opts_array_to_list(struct List *list, const char *array[], i
node = AllocChooserNode(CNA_Text, array[i], TAG_DONE);
break;
case NSA_LIST_RADIO:
- /* Note: RBNA_Labels is RBNA_Label in OS4
- * Also note: These labels don't work (FIXME) */
- node = AllocRadioButtonNode(RBNA_Labels, array[i], TAG_DONE);
+ /* Note: RBNA_Labels is RBNA_Label in OS4 */
+ node = AllocRadioButtonNode(0, RBNA_Labels, array[i], TAG_DONE);
break;
default:
break;
@@ -1107,8 +1106,8 @@ void ami_gui_opts_open(void)
GA_ID, GID_OPTS_DPI_Y,
GA_RelVerify, TRUE,
INTEGER_Number, nsoption_int(screen_ydpi),
- INTEGER_Minimum, 60,
- INTEGER_Maximum, 150,
+ INTEGER_Minimum, 20,
+ INTEGER_Maximum, 200,
INTEGER_Arrows, TRUE,
GA_Disabled, nsoption_bool(bitmap_fonts),
IntegerEnd,
@@ -1748,7 +1747,7 @@ static void ami_gui_opts_use(bool save)
switch(data)
{
case 0:
- nsoption_set_charp(pubscreen_name, strdup("\0"));
+ nsoption_set_charp(pubscreen_name, NULL);
break;
case 1:
diff --git a/frontends/amiga/history.c b/frontends/amiga/history.c
index 7fc1ec333..e724f3e70 100644
--- a/frontends/amiga/history.c
+++ b/frontends/amiga/history.c
@@ -438,7 +438,7 @@ nserror ami_history_global_present(void)
res = ami_history_global_create_window(ncwin);
if (res != NSERROR_OK) {
- LOG("SSL UI builder init failed");
+ NSLOG(netsurf, INFO, "SSL UI builder init failed");
ami_utf8_free(ncwin->core.wintitle);
free(ncwin);
return res;
diff --git a/frontends/amiga/history_local.c b/frontends/amiga/history_local.c
index c293f5909..0ae9cc040 100644
--- a/frontends/amiga/history_local.c
+++ b/frontends/amiga/history_local.c
@@ -261,7 +261,7 @@ nserror ami_history_local_present(struct gui_window *gw)
res = ami_history_local_create_window(ncwin);
if (res != NSERROR_OK) {
- LOG("SSL UI builder init failed");
+ NSLOG(netsurf, INFO, "SSL UI builder init failed");
ami_utf8_free(ncwin->core.wintitle);
free(ncwin);
return res;
diff --git a/frontends/amiga/hotlist.c b/frontends/amiga/hotlist.c
index c0a6b6f58..c7efe9148 100644
--- a/frontends/amiga/hotlist.c
+++ b/frontends/amiga/hotlist.c
@@ -563,7 +563,7 @@ nserror ami_hotlist_present(void)
res = ami_hotlist_create_window(ncwin);
if (res != NSERROR_OK) {
- LOG("SSL UI builder init failed");
+ NSLOG(netsurf, INFO, "SSL UI builder init failed");
ami_utf8_free(ncwin->core.wintitle);
free(ncwin);
return res;
diff --git a/frontends/amiga/icon.c b/frontends/amiga/icon.c
index 9de040d37..582d355b6 100644
--- a/frontends/amiga/icon.c
+++ b/frontends/amiga/icon.c
@@ -155,7 +155,7 @@ bool amiga_icon_convert(struct content *c)
if(filename == NULL)
{
msg_data.error = messages_get("NoMemory");
- content_broadcast(c, CONTENT_MSG_ERROR, msg_data);
+ content_broadcast(c, CONTENT_MSG_ERROR, &msg_data);
return false;
}
@@ -167,7 +167,7 @@ bool amiga_icon_convert(struct content *c)
if(dobj == NULL)
{
msg_data.error = messages_get("NoMemory");
- content_broadcast(c, CONTENT_MSG_ERROR, msg_data);
+ content_broadcast(c, CONTENT_MSG_ERROR, &msg_data);
return false;
}
@@ -187,14 +187,14 @@ bool amiga_icon_convert(struct content *c)
icon_c->bitmap = amiga_bitmap_create(width, height, BITMAP_NEW);
if (!icon_c->bitmap) {
msg_data.error = messages_get("NoMemory");
- content_broadcast(c, CONTENT_MSG_ERROR, msg_data);
+ content_broadcast(c, CONTENT_MSG_ERROR, &msg_data);
if(dobj) FreeDiskObject(dobj);
return false;
}
imagebuf = (ULONG *) amiga_bitmap_get_buffer(icon_c->bitmap);
if (!imagebuf) {
msg_data.error = messages_get("NoMemory");
- content_broadcast(c, CONTENT_MSG_ERROR, msg_data);
+ content_broadcast(c, CONTENT_MSG_ERROR, &msg_data);
if(dobj) FreeDiskObject(dobj);
return false;
}
diff --git a/frontends/amiga/libs.c b/frontends/amiga/libs.c
index 30694542c..305818076 100644
--- a/frontends/amiga/libs.c
+++ b/frontends/amiga/libs.c
@@ -23,6 +23,7 @@
#include "utils/utils.h"
#include "utils/log.h"
+#include <proto/dos.h>
#include <proto/exec.h>
#include <proto/intuition.h>
#include <proto/utility.h>
@@ -56,11 +57,11 @@
#ifdef __amigaos4__
#define AMINS_LIB_OPEN(LIB, LIBVER, PREFIX, INTERFACE, INTVER, FAIL) \
- LOG("Opening %s v%d", LIB, LIBVER); \
+ NSLOG(netsurf, INFO, "Opening %s v%d", LIB, LIBVER); \
if((PREFIX##Base = (struct PREFIX##Base *)OpenLibrary(LIB, LIBVER))) { \
I##PREFIX = (struct PREFIX##IFace *)GetInterface((struct Library *)PREFIX##Base, INTERFACE, INTVER, NULL); \
if(I##PREFIX == NULL) { \
- LOG("Failed to get %s interface v%d of %s", INTERFACE, INTVER, LIB); \
+ NSLOG(netsurf, INFO, "Failed to get %s interface v%d of %s", INTERFACE, INTVER, LIB); \
AMINS_LIB_CLOSE(PREFIX) \
if(FAIL == true) { \
STRPTR error = ASPrintf("Unable to open interface %s v%d\nof %s v%ld (fatal error - not an OS4 lib?)", INTERFACE, INTVER, LIB, LIBVER); \
@@ -70,7 +71,7 @@
} \
} \
} else { \
- LOG("Failed to open %s v%d", LIB, LIBVER); \
+ NSLOG(netsurf, INFO, "Failed to open %s v%d", LIB, LIBVER); \
if(FAIL == true) { \
STRPTR error = ASPrintf("Unable to open %s v%ld (fatal error)", LIB, LIBVER); \
ami_misc_fatal_error(error); \
@@ -90,13 +91,13 @@
struct PREFIX##IFace *I##PREFIX = NULL;
#define AMINS_CLASS_OPEN(CLASS, CLASSVER, PREFIX, CLASSGET, NEEDINTERFACE) \
- LOG("Opening %s v%d", CLASS, CLASSVER); \
+ NSLOG(netsurf, INFO, "Opening %s v%d", CLASS, CLASSVER); \
if((PREFIX##Base = OpenClass(CLASS, CLASSVER, &PREFIX##Class))) { \
if(NEEDINTERFACE == true) { \
- LOG(" + interface"); \
+ NSLOG(netsurf, INFO, " + interface"); \
I##PREFIX = (struct PREFIX##IFace *)GetInterface((struct Library *)PREFIX##Base, "main", 1, NULL); \
if(I##PREFIX == NULL) { \
- LOG("Failed to get main interface v1 of %s", CLASS); \
+ NSLOG(netsurf, INFO, "Failed to get main interface v1 of %s", CLASS); \
} \
} \
} \
@@ -118,10 +119,10 @@
#else
#define AMINS_LIB_OPEN(LIB, LIBVER, PREFIX, INTERFACE, INTVER, FAIL) \
- LOG("Opening %s v%d", LIB, LIBVER); \
+ NSLOG(netsurf, INFO, "Opening %s v%d", LIB, LIBVER); \
if((PREFIX##Base = (struct PREFIX##Base *)OpenLibrary(LIB, LIBVER))) { \
} else { \
- LOG("Failed to open %s v%d", LIB, LIBVER); \
+ NSLOG(netsurf, INFO, "Failed to open %s v%d", LIB, LIBVER); \
if(FAIL == true) { \
STRPTR error = ASPrintf("Unable to open %s v%d (fatal error)", LIB, LIBVER); \
ami_misc_fatal_error(error); \
@@ -137,7 +138,7 @@
struct PREFIX##Base *PREFIX##Base = NULL;
#define AMINS_CLASS_OPEN(CLASS, CLASSVER, PREFIX, CLASSGET, NEEDINTERFACE) \
- LOG("Opening %s v%d", CLASS, CLASSVER); \
+ NSLOG(netsurf, INFO, "Opening %s v%d", CLASS, CLASSVER); \
if((PREFIX##Base = OpenLibrary(CLASS, CLASSVER))) { \
PREFIX##Class = CLASSGET##_GetClass(); \
} \
@@ -219,6 +220,7 @@ bool ami_libs_open(void)
AMINS_LIB_OPEN("asl.library", 37, Asl, "main", 1, true)
AMINS_LIB_OPEN("datatypes.library", 39, DataTypes, "main", 1, true)
AMINS_LIB_OPEN("diskfont.library", 40, Diskfont, "main", 1, true)
+ AMINS_LIB_OPEN("dos.library", 37, DOS, "main", 1, true)
AMINS_LIB_OPEN("gadtools.library", 37, GadTools, "main", 1, true)
AMINS_LIB_OPEN("graphics.library", 40, Graphics, "main", 1, true)
AMINS_LIB_OPEN("icon.library", 44, Icon, "main", 1, true)
@@ -321,6 +323,7 @@ void ami_libs_close(void)
AMINS_LIB_CLOSE(Asl)
AMINS_LIB_CLOSE(DataTypes)
AMINS_LIB_CLOSE(Diskfont)
+ AMINS_LIB_CLOSE(DOS)
AMINS_LIB_CLOSE(GadTools)
AMINS_LIB_CLOSE(Graphics)
AMINS_LIB_CLOSE(Icon)
diff --git a/frontends/amiga/memory.c b/frontends/amiga/memory.c
index d371d2585..35ca9697f 100755
--- a/frontends/amiga/memory.c
+++ b/frontends/amiga/memory.c
@@ -50,23 +50,38 @@ void *ami_memory_clear_alloc(size_t size, UBYTE value)
static int ami_memory_slab_usage_cb(const struct __slab_usage_information * sui)
{
if(sui->sui_slab_index <= 1) {
- LOG("clib2 slab usage:");
- LOG(" The size of all slabs, in bytes: %ld", sui->sui_slab_size);
- LOG(" Number of allocations which are not managed by slabs: %ld",
- sui->sui_num_single_allocations);
- LOG(" Total number of bytes allocated for memory not managed by slabs: %ld",
- sui->sui_total_single_allocation_size);
- LOG(" Number of slabs currently in play: %ld", sui->sui_num_slabs);
- LOG(" Number of currently unused slabs: %ld", sui->sui_num_empty_slabs);
- LOG(" Number of slabs in use which are completely filled with data: %ld",
- sui->sui_num_full_slabs);
- LOG(" Total number of bytes allocated for all slabs: %ld",
- sui->sui_total_slab_allocation_size);
+ NSLOG(netsurf, INFO, "clib2 slab usage:");
+ NSLOG(netsurf, INFO,
+ " The size of all slabs, in bytes: %ld",
+ sui->sui_slab_size);
+ NSLOG(netsurf, INFO,
+ " Number of allocations which are not managed by slabs: %ld",
+ sui->sui_num_single_allocations);
+ NSLOG(netsurf, INFO,
+ " Total number of bytes allocated for memory not managed by slabs: %ld",
+ sui->sui_total_single_allocation_size);
+ NSLOG(netsurf, INFO,
+ " Number of slabs currently in play: %ld",
+ sui->sui_num_slabs);
+ NSLOG(netsurf, INFO,
+ " Number of currently unused slabs: %ld",
+ sui->sui_num_empty_slabs);
+ NSLOG(netsurf, INFO,
+ " Number of slabs in use which are completely filled with data: %ld",
+ sui->sui_num_full_slabs);
+ NSLOG(netsurf, INFO,
+ " Total number of bytes allocated for all slabs: %ld",
+ sui->sui_total_slab_allocation_size);
}
- LOG("Slab %d", sui->sui_slab_index);
- LOG(" Memory chunk size managed by this slab: %ld", sui->sui_chunk_size);
- LOG(" Number of memory chunks that fit in this slab: %ld", sui->sui_num_chunks);
- LOG(" Number of memory chunks used in this slab: %ld", sui->sui_num_chunks_used);
+ NSLOG(netsurf, INFO, "Slab %d", sui->sui_slab_index);
+ NSLOG(netsurf, INFO, " Memory chunk size managed by this slab: %ld",
+ sui->sui_chunk_size);
+ NSLOG(netsurf, INFO,
+ " Number of memory chunks that fit in this slab: %ld",
+ sui->sui_num_chunks);
+ NSLOG(netsurf, INFO,
+ " Number of memory chunks used in this slab: %ld",
+ sui->sui_num_chunks_used);
return 0;
}
@@ -74,16 +89,20 @@ static int ami_memory_slab_usage_cb(const struct __slab_usage_information * sui)
static int ami_memory_slab_alloc_cb(const struct __slab_allocation_information *sai)
{
if(sai->sai_allocation_index <= 1) {
- LOG("clib2 allocation usage:");
- LOG(" Number of allocations which are not managed by slabs: %ld",
- sai->sai_num_single_allocations);
- LOG(" Total number of bytes allocated for memory not managed by slabs: %ld",
- sai->sai_total_single_allocation_size);
+ NSLOG(netsurf, INFO, "clib2 allocation usage:");
+ NSLOG(netsurf, INFO,
+ " Number of allocations which are not managed by slabs: %ld",
+ sai->sai_num_single_allocations);
+ NSLOG(netsurf, INFO,
+ " Total number of bytes allocated for memory not managed by slabs: %ld",
+ sai->sai_total_single_allocation_size);
}
- LOG("Alloc %d", sai->sai_allocation_index);
- LOG(" Size of this allocation, as requested: %ld", sai->sai_allocation_size);
- LOG(" Total size of this allocation, including management data: %ld",
- sai->sai_total_allocation_size);
+ NSLOG(netsurf, INFO, "Alloc %d", sai->sai_allocation_index);
+ NSLOG(netsurf, INFO, " Size of this allocation, as requested: %ld",
+ sai->sai_allocation_size);
+ NSLOG(netsurf, INFO,
+ " Total size of this allocation, including management data: %ld",
+ sai->sai_total_allocation_size);
return 0;
}
@@ -111,13 +130,13 @@ void ami_memory_slab_dump(BPTR fh)
static void ami_memory_low_mem_handler(void *p)
{
if(low_mem_status == PURGE_STEP1) {
- LOG("Purging llcache");
+ NSLOG(netsurf, INFO, "Purging llcache");
llcache_clean(true);
low_mem_status = PURGE_DONE_STEP1;
}
if(low_mem_status == PURGE_STEP2) {
- LOG("Purging unused slabs");
+ NSLOG(netsurf, INFO, "Purging unused slabs");
__free_unused_slabs();
low_mem_status = PURGE_DONE_STEP2;
}
diff --git a/frontends/amiga/menu.c b/frontends/amiga/menu.c
index 65265c34d..1f3f981ea 100644
--- a/frontends/amiga/menu.c
+++ b/frontends/amiga/menu.c
@@ -263,7 +263,9 @@ static int ami_menu_layout_mc_recursive(Object *menu_parent, struct ami_menu_dat
TAG_DONE);
}
- //LOG("Adding item %p ID %d (%s) to parent %p", menu_item, j, md[j]->menulab, menu_parent);
+ NSLOG(netsurf, DEEPDEBUG,
+ "Adding item %p ID %d (%s) to parent %p",
+ menu_item, j, md[j]->menulab, menu_parent);
IDoMethod(menu_parent, OM_ADDMEMBER, menu_item);
continue;
} else if (md[j]->menutype > level) {
diff --git a/frontends/amiga/misc.c b/frontends/amiga/misc.c
index 5ca4f906a..532d2f182 100755
--- a/frontends/amiga/misc.c
+++ b/frontends/amiga/misc.c
@@ -46,7 +46,7 @@ static LONG ami_misc_req(const char *message, uint32 type)
{
LONG ret = 0;
- LOG("%s", message);
+ NSLOG(netsurf, INFO, "%s", message);
#ifdef __amigaos4__
ret = TimedDosRequesterTags(
TDR_TitleString, messages_get("NetSurf"),
diff --git a/frontends/amiga/os3support.c b/frontends/amiga/os3support.c
index 6dc95795f..645496b73 100644
--- a/frontends/amiga/os3support.c
+++ b/frontends/amiga/os3support.c
@@ -216,13 +216,13 @@ struct OutlineFont *OpenOutlineFont(STRPTR fileName, struct List *list, ULONG fl
fh = Open(fontpath, MODE_OLDFILE);
if(fh == 0) {
- LOG("Unable to open FONT %s", fontpath);
+ NSLOG(netsurf, INFO, "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);
+ NSLOG(netsurf, INFO, "Unable to read FONT %s", fontpath);
FreeVec(fontpath);
Close(fh);
return NULL;
@@ -231,7 +231,7 @@ struct OutlineFont *OpenOutlineFont(STRPTR fileName, struct List *list, ULONG fl
Close(fh);
if(fch.fch_FileID != OFCH_ID) {
- LOG("%s is not an outline font!", fontpath);
+ NSLOG(netsurf, INFO, "%s is not an outline font!", fontpath);
FreeVec(fontpath);
return NULL;
}
@@ -242,7 +242,7 @@ struct OutlineFont *OpenOutlineFont(STRPTR fileName, struct List *list, ULONG fl
if(p) *p = '.';
if(fh == 0) {
- LOG("Unable to open OTAG %s", otagpath);
+ NSLOG(netsurf, INFO, "Unable to open OTAG %s", otagpath);
FreeVec(otagpath);
return NULL;
}
@@ -250,7 +250,7 @@ struct OutlineFont *OpenOutlineFont(STRPTR fileName, struct List *list, ULONG fl
size = GetFileSize(fh);
buffer = (UBYTE *)malloc(size);
if(buffer == NULL) {
- LOG("Unable to allocate memory");
+ NSLOG(netsurf, INFO, "Unable to allocate memory");
Close(fh);
FreeVec(otagpath);
return NULL;
@@ -262,7 +262,7 @@ struct OutlineFont *OpenOutlineFont(STRPTR fileName, struct List *list, ULONG fl
/* The first tag is supposed to be OT_FileIdent and should equal 'size' */
struct TagItem *tag = (struct TagItem *)buffer;
if((tag->ti_Tag != OT_FileIdent) || (tag->ti_Data != (ULONG)size)) {
- LOG("Invalid OTAG file");
+ NSLOG(netsurf, INFO, "Invalid OTAG file");
free(buffer);
FreeVec(otagpath);
return NULL;
@@ -277,10 +277,10 @@ struct OutlineFont *OpenOutlineFont(STRPTR fileName, struct List *list, ULONG fl
/* Find OT_Engine and open the font engine */
if(ti = FindTagItem(OT_Engine, buffer)) {
- LOG("Using font engine %s", ti->ti_Data);
+ NSLOG(netsurf, INFO, "Using font engine %s", ti->ti_Data);
fname = ASPrintf("%s.library", ti->ti_Data);
} else {
- LOG("Cannot find OT_Engine tag");
+ NSLOG(netsurf, INFO, "Cannot find OT_Engine tag");
free(buffer);
FreeVec(otagpath);
return NULL;
@@ -289,7 +289,7 @@ struct OutlineFont *OpenOutlineFont(STRPTR fileName, struct List *list, ULONG fl
BulletBase = (struct BulletBase *)OpenLibrary(fname, 0L);
if(BulletBase == NULL) {
- LOG("Unable to open font engine %s", fname);
+ NSLOG(netsurf, INFO, "Unable to open font engine %s", fname);
free(buffer);
FreeVec(fname);
FreeVec(otagpath);
@@ -405,9 +405,10 @@ ULONG RefreshSetGadgetAttrsA(struct Gadget *g, struct Window *w, struct Requeste
ULONG retval;
BOOL changedisabled = FALSE;
BOOL disabled;
+ struct TagItem *ti;
if (w) {
- if (FindTagItem(GA_Disabled,tags)) {
+ if ((ti = FindTagItem(GA_Disabled,tags)) && (ti->ti_Data != FALSE)) {
changedisabled = TRUE;
disabled = g->Flags & GFLG_DISABLED;
}
diff --git a/frontends/amiga/plotters.c b/frontends/amiga/plotters.c
index e31d470a6..7c5df4678 100644
--- a/frontends/amiga/plotters.c
+++ b/frontends/amiga/plotters.c
@@ -53,15 +53,6 @@
#include "amiga/rtg.h"
#include "amiga/utf8.h"
-/* set AMI_PLOTTER_DEBUG to 0 for no debugging, 1 for debugging */
-//#define AMI_PLOTTER_DEBUG 1
-
-#ifdef AMI_PLOTTER_DEBUG
-#define PLOT_LOG(x...) LOG(x)
-#else
-#define PLOT_LOG(x...) ((void) 0)
-#endif
-
HOOKF(void, ami_bitmap_tile_hook, struct RastPort *, rp, struct BackFillMessage *);
struct bfbitmap {
@@ -119,9 +110,6 @@ static bool palette_mapped = true; /* palette-mapped state for the screen */
*/
#define AREA_SIZE 25000
-/* Define the below to get additional debug */
-#undef AMI_PLOTTER_DEBUG
-
struct gui_globals *ami_plot_ra_alloc(ULONG width, ULONG height, bool force32bit, bool alloc_pen_list)
{
/* init shared bitmaps */
@@ -131,7 +119,7 @@ struct gui_globals *ami_plot_ra_alloc(ULONG width, ULONG height, bool force32bit
struct gui_globals *gg = malloc(sizeof(struct gui_globals));
if(force32bit == false) depth = GetBitMapAttr(scrn->RastPort.BitMap, BMA_DEPTH);
- LOG("Screen depth = %d", depth);
+ NSLOG(netsurf, INFO, "Screen depth = %d", depth);
#ifdef __amigaos4__
if(depth < 16) {
@@ -241,7 +229,8 @@ struct gui_globals *ami_plot_ra_alloc(ULONG width, ULONG height, bool force32bit
gg->open_num = -1;
init_layers_count++;
- LOG("Layer initialised (total: %d)", init_layers_count);
+ NSLOG(netsurf, INFO, "Layer initialised (total: %d)",
+ init_layers_count);
return gg;
}
@@ -328,7 +317,8 @@ static ULONG ami_plot_obtain_pen(struct MinList *shared_pens, ULONG colr)
(colr & 0x00ff0000) << 8,
NULL);
- if(pen == -1) LOG("WARNING: Cannot allocate pen for ABGR:%lx", colr);
+ if(pen == -1) NSLOG(netsurf, INFO,
+ "WARNING: Cannot allocate pen for ABGR:%lx", colr);
if((shared_pens != NULL) && (pool_pens != NULL)) {
if((node = (struct ami_plot_pen *)ami_memory_itempool_alloc(pool_pens, sizeof(struct ami_plot_pen)))) {
@@ -436,7 +426,7 @@ static void ami_arc_gfxlib(struct RastPort *rp, int x, int y, int radius, int an
static nserror
ami_bitmap(struct gui_globals *glob, int x, int y, int width, int height, struct bitmap *bitmap)
{
- PLOT_LOG("[ami_plotter] Entered ami_bitmap()");
+ NSLOG(plot, DEEPDEBUG, "[ami_plotter] Entered ami_bitmap()");
struct BitMap *tbm;
@@ -456,7 +446,7 @@ ami_bitmap(struct gui_globals *glob, int x, int y, int width, int height, struct
return NSERROR_OK;
}
- PLOT_LOG("[ami_plotter] ami_bitmap() got native bitmap");
+ NSLOG(plot, DEEPDEBUG, "[ami_plotter] ami_bitmap() got native bitmap");
#ifdef __amigaos4__
if (__builtin_expect((GfxBase->LibNode.lib_Version >= 53) &&
@@ -615,7 +605,7 @@ ami_clip(const struct redraw_context *ctx, const struct rect *clip)
struct gui_globals *glob = (struct gui_globals *)ctx->priv;
struct Region *reg = NULL;
- PLOT_LOG("[ami_plotter] Entered ami_clip()");
+ NSLOG(plot, DEEPDEBUG, "[ami_plotter] Entered ami_clip()");
if (glob->rp->Layer) {
reg = NewRegion();
@@ -659,7 +649,7 @@ ami_arc(const struct redraw_context *ctx,
const plot_style_t *style,
int x, int y, int radius, int angle1, int angle2)
{
- PLOT_LOG("[ami_plotter] Entered ami_arc()");
+ NSLOG(plot, DEEPDEBUG, "[ami_plotter] Entered ami_arc()");
struct gui_globals *glob = (struct gui_globals *)ctx->priv;
@@ -691,7 +681,7 @@ ami_disc(const struct redraw_context *ctx,
const plot_style_t *style,
int x, int y, int radius)
{
- PLOT_LOG("[ami_plotter] Entered ami_disc()");
+ NSLOG(plot, DEEPDEBUG, "[ami_plotter] Entered ami_disc()");
struct gui_globals *glob = (struct gui_globals *)ctx->priv;
@@ -726,7 +716,7 @@ ami_line(const struct redraw_context *ctx,
const plot_style_t *style,
const struct rect *line)
{
- PLOT_LOG("[ami_plotter] Entered ami_line()");
+ NSLOG(plot, DEEPDEBUG, "[ami_plotter] Entered ami_line()");
struct gui_globals *glob = (struct gui_globals *)ctx->priv;
@@ -778,7 +768,7 @@ ami_rectangle(const struct redraw_context *ctx,
const plot_style_t *style,
const struct rect *rect)
{
- PLOT_LOG("[ami_plotter] Entered ami_rectangle()");
+ NSLOG(plot, DEEPDEBUG, "[ami_plotter] Entered ami_rectangle()");
struct gui_globals *glob = (struct gui_globals *)ctx->priv;
@@ -842,24 +832,24 @@ ami_polygon(const struct redraw_context *ctx,
const int *p,
unsigned int n)
{
- PLOT_LOG("[ami_plotter] Entered ami_polygon()");
+ NSLOG(plot, DEEPDEBUG, "[ami_plotter] Entered ami_polygon()");
struct gui_globals *glob = (struct gui_globals *)ctx->priv;
ami_plot_setapen(glob, glob->rp, style->fill_colour);
if (AreaMove(glob->rp,p[0],p[1]) == -1) {
- LOG("AreaMove: vector list full");
+ NSLOG(netsurf, INFO, "AreaMove: vector list full");
}
for (uint32 k = 1; k < n; k++) {
if (AreaDraw(glob->rp,p[k*2],p[(k*2)+1]) == -1) {
- LOG("AreaDraw: vector list full");
+ NSLOG(netsurf, INFO, "AreaDraw: vector list full");
}
}
if (AreaEnd(glob->rp) == -1) {
- LOG("AreaEnd: error");
+ NSLOG(netsurf, INFO, "AreaEnd: error");
}
return NSERROR_OK;
@@ -891,7 +881,7 @@ ami_path(const struct redraw_context *ctx,
unsigned int i;
struct bez_point start_p = {0, 0}, cur_p = {0, 0}, p_a, p_b, p_c, p_r;
- PLOT_LOG("[ami_plotter] Entered ami_path()");
+ NSLOG(plot, DEEPDEBUG, "[ami_plotter] Entered ami_path()");
struct gui_globals *glob = (struct gui_globals *)ctx->priv;
@@ -900,7 +890,7 @@ ami_path(const struct redraw_context *ctx,
}
if (p[0] != PLOTTER_PATH_MOVE) {
- LOG("Path does not start with move");
+ NSLOG(netsurf, INFO, "Path does not start with move");
return NSERROR_INVALID;
}
@@ -922,7 +912,8 @@ ami_path(const struct redraw_context *ctx,
if (p[i] == PLOTTER_PATH_MOVE) {
if (pstyle->fill_colour != NS_TRANSPARENT) {
if (AreaMove(glob->rp, p[i+1], p[i+2]) == -1) {
- LOG("AreaMove: vector list full");
+ NSLOG(netsurf, INFO,
+ "AreaMove: vector list full");
}
} else {
Move(glob->rp, p[i+1], p[i+2]);
@@ -936,7 +927,7 @@ ami_path(const struct redraw_context *ctx,
} else if (p[i] == PLOTTER_PATH_CLOSE) {
if (pstyle->fill_colour != NS_TRANSPARENT) {
if (AreaEnd(glob->rp) == -1) {
- LOG("AreaEnd: error");
+ NSLOG(netsurf, INFO, "AreaEnd: error");
}
} else {
Draw(glob->rp, start_p.x, start_p.y);
@@ -945,7 +936,8 @@ ami_path(const struct redraw_context *ctx,
} else if (p[i] == PLOTTER_PATH_LINE) {
if (pstyle->fill_colour != NS_TRANSPARENT) {
if (AreaDraw(glob->rp, p[i+1], p[i+2]) == -1) {
- LOG("AreaDraw: vector list full");
+ NSLOG(netsurf, INFO,
+ "AreaDraw: vector list full");
}
} else {
Draw(glob->rp, p[i+1], p[i+2]);
@@ -965,7 +957,8 @@ ami_path(const struct redraw_context *ctx,
ami_bezier(&cur_p, &p_a, &p_b, &p_c, t, &p_r);
if (pstyle->fill_colour != NS_TRANSPARENT) {
if (AreaDraw(glob->rp, p_r.x, p_r.y) == -1) {
- LOG("AreaDraw: vector list full");
+ NSLOG(netsurf, INFO,
+ "AreaDraw: vector list full");
}
} else {
Draw(glob->rp, p_r.x, p_r.y);
@@ -975,7 +968,7 @@ ami_path(const struct redraw_context *ctx,
cur_p.y = p_c.y;
i += 7;
} else {
- LOG("bad path command %f", p[i]);
+ NSLOG(netsurf, INFO, "bad path command %f", p[i]);
/* End path for safety if using Area commands */
if (pstyle->fill_colour != NS_TRANSPARENT) {
AreaEnd(glob->rp);
@@ -1032,7 +1025,7 @@ ami_bitmap_tile(const struct redraw_context *ctx,
bool repeat_x = (flags & BITMAPF_REPEAT_X);
bool repeat_y = (flags & BITMAPF_REPEAT_Y);
- PLOT_LOG("[ami_plotter] Entered ami_bitmap_tile()");
+ NSLOG(plot, DEEPDEBUG, "[ami_plotter] Entered ami_bitmap_tile()");
struct gui_globals *glob = (struct gui_globals *)ctx->priv;
@@ -1149,7 +1142,7 @@ ami_text(const struct redraw_context *ctx,
const char *text,
size_t length)
{
- PLOT_LOG("[ami_plotter] Entered ami_text()");
+ NSLOG(plot, DEEPDEBUG, "[ami_plotter] Entered ami_text()");
struct gui_globals *glob = (struct gui_globals *)ctx->priv;
diff --git a/frontends/amiga/plugin_hack.c b/frontends/amiga/plugin_hack.c
index 2327f9190..4fd1f03f7 100644
--- a/frontends/amiga/plugin_hack.c
+++ b/frontends/amiga/plugin_hack.c
@@ -82,7 +82,8 @@ nserror amiga_plugin_hack_init(void)
if(node)
{
- LOG("plugin_hack registered %s", lwc_string_data(type));
+ NSLOG(netsurf, INFO, "plugin_hack registered %s",
+ lwc_string_data(type));
error = content_factory_register_handler(
lwc_string_data(type),
@@ -123,7 +124,7 @@ nserror amiga_plugin_hack_create(const content_handler *handler,
bool amiga_plugin_hack_convert(struct content *c)
{
- LOG("amiga_plugin_hack_convert");
+ NSLOG(netsurf, INFO, "amiga_plugin_hack_convert");
content_set_ready(c);
content_set_done(c);
@@ -137,7 +138,7 @@ void amiga_plugin_hack_destroy(struct content *c)
{
amiga_plugin_hack_content *plugin = (amiga_plugin_hack_content *) c;
- LOG("amiga_plugin_hack_destroy %p", plugin);
+ NSLOG(netsurf, INFO, "amiga_plugin_hack_destroy %p", plugin);
return;
}
@@ -155,7 +156,7 @@ bool amiga_plugin_hack_redraw(struct content *c,
struct rect rect;
nserror res;
- LOG("amiga_plugin_hack_redraw");
+ NSLOG(netsurf, INFO, "amiga_plugin_hack_redraw");
rect.x0 = data->x;
rect.y0 = data->y;
@@ -187,7 +188,8 @@ bool amiga_plugin_hack_redraw(struct content *c,
void amiga_plugin_hack_open(struct content *c, struct browser_window *bw,
struct content *page, struct object_params *params)
{
- LOG("amiga_plugin_hack_open %s", nsurl_access(content_get_url(c)));
+ NSLOG(netsurf, INFO, "amiga_plugin_hack_open %s",
+ nsurl_access(content_get_url(c)));
if(c)
{
@@ -201,13 +203,13 @@ void amiga_plugin_hack_open(struct content *c, struct browser_window *bw,
void amiga_plugin_hack_close(struct content *c)
{
- LOG("amiga_plugin_hack_close");
+ NSLOG(netsurf, INFO, "amiga_plugin_hack_close");
return;
}
void amiga_plugin_hack_reformat(struct content *c, int width, int height)
{
- LOG("amiga_plugin_hack_reformat");
+ NSLOG(netsurf, INFO, "amiga_plugin_hack_reformat");
c->width = width;
c->height = height;
@@ -220,7 +222,7 @@ nserror amiga_plugin_hack_clone(const struct content *old, struct content **newc
amiga_plugin_hack_content *plugin;
nserror error;
- LOG("amiga_plugin_hack_clone");
+ NSLOG(netsurf, INFO, "amiga_plugin_hack_clone");
plugin = calloc(1, sizeof(amiga_plugin_hack_content));
if (plugin == NULL)
@@ -267,7 +269,7 @@ void amiga_plugin_hack_execute(struct hlcache_handle *c)
if(full_cmd)
{
#ifdef __amigaos4__
- LOG("Attempting to execute %s", full_cmd);
+ NSLOG(netsurf, INFO, "Attempting to execute %s", full_cmd);
in = Open("NIL:", MODE_OLDFILE);
out = Open("NIL:", MODE_NEWFILE);
diff --git a/frontends/amiga/schedule.c b/frontends/amiga/schedule.c
index bfafe9c88..043edc7fe 100644
--- a/frontends/amiga/schedule.c
+++ b/frontends/amiga/schedule.c
@@ -218,22 +218,25 @@ static void ami_schedule_dump(void)
GetSysTime(&tv);
Amiga2Date(tv.Seconds, &clockdata);
- LOG("Current time = %d-%d-%d %d:%d:%d.%d", clockdata.mday, clockdata.month, clockdata.year,
- clockdata.hour, clockdata.min, clockdata.sec, tv.Microseconds);
- LOG("Events remaining in queue:");
+ NSLOG(netsurf, INFO, "Current time = %d-%d-%d %d:%d:%d.%d",
+ clockdata.mday, clockdata.month, clockdata.year,
+ clockdata.hour, clockdata.min, clockdata.sec, tv.Microseconds);
+ NSLOG(netsurf, INFO, "Events remaining in queue:");
iterator = pblHeapIterator(schedule_list);
while ((nscb = pblIteratorNext(iterator)) != -1)
{
Amiga2Date(nscb->tv.Seconds, &clockdata);
- LOG("nscb: %p, at %d-%d-%d %d:%d:%d.%d, callback: %p, %p",
- nscb, clockdata.mday, clockdata.month, clockdata.year, clockdata.hour, clockdata.min, clockdata.sec,
- nscb->tv.Microseconds, nscb->callback, nscb->p);
+ NSLOG(netsurf, INFO,
+ "nscb: %p, at %d-%d-%d %d:%d:%d.%d, callback: %p, %p",
+ nscb, clockdata.mday, clockdata.month, clockdata.year,
+ clockdata.hour, clockdata.min, clockdata.sec,
+ nscb->tv.Microseconds, nscb->callback, nscb->p);
if(CheckIO((struct IORequest *)nscb) == NULL) {
- LOG("-> ACTIVE");
+ NSLOG(netsurf, INFO, "-> ACTIVE");
} else {
- LOG("-> COMPLETE");
+ NSLOG(netsurf, INFO, "-> COMPLETE");
}
};
diff --git a/frontends/amiga/selectmenu.c b/frontends/amiga/selectmenu.c
index f3a11b67a..8a8614136 100644
--- a/frontends/amiga/selectmenu.c
+++ b/frontends/amiga/selectmenu.c
@@ -58,7 +58,8 @@ BOOL ami_selectmenu_is_safe(void)
BOOL popupmenu_lib_ok = FALSE;
if((PopupMenuBase = OpenLibrary("popupmenu.library", 53))) {
- LOG("popupmenu.library v%d.%d", PopupMenuBase->lib_Version, PopupMenuBase->lib_Revision);
+ NSLOG(netsurf, INFO, "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);
diff --git a/frontends/amiga/sslcert.c b/frontends/amiga/sslcert.c
index eeb34108a..136b918fc 100644
--- a/frontends/amiga/sslcert.c
+++ b/frontends/amiga/sslcert.c
@@ -317,7 +317,7 @@ nserror ami_cert_verify(struct nsurl *url,
res = ami_crtvrfy_create_window(ncwin);
if (res != NSERROR_OK) {
- LOG("SSL UI builder init failed");
+ NSLOG(netsurf, INFO, "SSL UI builder init failed");
ami_utf8_free(ncwin->core.wintitle);
ami_utf8_free(ncwin->sslerr);
ami_utf8_free(ncwin->sslaccept);
diff --git a/frontends/amiga/version.c b/frontends/amiga/version.c
index c3cd9e2b5..61fbd7176 100644
--- a/frontends/amiga/version.c
+++ b/frontends/amiga/version.c
@@ -25,7 +25,7 @@
* problems created by "0" not being a valid AmigaOS revision number.
*/
#define NETSURF_VERSION_MAJOR "3"
-#define NETSURF_VERSION_MINOR_EXTERNAL "7"
+#define NETSURF_VERSION_MINOR_EXTERNAL "8"
#if defined(CI_BUILD)
#define NETSURF_VERSION_MINOR CI_BUILD
#else
diff --git a/frontends/atari/Makefile b/frontends/atari/Makefile
index b4fb16ec1..a2f27e2f2 100644
--- a/frontends/atari/Makefile
+++ b/frontends/atari/Makefile
@@ -47,6 +47,7 @@ CFLAGS += -U__STRICT_ANSI__ -std=c99 -Dsmall -Dnsatari \
-D_BSD_SOURCE \
-D_XOPEN_SOURCE=600 \
-D_POSIX_C_SOURCE=200112L \
+ -DNSLOG_LEVEL_0x0010=NSLOG_LEVEL_INFO \
$(shell $(PKG_CONFIG) --cflags openssl ) \
$(shell $(PKG_CONFIG) --cflags libcurl )
diff --git a/frontends/atari/bitmap.c b/frontends/atari/bitmap.c
index cbb719586..ae42da837 100644
--- a/frontends/atari/bitmap.c
+++ b/frontends/atari/bitmap.c
@@ -81,7 +81,9 @@ static void *atari_bitmap_create_ex( int w, int h, short bpp, int rowstride, uns
{
struct bitmap * bitmap;
- LOG("width %d (rowstride: %d, bpp: %d), height %d, state %u", w, rowstride, bpp, h, state);
+ NSLOG(netsurf, INFO,
+ "width %d (rowstride: %d, bpp: %d), height %d, state %u", w,
+ rowstride, bpp, h, state);
if( rowstride == 0) {
rowstride = bpp * w;
@@ -107,10 +109,10 @@ static void *atari_bitmap_create_ex( int w, int h, short bpp, int rowstride, uns
} else {
free(bitmap);
bitmap=NULL;
- LOG("Out of memory!");
+ NSLOG(netsurf, INFO, "Out of memory!");
}
}
- LOG("bitmap %p", bitmap);
+ NSLOG(netsurf, INFO, "bitmap %p", bitmap);
return bitmap;
}
@@ -194,7 +196,7 @@ static unsigned char *bitmap_get_buffer(void *bitmap)
struct bitmap *bm = bitmap;
if (bitmap == NULL) {
- LOG("NULL bitmap!");
+ NSLOG(netsurf, INFO, "NULL bitmap!");
return NULL;
}
@@ -218,7 +220,7 @@ size_t atari_bitmap_get_rowstride(void *bitmap)
struct bitmap *bm = bitmap;
if (bitmap == NULL) {
- LOG("NULL bitmap!");
+ NSLOG(netsurf, INFO, "NULL bitmap!");
return 0;
}
return bm->rowstride;
@@ -231,7 +233,7 @@ void atari_bitmap_destroy(void *bitmap)
struct bitmap *bm = bitmap;
if (bitmap == NULL) {
- LOG("NULL bitmap!");
+ NSLOG(netsurf, INFO, "NULL bitmap!");
return;
}
@@ -272,11 +274,12 @@ static void bitmap_set_opaque(void *bitmap, bool opaque)
struct bitmap *bm = bitmap;
if (bitmap == NULL) {
- LOG("NULL bitmap!");
+ NSLOG(netsurf, INFO, "NULL bitmap!");
return;
}
- LOG("setting bitmap %p to %s", bm, opaque ? "opaque" : "transparent");
+ NSLOG(netsurf, INFO, "setting bitmap %p to %s", bm,
+ opaque ? "opaque" : "transparent");
bm->opaque = opaque;
}
@@ -293,7 +296,7 @@ static bool bitmap_test_opaque(void *bitmap)
struct bitmap *bm = bitmap;
if (bitmap == NULL) {
- LOG("NULL bitmap!");
+ NSLOG(netsurf, INFO, "NULL bitmap!");
return false;
}
@@ -305,11 +308,12 @@ static bool bitmap_test_opaque(void *bitmap)
while (tst-- > 0) {
if (bm->pixdata[(tst << 2) + 3] != 0xff) {
- LOG("bitmap %p has transparency", bm);
+ NSLOG(netsurf, INFO,
+ "bitmap %p has transparency", bm);
return false;
}
}
- LOG("bitmap %p is opaque", bm);
+ NSLOG(netsurf, INFO, "bitmap %p is opaque", bm);
return true;
}
@@ -320,7 +324,7 @@ bool atari_bitmap_get_opaque(void *bitmap)
struct bitmap *bm = bitmap;
if (bitmap == NULL) {
- LOG("NULL bitmap!");
+ NSLOG(netsurf, INFO, "NULL bitmap!");
return false;
}
@@ -334,7 +338,7 @@ int atari_bitmap_get_width(void *bitmap)
struct bitmap *bm = bitmap;
if (bitmap == NULL) {
- LOG("NULL bitmap!");
+ NSLOG(netsurf, INFO, "NULL bitmap!");
return 0;
}
@@ -348,7 +352,7 @@ int atari_bitmap_get_height(void *bitmap)
struct bitmap *bm = bitmap;
if (bitmap == NULL) {
- LOG("NULL bitmap!");
+ NSLOG(netsurf, INFO, "NULL bitmap!");
return 0;
}
return(bm->height);
diff --git a/frontends/atari/certview.c b/frontends/atari/certview.c
index 6950d31f8..80d18a059 100644
--- a/frontends/atari/certview.c
+++ b/frontends/atari/certview.c
@@ -81,7 +81,7 @@ static nserror atari_sslcert_viewer_init_phase2(struct core_window *cw,
assert(ssl_d);
- LOG("cw %p", cw);
+ NSLOG(netsurf, INFO, "cw %p", cw);
return(sslcert_viewer_init(cb_t, cw, ssl_d));
}
@@ -97,7 +97,7 @@ static void atari_sslcert_viewer_finish(struct core_window *cw)
/* This will also free the session data: */
sslcert_viewer_fini(cvwin->ssl_session_data);
- LOG("cw %p", cw);
+ NSLOG(netsurf, INFO, "cw %p", cw);
}
static void atari_sslcert_viewer_draw(struct core_window *cw, int x,
@@ -123,7 +123,7 @@ static void atari_sslcert_viewer_keypress(struct core_window *cw, uint32_t ucs4)
cvwin = (struct atari_sslcert_viewer_s *)atari_treeview_get_user_data(cw);
- LOG("ucs4: %"PRIu32, ucs4);
+ NSLOG(netsurf, INFO, "ucs4: %"PRIu32, ucs4);
sslcert_viewer_keypress(cvwin->ssl_session_data, ucs4);
}
@@ -150,14 +150,14 @@ static short handle_event(GUIWIN *win, EVMULT_OUT *ev_out, short msg[8])
short retval = 0;
OBJECT *toolbar;
- LOG("win %p", win);
+ NSLOG(netsurf, INFO, "win %p", win);
if(ev_out->emo_events & MU_MESAG){
switch (msg[0]) {
case WM_TOOLBAR:
toolbar = gemtk_obj_get_tree(TOOLBAR_SSL_CERT);
- LOG("CERTVIEWER WM_TOOLBAR");
+ NSLOG(netsurf, INFO, "CERTVIEWER WM_TOOLBAR");
tv = (struct core_window*) gemtk_wm_get_user_data(win);
assert(tv);
cvwin = (struct atari_sslcert_viewer_s *)
@@ -238,7 +238,7 @@ static void atari_sslcert_viewer_init(struct atari_sslcert_viewer_s * cvwin,
if (cvwin->tv == NULL) {
/* handle it properly, clean up previous allocs */
- LOG("Failed to allocate treeview");
+ NSLOG(netsurf, INFO, "Failed to allocate treeview");
return;
}
@@ -280,7 +280,7 @@ static void atari_sslcert_viewer_destroy(struct atari_sslcert_viewer_s * cvwin)
assert(cvwin->init);
assert(cvwin->window);
- LOG("cvwin %p", cvwin);
+ NSLOG(netsurf, INFO, "cvwin %p", cvwin);
if (atari_treeview_is_open(cvwin->tv))
atari_treeview_close(cvwin->tv);
@@ -289,5 +289,5 @@ static void atari_sslcert_viewer_destroy(struct atari_sslcert_viewer_s * cvwin)
cvwin->window = NULL;
atari_treeview_delete(cvwin->tv);
free(cvwin);
- LOG("done");
+ NSLOG(netsurf, INFO, "done");
}
diff --git a/frontends/atari/cookies.c b/frontends/atari/cookies.c
index 9045009fc..df2de0d4c 100644
--- a/frontends/atari/cookies.c
+++ b/frontends/atari/cookies.c
@@ -63,7 +63,7 @@ static nserror
atari_cookie_manager_init_phase2(struct core_window *cw,
struct core_window_callback_table *cb_t)
{
- LOG("cw %p",cw);
+ NSLOG(netsurf, INFO, "cw %p", cw);
return(cookie_manager_init(cb_t, cw));
}
@@ -71,7 +71,7 @@ atari_cookie_manager_init_phase2(struct core_window *cw,
static void
atari_cookie_manager_finish(struct core_window *cw)
{
- LOG("cw %p",cw);
+ NSLOG(netsurf, INFO, "cw %p", cw);
cookie_manager_fini();
}
@@ -89,7 +89,7 @@ atari_cookie_manager_draw(struct core_window *cw,
static void
atari_cookie_manager_keypress(struct core_window *cw, uint32_t ucs4)
{
- LOG("ucs4: %"PRIu32, ucs4);
+ NSLOG(netsurf, INFO, "ucs4: %"PRIu32, ucs4);
cookie_manager_keypress(ucs4);
}
@@ -108,13 +108,13 @@ static short handle_event(GUIWIN *win, EVMULT_OUT *ev_out, short msg[8])
{
short retval = 0;
- LOG("win %p", win);
+ NSLOG(netsurf, INFO, "win %p", win);
if (ev_out->emo_events & MU_MESAG) {
switch (msg[0]) {
case WM_TOOLBAR:
- LOG("WM_TOOLBAR");
+ NSLOG(netsurf, INFO, "WM_TOOLBAR");
break;
case WM_CLOSED:
@@ -158,7 +158,8 @@ void atari_cookie_manager_init(void)
if (atari_cookie_manager.tv == NULL) {
/* handle it properly, clean up previous allocs */
- LOG("Failed to allocate treeview");
+ NSLOG(netsurf, INFO,
+ "Failed to allocate treeview");
return;
}
@@ -209,7 +210,7 @@ void atari_cookie_manager_destroy(void)
atari_treeview_delete(atari_cookie_manager.tv);
atari_cookie_manager.init = false;
}
- LOG("done");
+ NSLOG(netsurf, INFO, "done");
}
diff --git a/frontends/atari/ctxmenu.c b/frontends/atari/ctxmenu.c
index e25d8e522..ef4f01ae2 100644
--- a/frontends/atari/ctxmenu.c
+++ b/frontends/atari/ctxmenu.c
@@ -288,7 +288,9 @@ void context_popup(struct gui_window * gw, short x, short y)
/* the GEMDOS cmdline contains the length of the commandline
in the first byte: */
cmdline[0] = (unsigned char)strlen(tempfile);
- LOG("Creating temporay source file: %s\n", tempfile);
+ NSLOG(netsurf, INFO,
+ "Creating temporay source file: %s\n",
+ tempfile);
fp_tmpfile = fopen(tempfile, "w");
if (fp_tmpfile != NULL){
fwrite(data, size, 1, fp_tmpfile);
@@ -306,7 +308,8 @@ void context_popup(struct gui_window * gw, short x, short y)
}
} else {
- LOG("Invalid content!");
+ NSLOG(netsurf, INFO,
+ "Invalid content!");
}
} else {
form_alert(0, "[1][Set option \"atari_editor\".][OK]");
diff --git a/frontends/atari/deskmenu.c b/frontends/atari/deskmenu.c
index addba2764..ded68ca5b 100644
--- a/frontends/atari/deskmenu.c
+++ b/frontends/atari/deskmenu.c
@@ -181,7 +181,7 @@ static void __CDECL menu_about(short item, short title, void *data)
nserror error;
char buf[PATH_MAX];
- LOG("%s", __FUNCTION__);
+ NSLOG(netsurf, INFO, "abort menu");
strcpy((char*)&buf, "file://");
strncat((char*)&buf, (char*)"./doc/README.TXT",
PATH_MAX - (strlen("file://")+1) );
@@ -208,7 +208,7 @@ static void __CDECL menu_new_win(short item, short title, void *data)
nserror error;
const char *addr;
- LOG("%s", __FUNCTION__);
+ NSLOG(netsurf, INFO, "%s", __FUNCTION__);
if (nsoption_charp(homepage_url) != NULL) {
addr = nsoption_charp(homepage_url);
@@ -236,7 +236,7 @@ static void __CDECL menu_open_url(short item, short title, void *data)
{
struct gui_window * gw;
struct browser_window * bw ;
- LOG("%s", __FUNCTION__);
+ NSLOG(netsurf, INFO, "%s", __FUNCTION__);
gw = input_window;
if( gw == NULL ) {
@@ -251,7 +251,7 @@ static void __CDECL menu_open_url(short item, short title, void *data)
static void __CDECL menu_open_file(short item, short title, void *data)
{
- LOG("%s", __FUNCTION__);
+ NSLOG(netsurf, INFO, "%s", __FUNCTION__);
const char * filename = file_select(messages_get("OpenFile"), "");
if( filename != NULL ){
@@ -280,7 +280,7 @@ static void __CDECL menu_open_file(short item, short title, void *data)
static void __CDECL menu_close_win(short item, short title, void *data)
{
- LOG("%s", __FUNCTION__);
+ NSLOG(netsurf, INFO, "%s", __FUNCTION__);
if( input_window == NULL )
return;
gui_window_destroy( input_window );
@@ -288,7 +288,7 @@ static void __CDECL menu_close_win(short item, short title, void *data)
static void __CDECL menu_save_page(short item, short title, void *data)
{
- LOG("%s", __FUNCTION__);
+ NSLOG(netsurf, INFO, "%s", __FUNCTION__);
static bool init = true;
bool is_folder=false;
const char * path;
@@ -319,7 +319,7 @@ static void __CDECL menu_quit(short item, short title, void *data)
{
short buff[8];
memset( &buff, 0, sizeof(short)*8 );
- LOG("%s", __FUNCTION__);
+ NSLOG(netsurf, INFO, "%s", __FUNCTION__);
gemtk_wm_send_msg(NULL, AP_TERM, 0, 0, 0, 0);
}
@@ -331,21 +331,21 @@ static void __CDECL menu_cut(short item, short title, void *data)
static void __CDECL menu_copy(short item, short title, void *data)
{
- LOG("%s", __FUNCTION__);
+ NSLOG(netsurf, INFO, "%s", __FUNCTION__);
if( input_window != NULL )
browser_window_key_press( input_window->browser->bw, NS_KEY_COPY_SELECTION);
}
static void __CDECL menu_paste(short item, short title, void *data)
{
- LOG("%s", __FUNCTION__);
+ NSLOG(netsurf, INFO, "%s", __FUNCTION__);
if( input_window != NULL )
browser_window_key_press( input_window->browser->bw, NS_KEY_PASTE);
}
static void __CDECL menu_find(short item, short title, void *data)
{
- LOG("%s", __FUNCTION__);
+ NSLOG(netsurf, INFO, "%s", __FUNCTION__);
if (input_window != NULL) {
if (input_window->search) {
window_close_search(input_window->root);
@@ -358,13 +358,13 @@ static void __CDECL menu_find(short item, short title, void *data)
static void __CDECL menu_choices(short item, short title, void *data)
{
- LOG("%s", __FUNCTION__);
+ NSLOG(netsurf, INFO, "%s", __FUNCTION__);
open_settings();
}
static void __CDECL menu_stop(short item, short title, void *data)
{
- LOG("%s", __FUNCTION__);
+ NSLOG(netsurf, INFO, "%s", __FUNCTION__);
if( input_window == NULL )
return;
@@ -378,7 +378,7 @@ static void __CDECL menu_reload(short item, short title, void *data)
if(input_window == NULL)
return;
toolbar_reload_click(input_window->root->toolbar);
- LOG("%s", __FUNCTION__);
+ NSLOG(netsurf, INFO, "%s", __FUNCTION__);
}
@@ -408,7 +408,7 @@ static void __CDECL menu_dec_scale(short item, short title, void *data)
static void __CDECL menu_toolbars(short item, short title, void *data)
{
static int state = 0;
- LOG("%s", __FUNCTION__);
+ NSLOG(netsurf, INFO, "%s", __FUNCTION__);
if( input_window != null && input_window->root->toolbar != null ){
state = !state;
// TODO: implement toolbar hide
@@ -418,7 +418,7 @@ static void __CDECL menu_toolbars(short item, short title, void *data)
static void __CDECL menu_savewin(short item, short title, void *data)
{
- LOG("%s", __FUNCTION__);
+ NSLOG(netsurf, INFO, "%s", __FUNCTION__);
if (input_window && input_window->browser) {
GRECT rect;
wind_get_grect(gemtk_wm_get_handle(input_window->root->win), WF_CURRXYWH,
@@ -438,7 +438,7 @@ static void __CDECL menu_savewin(short item, short title, void *data)
static void __CDECL menu_debug_render(short item, short title, void *data)
{
- LOG("%s", __FUNCTION__);
+ NSLOG(netsurf, INFO, "%s", __FUNCTION__);
html_redraw_debug = !html_redraw_debug;
if( input_window != NULL ) {
if ( input_window->browser != NULL
@@ -469,7 +469,7 @@ static void __CDECL menu_bg_images(short item, short title, void *data)
static void __CDECL menu_back(short item, short title, void *data)
{
- LOG("%s", __FUNCTION__);
+ NSLOG(netsurf, INFO, "%s", __FUNCTION__);
if( input_window == NULL )
return;
toolbar_back_click(input_window->root->toolbar);
@@ -477,7 +477,7 @@ static void __CDECL menu_back(short item, short title, void *data)
static void __CDECL menu_forward(short item, short title, void *data)
{
- LOG("%s", __FUNCTION__);
+ NSLOG(netsurf, INFO, "%s", __FUNCTION__);
if( input_window == NULL )
return;
toolbar_forward_click(input_window->root->toolbar);
@@ -485,7 +485,7 @@ static void __CDECL menu_forward(short item, short title, void *data)
static void __CDECL menu_home(short item, short title, void *data)
{
- LOG("%s", __FUNCTION__);
+ NSLOG(netsurf, INFO, "%s", __FUNCTION__);
if( input_window == NULL )
return;
toolbar_home_click(input_window->root->toolbar);
@@ -493,20 +493,20 @@ static void __CDECL menu_home(short item, short title, void *data)
static void __CDECL menu_lhistory(short item, short title, void *data)
{
- LOG("%s", __FUNCTION__);
+ NSLOG(netsurf, INFO, "%s", __FUNCTION__);
if( input_window == NULL )
return;
}
static void __CDECL menu_ghistory(short item, short title, void *data)
{
- LOG("%s", __FUNCTION__);
+ NSLOG(netsurf, INFO, "%s", __FUNCTION__);
atari_global_history_open();
}
static void __CDECL menu_add_bookmark(short item, short title, void *data)
{
- LOG("%s", __FUNCTION__);
+ NSLOG(netsurf, INFO, "%s", __FUNCTION__);
if (input_window) {
if( browser_window_has_content(input_window->browser->bw) ){
atari_hotlist_add_page(
@@ -519,26 +519,26 @@ static void __CDECL menu_add_bookmark(short item, short title, void *data)
static void __CDECL menu_bookmarks(short item, short title, void *data)
{
- LOG("%s", __FUNCTION__);
+ NSLOG(netsurf, INFO, "%s", __FUNCTION__);
atari_hotlist_open();
}
static void __CDECL menu_cookies(short item, short title, void *data)
{
- LOG("%s", __FUNCTION__);
+ NSLOG(netsurf, INFO, "%s", __FUNCTION__);
atari_cookie_manager_open();
}
static void __CDECL menu_vlog(short item, short title, void *data)
{
- LOG("%s", __FUNCTION__);
+ NSLOG(netsurf, INFO, "%s", __FUNCTION__);
verbose_log = !verbose_log;
menu_icheck(h_gem_menu, MAINMENU_M_VLOG, (verbose_log) ? 1 : 0);
}
static void __CDECL menu_help_content(short item, short title, void *data)
{
- LOG("%s", __FUNCTION__);
+ NSLOG(netsurf, INFO, "%s", __FUNCTION__);
}
/*
@@ -580,14 +580,16 @@ static void register_menu_str( struct s_menu_item_evnt * mi )
while (i > 2) {
if ((strncmp(" ", &str[i], 2) == 0) && (strlen(&str[i]) > 2)) {
// "Standard" Keyboard Shortcut Element found:
- LOG("Standard Keyboard Shortcut: \"%s\"\n", &str[i]);
+ NSLOG(netsurf, INFO,
+ "Standard Keyboard Shortcut: \"%s\"\n", &str[i]);
x = i+2;
is_std_shortcut = true;
break;
}
if( str[i] == '['){
- LOG("Keyboard Shortcut: \"%s\"\n", &str[i]);
+ NSLOG(netsurf, INFO, "Keyboard Shortcut: \"%s\"\n",
+ &str[i]);
// "Custom" Keyboard Shortcut Element found (identified by [):
x = i;
break;
@@ -662,8 +664,12 @@ static void register_menu_str( struct s_menu_item_evnt * mi )
}
}
- LOG("Registered keyboard shortcut for \"%s\" => mod: %d, ""keycode: %ld, ascii: %c\n",
- str, accel->mod, accel->keycode, accel->ascii);
+ NSLOG(netsurf, INFO,
+ "Registered keyboard shortcut for \"%s\" => mod: %d, ""keycode: %ld, ascii: %c\n",
+ str,
+ accel->mod,
+ accel->keycode,
+ accel->ascii);
}
}
diff --git a/frontends/atari/download.c b/frontends/atari/download.c
index d756e6694..7a1c7d2b7 100644
--- a/frontends/atari/download.c
+++ b/frontends/atari/download.c
@@ -194,7 +194,7 @@ static void on_close(struct gui_download_window * dw)
static void gui_download_window_destroy( struct gui_download_window * gdw)
{
- LOG("gdw %p", gdw);
+ NSLOG(netsurf, INFO, "gdw %p", gdw);
if (gdw->status == NSATARI_DOWNLOAD_WORKING) {
download_context_abort(gdw->ctx);
@@ -253,7 +253,8 @@ gui_download_window_create(download_context *ctx, struct gui_window *parent)
char alert[200];
- LOG("Creating download window for gui window: %p", parent);
+ NSLOG(netsurf, INFO, "Creating download window for gui window: %p",
+ parent);
/* TODO: Implement real form and use messages file strings! */
@@ -330,7 +331,8 @@ gui_download_window_create(download_context *ctx, struct gui_window *parent)
gemtk_wm_set_toolbar_redraw_func(gdw->guiwin, toolbar_redraw_cb);
strncpy((char*)&gdw->lbl_file, filename, MAX_SLEN_LBL_FILE-1);
- LOG("created download: %s (total size: %d)", gdw->destination, gdw->size_total);
+ NSLOG(netsurf, INFO, "created download: %s (total size: %d)",
+ gdw->destination, gdw->size_total);
GRECT work, curr;
work.g_x = 0;
@@ -357,7 +359,7 @@ static nserror gui_download_window_data(struct gui_download_window *dw,
uint32_t tnow = clck / (CLOCKS_PER_SEC>>3);
uint32_t sdiff = (clck / (CLOCKS_PER_SEC)) - dw->start;
- LOG("dw %p",dw);
+ NSLOG(netsurf, INFO, "dw %p", dw);
if (dw->abort == true){
dw->status = NSATARI_DOWNLOAD_CANCELED;
@@ -405,7 +407,7 @@ static nserror gui_download_window_data(struct gui_download_window *dw,
static void gui_download_window_error(struct gui_download_window *dw,
const char *error_msg)
{
- LOG("%s", error_msg);
+ NSLOG(netsurf, INFO, "%s", error_msg);
strncpy((char*)&dw->lbl_file, error_msg, MAX_SLEN_LBL_FILE-1);
dw->status = NSATARI_DOWNLOAD_ERROR;
@@ -416,7 +418,7 @@ static void gui_download_window_error(struct gui_download_window *dw,
static void gui_download_window_done(struct gui_download_window *dw)
{
- LOG("dw %p", dw);
+ NSLOG(netsurf, INFO, "dw %p", dw);
// TODO: change abort to close
dw->status = NSATARI_DOWNLOAD_COMPLETE;
diff --git a/frontends/atari/filetype.c b/frontends/atari/filetype.c
index d27076e9c..706347137 100644
--- a/frontends/atari/filetype.c
+++ b/frontends/atari/filetype.c
@@ -36,7 +36,7 @@ const char *fetch_filetype(const char *unix_path)
char * res = (char*)"text/html";
l = strlen(unix_path);
- LOG("unix path: %s", unix_path);
+ NSLOG(netsurf, INFO, "unix path: %s", unix_path);
/* This line is added for devlopment versions running from the root dir: */
if( strchr( unix_path, (int)'.' ) ){
@@ -85,6 +85,6 @@ const char *fetch_filetype(const char *unix_path)
}
}
- LOG("mime type: %s", res);
+ NSLOG(netsurf, INFO, "mime type: %s", res);
return( res );
}
diff --git a/frontends/atari/findfile.c b/frontends/atari/findfile.c
index 45ca6d916..8784727bc 100644
--- a/frontends/atari/findfile.c
+++ b/frontends/atari/findfile.c
@@ -31,7 +31,7 @@ char * local_file_to_url( const char * filename )
#define BACKSLASH 0x5C
char * url;
- LOG("in: %s", filename);
+ NSLOG(netsurf, INFO, "in: %s", filename);
if( strlen(filename) <= 2){
return( NULL );
@@ -55,7 +55,7 @@ char * local_file_to_url( const char * filename )
free(fname_local);
- LOG("out: %s", url);
+ NSLOG(netsurf, INFO, "out: %s", url);
return( url );
#undef BACKSLASH
@@ -81,10 +81,10 @@ char * atari_find_resource(char *buf, const char *filename, const char *def)
{
char *cdir = NULL;
char t[PATH_MAX];
- LOG("%s (def: %s)", filename, def);
+ NSLOG(netsurf, INFO, "%s (def: %s)", filename, def);
strcpy(t, NETSURF_GEM_RESPATH);
strcat(t, filename);
- LOG("checking %s", (char *)&t);
+ NSLOG(netsurf, INFO, "checking %s", (char *)&t);
if (gemdos_realpath(t, buf) != NULL) {
if (access(buf, R_OK) == 0) {
return buf;
@@ -92,7 +92,7 @@ char * atari_find_resource(char *buf, const char *filename, const char *def)
}
strcpy(t, "./");
strcat(t, filename);
- LOG("checking %s", (char *)&t);
+ NSLOG(netsurf, INFO, "checking %s", (char *)&t);
if (gemdos_realpath(t, buf) != NULL) {
if (access(buf, R_OK) == 0) {
return buf;
@@ -104,7 +104,7 @@ char * atari_find_resource(char *buf, const char *filename, const char *def)
strcpy(t, cdir);
strcat(t, "/.netsurf/");
strcat(t, filename);
- LOG("checking %s", (char *)&t);
+ NSLOG(netsurf, INFO, "checking %s", (char *)&t);
if (gemdos_realpath(t, buf) != NULL) {
if (access(buf, R_OK) == 0)
return buf;
@@ -116,19 +116,19 @@ char * atari_find_resource(char *buf, const char *filename, const char *def)
if (gemdos_realpath(cdir, buf) != NULL) {
strcat(buf, "/");
strcat(buf, filename);
- LOG("checking %s", (char *)&t);
+ NSLOG(netsurf, INFO, "checking %s", (char *)&t);
if (access(buf, R_OK) == 0)
return buf;
}
}
if (def[0] == '~') {
snprintf(t, PATH_MAX, "%s%s", getenv("HOME"), def + 1);
- LOG("checking %s", (char *)&t);
+ NSLOG(netsurf, INFO, "checking %s", (char *)&t);
if (gemdos_realpath(t, buf) == NULL) {
strcpy(buf, t);
}
} else {
- LOG("checking %s", (char *)def);
+ NSLOG(netsurf, INFO, "checking %s", (char *)def);
if (gemdos_realpath(def, buf) == NULL) {
strcpy(buf, def);
}
diff --git a/frontends/atari/gui.c b/frontends/atari/gui.c
index 4876d3106..6ee63b301 100644
--- a/frontends/atari/gui.c
+++ b/frontends/atari/gui.c
@@ -139,11 +139,11 @@ static void atari_poll(void)
evnt_multi_fast(&aes_event_in, aes_msg_out, &aes_event_out);
if(gemtk_wm_dispatch_event(&aes_event_in, &aes_event_out, aes_msg_out) == 0) {
if( (aes_event_out.emo_events & MU_MESAG) != 0 ) {
- LOG("WM: %d\n", aes_msg_out[0]);
+ NSLOG(netsurf, INFO, "WM: %d\n", aes_msg_out[0]);
switch(aes_msg_out[0]) {
case MN_SELECTED:
- LOG("Menu Item: %d\n", aes_msg_out[4]);
+ NSLOG(netsurf, INFO, "Menu Item: %d\n", aes_msg_out[4]);
deskmenu_dispatch_item(aes_msg_out[3], aes_msg_out[4]);
break;
@@ -195,13 +195,14 @@ gui_window_create(struct browser_window *bw,
gui_window_create_flags flags)
{
struct gui_window *gw=NULL;
- LOG("gw: %p, BW: %p, existing %p, flags: %d\n", gw, bw, existing, (int)flags);
+ NSLOG(netsurf, INFO, "gw: %p, BW: %p, existing %p, flags: %d\n", gw, bw,
+ existing, (int)flags);
gw = calloc(1, sizeof(struct gui_window));
if (gw == NULL)
return NULL;
- LOG("new window: %p, bw: %p\n", gw, bw);
+ NSLOG(netsurf, INFO, "new window: %p, bw: %p\n", gw, bw);
window_create(gw, bw, existing, WIDGET_STATUSBAR|WIDGET_TOOLBAR|WIDGET_RESIZE\
|WIDGET_SCROLL);
if (gw->root->win) {
@@ -253,7 +254,7 @@ void gui_window_destroy(struct gui_window *gw)
if (gw == NULL)
return;
- LOG("%s\n", __FUNCTION__);
+ NSLOG(netsurf, INFO, "%s\n", __FUNCTION__);
if (input_window == gw) {
gui_set_input_gui_window(NULL);
@@ -444,7 +445,8 @@ gui_window_set_scroll(struct gui_window *gw, const struct rect *rect)
return NSERROR_BAD_PARAMETER;
}
- LOG("scroll (gui_window: %p) %d, %d\n", gw, rect->x0, rect->y0);
+ NSLOG(netsurf, INFO, "scroll (gui_window: %p) %d, %d\n", gw, rect->x0,
+ rect->y0);
window_scroll_by(gw->root, rect->x0, rect->y0);
return NSERROR_OK;
@@ -771,7 +773,8 @@ static void gui_401login_open(nsurl *url, const char *realm,
char * out = NULL;
bres = login_form_do( url, (char*)realm, &out);
if (bres) {
- LOG("url: %s, realm: %s, auth: %s\n", nsurl_access(url), realm, out);
+ NSLOG(netsurf, INFO, "url: %s, realm: %s, auth: %s\n",
+ nsurl_access(url), realm, out);
urldb_set_auth_details(url, realm, out);
}
if (out != NULL) {
@@ -789,7 +792,7 @@ gui_cert_verify(nsurl *url, const struct ssl_cert_info *certs,
void *cbpw)
{
struct sslcert_session_data *data;
- LOG("url %s", nsurl_access(url));
+ NSLOG(netsurf, INFO, "url %s", nsurl_access(url));
// TODO: localize string
int b = form_alert(1, "[2][SSL Verify failed, continue?][Continue|Abort|Details...]");
@@ -812,7 +815,8 @@ gui_cert_verify(nsurl *url, const struct ssl_cert_info *certs,
void gui_set_input_gui_window(struct gui_window *gw)
{
- LOG("Setting input window from: %p to %p\n", input_window, gw);
+ NSLOG(netsurf, INFO, "Setting input window from: %p to %p\n",
+ input_window, gw);
input_window = gw;
}
@@ -823,7 +827,7 @@ struct gui_window * gui_get_input_window(void)
static void gui_quit(void)
{
- LOG("quitting");
+ NSLOG(netsurf, INFO, "quitting");
struct gui_window *gw = window_list;
struct gui_window *tmp = window_list;
@@ -852,9 +856,9 @@ static void gui_quit(void)
rsrc_free();
- LOG("Shutting down plotter");
+ NSLOG(netsurf, INFO, "Shutting down plotter");
plot_finalise();
- LOG("done");
+ NSLOG(netsurf, INFO, "done");
}
/**
@@ -866,7 +870,7 @@ process_cmdline(int argc, char** argv)
int opt;
bool set_default_dimensions = true;
- LOG("argc %d, argv %p", argc, argv);
+ NSLOG(netsurf, INFO, "argc %d, argv %p", argc, argv);
if ((nsoption_int(window_width) != 0) && (nsoption_int(window_height) != 0)) {
@@ -959,7 +963,7 @@ static nserror set_defaults(struct nsoption_s *defaults)
/* Set defaults for absent option strings */
nsoption_setnull_charp(cookie_file, strdup("cookies"));
if (nsoption_charp(cookie_file) == NULL) {
- LOG("Failed initialising string options");
+ NSLOG(netsurf, INFO, "Failed initialising string options");
return NSERROR_BAD_PARAMETER;
}
return NSERROR_OK;
@@ -976,7 +980,7 @@ static void gui_init(int argc, char** argv)
OBJECT * cursors;
atari_find_resource(buf, "netsurf.rsc", "./res/netsurf.rsc");
- LOG("Using RSC file: %s ", (char *)&buf);
+ NSLOG(netsurf, INFO, "Using RSC file: %s ", (char *)&buf);
if (rsrc_load(buf)==0) {
char msg[1024];
@@ -1012,15 +1016,16 @@ static void gui_init(int argc, char** argv)
create_cursor(MFORM_EX_FLAG_USERFORM, CURSOR_HELP,
cursors, &gem_cursors.help);
- LOG("Enabling core select menu");
+ NSLOG(netsurf, INFO, "Enabling core select menu");
nsoption_set_bool(core_select_menu, true);
- LOG("Loading url.db from: %s", nsoption_charp(url_file));
+ NSLOG(netsurf, INFO, "Loading url.db from: %s", nsoption_charp(url_file));
if( strlen(nsoption_charp(url_file)) ) {
urldb_load(nsoption_charp(url_file));
}
- LOG("Loading cookies from: %s", nsoption_charp(cookie_file));
+ NSLOG(netsurf, INFO, "Loading cookies from: %s",
+ nsoption_charp(cookie_file));
if( strlen(nsoption_charp(cookie_file)) ) {
urldb_load_cookies(nsoption_charp(cookie_file));
}
@@ -1028,10 +1033,10 @@ static void gui_init(int argc, char** argv)
if (process_cmdline(argc,argv) != true)
die("unable to process command line.\n");
- LOG("Initializing NKC...");
+ NSLOG(netsurf, INFO, "Initializing NKC...");
nkc_init();
- LOG("Initializing plotters...");
+ NSLOG(netsurf, INFO, "Initializing plotters...");
struct redraw_context ctx = {
.interactive = true,
.background_images = true,
@@ -1172,18 +1177,18 @@ int main(int argc, char** argv)
ret = messages_add_from_file(messages);
/* common initialisation */
- LOG("Initialising core...");
+ NSLOG(netsurf, INFO, "Initialising core...");
ret = netsurf_init(store);
if (ret != NSERROR_OK) {
die("NetSurf failed to initialise");
}
- LOG("Initializing GUI...");
+ NSLOG(netsurf, INFO, "Initializing GUI...");
gui_init(argc, argv);
graf_mouse( ARROW , NULL);
- LOG("Creating initial browser window...");
+ NSLOG(netsurf, INFO, "Creating initial browser window...");
addr = option_homepage_url;
if (strncmp(addr, "file://", 7) && strncmp(addr, "http://", 7)) {
if (stat(addr, &stat_buf) == 0) {
@@ -1205,7 +1210,7 @@ int main(int argc, char** argv)
if (ret != NSERROR_OK) {
atari_warn_user(messages_get_errorcode(ret), 0);
} else {
- LOG("Entering Atari event mainloop...");
+ NSLOG(netsurf, INFO, "Entering Atari event mainloop...");
while (!atari_quit) {
atari_poll();
}
@@ -1219,7 +1224,11 @@ int main(int argc, char** argv)
fclose(stdout);
fclose(stderr);
#endif
- LOG("exit_gem");
+ NSLOG(netsurf, INFO, "exit_gem");
+
+ /* finalise logging */
+ nslog_finalise();
+
exit_gem();
return 0;
diff --git a/frontends/atari/history.c b/frontends/atari/history.c
index 56aafd056..ec602684f 100644
--- a/frontends/atari/history.c
+++ b/frontends/atari/history.c
@@ -39,13 +39,13 @@ static nserror
atari_global_history_init_phase2(struct core_window *cw,
struct core_window_callback_table *cb_t)
{
- LOG("cw %p", cw);
+ NSLOG(netsurf, INFO, "cw %p", cw);
return(global_history_init(cb_t, cw));
}
static void atari_global_history_finish(struct core_window *cw)
{
- LOG("cw %p", cw);
+ NSLOG(netsurf, INFO, "cw %p", cw);
global_history_fini();
}
@@ -58,7 +58,7 @@ static void atari_global_history_draw(struct core_window *cw, int x,
static void atari_global_history_keypress(struct core_window *cw, uint32_t ucs4)
{
- LOG("ucs4: %"PRIu32, ucs4);
+ NSLOG(netsurf, INFO, "ucs4: %"PRIu32, ucs4);
global_history_keypress(ucs4);
}
@@ -67,7 +67,7 @@ atari_global_history_mouse_action(struct core_window *cw,
browser_mouse_state mouse,
int x, int y)
{
- LOG("x: %d, y: %d\n", x, y);
+ NSLOG(netsurf, INFO, "x: %d, y: %d\n", x, y);
global_history_mouse_action(mouse, x, y);
}
@@ -82,7 +82,7 @@ static short handle_event(GUIWIN *win, EVMULT_OUT *ev_out, short msg[8])
{
short retval = 0;
- LOG("win %p", win);
+ NSLOG(netsurf, INFO, "win %p", win);
if (ev_out->emo_events & MU_MESAG) {
switch (msg[0]) {
@@ -134,7 +134,8 @@ void atari_global_history_init(void)
if (atari_global_history.tv == NULL) {
/* handle it properly, clean up previous allocs */
- LOG("Failed to allocate treeview");
+ NSLOG(netsurf, INFO,
+ "Failed to allocate treeview");
return;
}
}
@@ -181,7 +182,7 @@ void atari_global_history_destroy(void)
atari_treeview_delete(atari_global_history.tv);
atari_global_history.init = false;
}
- LOG("done");
+ NSLOG(netsurf, INFO, "done");
}
void atari_global_history_redraw(void)
diff --git a/frontends/atari/hotlist.c b/frontends/atari/hotlist.c
index 659b3a562..3a54c98eb 100644
--- a/frontends/atari/hotlist.c
+++ b/frontends/atari/hotlist.c
@@ -72,13 +72,13 @@ static struct atari_treeview_callbacks atari_hotlist_treeview_callbacks = {
static nserror atari_hotlist_init_phase2(struct core_window *cw,
struct core_window_callback_table *cb_t)
{
- LOG("cw:%p", cw);
+ NSLOG(netsurf, INFO, "cw:%p", cw);
return hotlist_manager_init(cb_t, cw);
}
static void atari_hotlist_finish(struct core_window *cw)
{
- LOG("cw:%p", cw);
+ NSLOG(netsurf, INFO, "cw:%p", cw);
hotlist_fini();
}
@@ -93,7 +93,7 @@ static void atari_hotlist_keypress(struct core_window *cw, uint32_t ucs4)
{
//GUIWIN *gemtk_win;
//GRECT area;
- LOG("ucs4: %"PRIu32 , ucs4);
+ NSLOG(netsurf, INFO, "ucs4: %"PRIu32, ucs4);
hotlist_keypress(ucs4);
//gemtk_win = atari_treeview_get_gemtk_window(cw);
//atari_treeview_get_grect(cw, TREEVIEW_AREA_CONTENT, &area);
@@ -104,7 +104,7 @@ static void atari_hotlist_mouse_action(struct core_window *cw,
browser_mouse_state mouse,
int x, int y)
{
- LOG("x: %d, y: %d\n", x, y);
+ NSLOG(netsurf, INFO, "x: %d, y: %d\n", x, y);
hotlist_mouse_action(mouse, x, y);
}
@@ -123,7 +123,7 @@ static short handle_event(GUIWIN *win, EVMULT_OUT *ev_out, short msg[8])
GRECT tb_area;
GUIWIN * gemtk_win;
- LOG("gw:%p", win);
+ NSLOG(netsurf, INFO, "gw:%p", win);
tv = (struct atari_treeview_window*) gemtk_wm_get_user_data(win);
cw = (struct core_window *)tv;
@@ -132,7 +132,7 @@ static short handle_event(GUIWIN *win, EVMULT_OUT *ev_out, short msg[8])
switch (msg[0]) {
case WM_TOOLBAR:
- LOG("WM_TOOLBAR");
+ NSLOG(netsurf, INFO, "WM_TOOLBAR");
toolbar = gemtk_obj_get_tree(TOOLBAR_HOTLIST);
@@ -198,7 +198,7 @@ void atari_hotlist_init(void)
strncpy( (char*)&hl.path, nsoption_charp(hotlist_file), PATH_MAX-1 );
}
- LOG("Hotlist: %s", (char *)&hl.path);
+ NSLOG(netsurf, INFO, "Hotlist: %s", (char *)&hl.path);
hotlist_init(hl.path, hl.path);
if( hl.window == NULL ){
@@ -224,7 +224,8 @@ void atari_hotlist_init(void)
if (hl.tv == NULL) {
/* handle it properly, clean up previous allocs */
- LOG("Failed to allocate treeview");
+ NSLOG(netsurf, INFO,
+ "Failed to allocate treeview");
return;
}
@@ -276,7 +277,7 @@ void atari_hotlist_destroy(void)
atari_treeview_delete(hl.tv);
hl.init = false;
}
- LOG("done");
+ NSLOG(netsurf, INFO, "done");
}
void atari_hotlist_redraw(void)
@@ -299,7 +300,7 @@ void atari_hotlist_add_page( const char * url, const char * title )
return;
if (hotlist_has_url(nsurl)) {
- LOG("URL already added as Bookmark");
+ NSLOG(netsurf, INFO, "URL already added as Bookmark");
nsurl_unref(nsurl);
return;
}
diff --git a/frontends/atari/osspec.c b/frontends/atari/osspec.c
index f64402e8d..ca042f164 100644
--- a/frontends/atari/osspec.c
+++ b/frontends/atari/osspec.c
@@ -119,14 +119,14 @@ char *gemdos_realpath(const char * path, char * rpath)
return(rpath);
}
- LOG("realpath in: %s\n", path);
+ NSLOG(netsurf, INFO, "realpath in: %s\n", path);
r = realpath(path, work);
if (r != NULL) {
unx2dos((const char *)r, rpath);
- LOG("realpath out: %s\n", rpath);
+ NSLOG(netsurf, INFO, "realpath out: %s\n", rpath);
return(rpath);
} else {
- LOG("realpath out: NULL!\n");
+ NSLOG(netsurf, INFO, "realpath out: NULL!\n");
}
return (NULL);
}
diff --git a/frontends/atari/plot/font_freetype.c b/frontends/atari/plot/font_freetype.c
index 17d3c3bfd..1688e978b 100644
--- a/frontends/atari/plot/font_freetype.c
+++ b/frontends/atari/plot/font_freetype.c
@@ -154,11 +154,12 @@ static FT_Error ft_face_requester(FTC_FaceID face_id, FT_Library library, FT_Po
error = FT_New_Face(library, ft_face->fontfile, ft_face->index, face);
if (error) {
- LOG("Could not find font (code %d)\n", error);
+ NSLOG(netsurf, INFO, "Could not find font (code %d)\n", error);
} else {
error = FT_Select_Charmap(*face, FT_ENCODING_UNICODE);
if (error) {
- LOG("Could not select charmap (code %d)\n", error);
+ NSLOG(netsurf, INFO,
+ "Could not select charmap (code %d)\n", error);
} else {
for (cidx = 0; cidx < (*face)->num_charmaps; cidx++) {
if ((*face)->charmap == (*face)->charmaps[cidx]) {
@@ -168,7 +169,7 @@ static FT_Error ft_face_requester(FTC_FaceID face_id, FT_Library library, FT_Po
}
}
}
- LOG("Loaded face from %s\n", ft_face->fontfile);
+ NSLOG(netsurf, INFO, "Loaded face from %s\n", ft_face->fontfile);
return error;
}
@@ -190,7 +191,9 @@ ft_new_face(const char *option, const char *resname, const char *fontfile)
}
error = FTC_Manager_LookupFace(ft_cmanager, (FTC_FaceID)newf, &aface);
if (error) {
- LOG("Could not find font face %s (code %d)\n", fontfile, error);
+ NSLOG(netsurf, INFO,
+ "Could not find font face %s (code %d)\n", fontfile,
+ error);
free(newf);
newf = font_faces[FONT_FACE_DEFAULT]; /* use default */
}
@@ -292,7 +295,8 @@ static bool ft_font_init(void)
/* freetype library initialise */
error = FT_Init_FreeType( &library );
if (error) {
- LOG("Freetype could not initialised (code %d)\n", error);
+ NSLOG(netsurf, INFO,
+ "Freetype could not initialised (code %d)\n", error);
return false;
}
@@ -311,7 +315,9 @@ static bool ft_font_init(void)
NULL,
&ft_cmanager);
if (error) {
- LOG("Freetype could not initialise cache manager (code %d)\n", error);
+ NSLOG(netsurf, INFO,
+ "Freetype could not initialise cache manager (code %d)\n",
+ error);
FT_Done_FreeType(library);
return false;
}
@@ -330,7 +336,8 @@ static bool ft_font_init(void)
FONT_PKG_PATH FONT_FILE_SANS
);
if (font_faces[FONT_FACE_SANS_SERIF] == NULL) {
- LOG("Could not find default font (code %d)\n", error);
+ NSLOG(netsurf, INFO,
+ "Could not find default font (code %d)\n", error);
FTC_Manager_Done(ft_cmanager);
FT_Done_FreeType(library);
return false;
@@ -688,7 +695,7 @@ int ctor_font_plotter_freetype( FONT_PLOTTER self )
self->draw_glyph = draw_glyph8;
}
- LOG("%s: %s\n", (char *)__FILE__, __FUNCTION__);
+ NSLOG(netsurf, INFO, "%s: %s\n", (char *)__FILE__, __FUNCTION__);
if( !init ) {
ft_font_init();
fontbmp = atari_bitmap_create(48, 48, 0);
diff --git a/frontends/atari/plot/font_internal.c b/frontends/atari/plot/font_internal.c
index 3575bc3e1..709697f74 100644
--- a/frontends/atari/plot/font_internal.c
+++ b/frontends/atari/plot/font_internal.c
@@ -96,7 +96,7 @@ int ctor_font_plotter_internal( FONT_PLOTTER self )
self->str_split = str_split;
self->pixel_pos = pixel_pos;
self->text = text;
- LOG("%s: %s\n", (char *)__FILE__, __FUNCTION__);
+ NSLOG(netsurf, INFO, "%s: %s\n", (char *)__FILE__, __FUNCTION__);
if( !init ) {
vdih = self->vdi_handle;
fontbmp = atari_bitmap_create(48, 48, 0);
diff --git a/frontends/atari/plot/font_vdi.c b/frontends/atari/plot/font_vdi.c
index ef5499207..7cd82ddc9 100644
--- a/frontends/atari/plot/font_vdi.c
+++ b/frontends/atari/plot/font_vdi.c
@@ -70,7 +70,7 @@ int ctor_font_plotter_vdi( FONT_PLOTTER self )
self->str_split = str_split;
self->pixel_pos = pixel_pos;
self->text = text;
- LOG("%s: %s\n", (char *)__FILE__, __FUNCTION__);
+ NSLOG(netsurf, INFO, "%s: %s\n", (char *)__FILE__, __FUNCTION__);
if( !init ) {
vdih = self->vdi_handle;
}
diff --git a/frontends/atari/plot/plot.c b/frontends/atari/plot/plot.c
index 2324f82d9..14c670352 100644
--- a/frontends/atari/plot/plot.c
+++ b/frontends/atari/plot/plot.c
@@ -1628,7 +1628,7 @@ int plot_init(const struct redraw_context *ctx, char *fdrvrname)
short work_out[57];
atari_plot_vdi_handle=graf_handle(&dummy, &dummy, &dummy, &dummy);
v_opnvwk(work_in, &atari_plot_vdi_handle, work_out);
- LOG("Plot VDI handle: %d", atari_plot_vdi_handle);
+ NSLOG(netsurf, INFO, "Plot VDI handle: %d", atari_plot_vdi_handle);
}
read_vdi_sysinfo(atari_plot_vdi_handle, &vdi_sysinfo);
if(verbose_log) {
@@ -1640,7 +1640,8 @@ int plot_init(const struct redraw_context *ctx, char *fdrvrname)
atari_font_flags, &err);
if (err) {
const char * desc = plot_err_str(err);
- LOG("Unable to load font plotter %s -> %s", fdrvrname, desc );
+ NSLOG(netsurf, INFO, "Unable to load font plotter %s -> %s",
+ fdrvrname, desc);
die("font plotter");
}
diff --git a/frontends/atari/rootwin.c b/frontends/atari/rootwin.c
index 0b77cbba5..6576eac77 100644
--- a/frontends/atari/rootwin.c
+++ b/frontends/atari/rootwin.c
@@ -105,7 +105,7 @@ static short handle_event(GUIWIN *win, EVMULT_OUT *ev_out, short msg[8])
switch (msg[0]) {
case WM_REDRAW:
- LOG("WM_REDRAW");
+ NSLOG(netsurf, INFO, "WM_REDRAW");
on_redraw(data->rootwin, msg);
break;
@@ -113,7 +113,7 @@ static short handle_event(GUIWIN *win, EVMULT_OUT *ev_out, short msg[8])
case WM_SIZED:
case WM_MOVED:
case WM_FULLED:
- LOG("WM_SIZED");
+ NSLOG(netsurf, INFO, "WM_SIZED");
on_resized(data->rootwin);
break;
@@ -132,7 +132,7 @@ static short handle_event(GUIWIN *win, EVMULT_OUT *ev_out, short msg[8])
case WM_TOPPED:
case WM_NEWTOP:
case WM_UNICONIFY:
- LOG("WM_TOPPED");
+ NSLOG(netsurf, INFO, "WM_TOPPED");
gui_set_input_gui_window(data->rootwin->active_gui_window);
//window_restore_active_gui_window(data->rootwin);
// TODO: use something like "restore_active_gui_window_state()"
@@ -143,7 +143,8 @@ static short handle_event(GUIWIN *win, EVMULT_OUT *ev_out, short msg[8])
// TODO: this needs to iterate through all gui windows and
// check if the rootwin is this window...
if (data->rootwin->active_gui_window != NULL) {
- LOG("WM_CLOSED initiated destroy for bw %p", data->rootwin->active_gui_window->browser->bw);
+ NSLOG(netsurf, INFO, "WM_CLOSED initiated destroy for bw %p",
+ data->rootwin->active_gui_window->browser->bw);
browser_window_destroy(
data->rootwin->active_gui_window->browser->bw);
}
@@ -166,13 +167,16 @@ static short handle_event(GUIWIN *win, EVMULT_OUT *ev_out, short msg[8])
// handle key
uint16_t nkc = gem_to_norm( (short)ev_out->emo_kmeta,
(short)ev_out->emo_kreturn);
- LOG("rootwin MU_KEYBD input, nkc: %x\n", nkc);
+ NSLOG(netsurf, INFO, "rootwin MU_KEYBD input, nkc: %x\n", nkc);
retval = on_window_key_input(data->rootwin, nkc);
// printf("on_window_key_input: %d\n", retval);
}
if ((ev_out->emo_events & MU_BUTTON) != 0) {
- LOG("rootwin MU_BUTTON input, x: %d, y: %d\n", ev_out->emo_mouse.p_x, ev_out->emo_mouse.p_x);
+ NSLOG(netsurf, INFO,
+ "rootwin MU_BUTTON input, x: %d, y: %d\n",
+ ev_out->emo_mouse.p_x,
+ ev_out->emo_mouse.p_x);
window_get_grect(data->rootwin, BROWSER_AREA_CONTENT,
&area);
if (POINT_WITHIN(ev_out->emo_mouse.p_x, ev_out->emo_mouse.p_y,
@@ -312,13 +316,13 @@ void window_unref_gui_window(ROOTWIN *rootwin, struct gui_window *gw)
struct gui_window *w;
input_window = NULL;
- LOG("window: %p, gui_window: %p", rootwin, gw);
+ NSLOG(netsurf, INFO, "window: %p, gui_window: %p", rootwin, gw);
w = window_list;
// find the next active tab:
while( w != NULL ) {
if(w->root == rootwin && w != gw) {
- LOG("activating next tab %p", w);
+ NSLOG(netsurf, INFO, "activating next tab %p", w);
gui_set_input_gui_window(w);
break;
}
@@ -338,7 +342,7 @@ int window_destroy(ROOTWIN *rootwin)
assert(rootwin != NULL);
- LOG("%p", rootwin);
+ NSLOG(netsurf, INFO, "%p", rootwin);
if (gemtk_wm_get_user_data(rootwin->win) != NULL) {
free(gemtk_wm_get_user_data(rootwin->win));
@@ -404,7 +408,7 @@ void window_restore_active_gui_window(ROOTWIN *rootwin)
GRECT tb_area;
struct gui_window *gw;
- LOG("rootwin %p", rootwin);
+ NSLOG(netsurf, INFO, "rootwin %p", rootwin);
assert(rootwin->active_gui_window);
@@ -499,7 +503,7 @@ void window_set_focus(struct s_gui_win_root *rootwin,
assert(rootwin != NULL);
if (rootwin->focus.type != type || rootwin->focus.element != element) {
- LOG("Set focus: %p (%d)\n", element, type);
+ NSLOG(netsurf, INFO, "Set focus: %p (%d)\n", element, type);
rootwin->focus.type = type;
rootwin->focus.element = element;
switch( type ) {
@@ -563,11 +567,11 @@ void window_set_active_gui_window(ROOTWIN *rootwin, struct gui_window *gw)
{
struct gui_window *old_gw = rootwin->active_gui_window;
- LOG("gw %p",gw);
+ NSLOG(netsurf, INFO, "gw %p", gw);
if (rootwin->active_gui_window != NULL) {
if(rootwin->active_gui_window == gw) {
- LOG("nothing to do...");
+ NSLOG(netsurf, INFO, "nothing to do...");
return;
}
}
@@ -576,7 +580,7 @@ void window_set_active_gui_window(ROOTWIN *rootwin, struct gui_window *gw)
rootwin->active_gui_window = gw;
if (old_gw != NULL) {
- LOG("restoring window...");
+ NSLOG(netsurf, INFO, "restoring window...");
window_restore_active_gui_window(rootwin);
}
}
@@ -651,7 +655,7 @@ void window_open_search(ROOTWIN *rootwin, bool reformat)
GRECT area;
OBJECT *obj;
- LOG("rootwin %p", rootwin);
+ NSLOG(netsurf, INFO, "rootwin %p", rootwin);
gw = rootwin->active_gui_window;
bw = gw->browser->bw;
@@ -1478,7 +1482,13 @@ static void on_file_dropped(ROOTWIN *rootwin, short msg[8])
buff[size] = 0;
- LOG("file: %s, ext: %s, size: %ld dropped at: %d,%d\n", (char *)buff, (char *)&ext, size, mx, my);
+ NSLOG(netsurf, INFO,
+ "file: %s, ext: %s, size: %ld dropped at: %d,%d\n",
+ (char *)buff,
+ (char *)&ext,
+ size,
+ mx,
+ my);
gui_window_get_scroll(gw, &sx, &sy);
@@ -1500,7 +1510,8 @@ static void on_file_dropped(ROOTWIN *rootwin, short msg[8])
if (ret != NSERROR_OK) {
free(buff);
/* A bad encoding should never happen */
- LOG("utf8_from_local_encoding failed");
+ NSLOG(netsurf, INFO,
+ "utf8_from_local_encoding failed");
assert(ret != NSERROR_BAD_ENCODING);
/* no memory */
goto error;
diff --git a/frontends/atari/schedule.c b/frontends/atari/schedule.c
index 48980426d..9a7836b1f 100644
--- a/frontends/atari/schedule.c
+++ b/frontends/atari/schedule.c
@@ -23,15 +23,10 @@
#include "utils/sys_time.h"
#include "utils/errors.h"
+#include "utils/log.h"
#include "atari/schedule.h"
-#ifdef DEBUG_SCHEDULER
-#include "utils/log.h"
-#else
-#define LOG(x...)
-#endif
-
#define MS_NOW() ((clock() * 1000) / CLOCKS_PER_SEC)
/* linked list of scheduled callbacks */
@@ -71,7 +66,7 @@ static nserror schedule_remove(void (*callback)(void *p), void *p)
return NSERROR_OK;
}
- LOG("removing %p, %p", callback, p);
+ NSLOG(schedule, DEBUG, "removing %p, %p", callback, p);
cur_nscb = schedule_list;
prev_nscb = NULL;
@@ -80,7 +75,9 @@ static nserror schedule_remove(void (*callback)(void *p), void *p)
if ((cur_nscb->callback == callback) &&
(cur_nscb->p == p)) {
/* item to remove */
- LOG("callback entry %p removing %p(%p)", cur_nscb, cur_nscb->callback, cur_nscb->p);
+ NSLOG(schedule, DEBUG,
+ "callback entry %p removing %p(%p)", cur_nscb,
+ cur_nscb->callback, cur_nscb->p);
/* remove callback */
unlnk_nscb = cur_nscb;
@@ -118,7 +115,8 @@ nserror atari_schedule(int ival, void (*callback)(void *p), void *p)
nscb->timeout = MS_NOW() + ival;
- LOG("adding callback %p for %p(%p) at %d ms", nscb, callback, p, nscb->timeout);
+ NSLOG(schedule, DEBUG, "adding callback %p for %p(%p) at %d ms", nscb,
+ callback, p, nscb->timeout);
nscb->callback = callback;
nscb->p = p;
@@ -164,7 +162,9 @@ int schedule_run(void)
prev_nscb->next = unlnk_nscb->next;
}
- LOG("callback entry %p running %p(%p)", unlnk_nscb, unlnk_nscb->callback, unlnk_nscb->p);
+ NSLOG(schedule, DEBUG,
+ "callback entry %p running %p(%p)", unlnk_nscb,
+ unlnk_nscb->callback, unlnk_nscb->p);
/* call callback */
unlnk_nscb->callback(unlnk_nscb->p);
@@ -173,7 +173,7 @@ int schedule_run(void)
/* need to deal with callback modifying the list. */
if (schedule_list == NULL) {
- LOG("schedule_list == NULL");
+ NSLOG(schedule, DEBUG, "schedule_list == NULL");
return -1; /* no more callbacks scheduled */
}
@@ -198,7 +198,8 @@ int schedule_run(void)
/* make rettime relative to now and convert to ms */
nexttime = nexttime - now;
- LOG("returning time to next event as %ldms", nexttime);
+ NSLOG(schedule, DEBUG, "returning time to next event as %ldms",
+ nexttime);
/*return next event time in milliseconds (24days max wait) */
return nexttime;
@@ -210,14 +211,15 @@ void list_schedule(void)
{
struct nscallback *cur_nscb;
- LOG("schedule list at ms clock %ld", MS_NOW());
+ NSLOG(schedule, DEBUG, "schedule list at ms clock %ld", MS_NOW());
cur_nscb = schedule_list;
while (cur_nscb != NULL) {
- LOG("Schedule %p at %ld", cur_nscb, cur_nscb->timeout);
+ NSLOG(schedule, DEBUG, "Schedule %p at %ld", cur_nscb,
+ cur_nscb->timeout);
cur_nscb = cur_nscb->next;
}
- LOG("Maxmium callbacks scheduled: %d", max_scheduled);
+ NSLOG(schedule, DEBUG, "Maxmium callbacks scheduled: %d", max_scheduled);
}
diff --git a/frontends/atari/search.c b/frontends/atari/search.c
index 4da7f16a3..8df4ad676 100644
--- a/frontends/atari/search.c
+++ b/frontends/atari/search.c
@@ -67,7 +67,7 @@ struct gui_search_table *atari_search_table = &search_table;
*/
void nsatari_search_set_status(bool found, void *p)
{
- LOG("%p set status: %d\n", p, found);
+ NSLOG(netsurf, INFO, "%p set status: %d\n", p, found);
// TODO: maybe update GUI
}
@@ -80,7 +80,7 @@ void nsatari_search_set_status(bool found, void *p)
void nsatari_search_set_hourglass(bool active, void *p)
{
SEARCH_FORM_SESSION s = (SEARCH_FORM_SESSION)p;
- LOG("active: %d, session: %p", active, p);
+ NSLOG(netsurf, INFO, "active: %d, session: %p", active, p);
if (active) {
gui_window_set_pointer(s->g, GUI_POINTER_PROGRESS);
} else {
@@ -99,7 +99,7 @@ void nsatari_search_set_hourglass(bool active, void *p)
*/
void nsatari_search_add_recent(const char *string, void *p)
{
- LOG("%p add recent: %s\n", p, string);
+ NSLOG(netsurf, INFO, "%p add recent: %s\n", p, string);
}
@@ -115,7 +115,7 @@ void nsatari_search_set_forward_state(bool active, void *p)
GRECT area;
SEARCH_FORM_SESSION s = (SEARCH_FORM_SESSION)p;
/* deactivate back cb */
- LOG("%p: set forward state: %d\n", p, active);
+ NSLOG(netsurf, INFO, "%p: set forward state: %d\n", p, active);
gw = s->g;
@@ -142,7 +142,7 @@ void nsatari_search_set_back_state(bool active, void *p)
GRECT area;
SEARCH_FORM_SESSION s = (SEARCH_FORM_SESSION)p;
/* deactivate back cb */
- LOG("%p: set back state: %d\n", p, active);
+ NSLOG(netsurf, INFO, "%p: set back state: %d\n", p, active);
s->state.back_avail = active;
gw = s->g;
@@ -224,7 +224,7 @@ void nsatari_search_restore_form( struct s_search_form_session *s, OBJECT *obj)
void nsatari_search_session_destroy(struct s_search_form_session *s)
{
if (s != NULL) {
- LOG("session %p", s);
+ NSLOG(netsurf, INFO, "session %p", s);
browser_window_search_clear(s->g->browser->bw);
free(s);
}
diff --git a/frontends/atari/settings.c b/frontends/atari/settings.c
index ed1fb2e45..7084bacf7 100644
--- a/frontends/atari/settings.c
+++ b/frontends/atari/settings.c
@@ -172,7 +172,7 @@ static char **read_locales(void)
atari_warn_user("Failed to load locales: %s",buf);
return(NULL);
} else {
- LOG("Reading locales from: %s...", buf);
+ NSLOG(netsurf, INFO, "Reading locales from: %s...", buf);
}
/* Count items: */
@@ -257,15 +257,15 @@ static void display_settings(void)
/* "Cache" tab: */
tmp_option_memory_cache_size = nsoption_int(memory_cache_size) / (1024*1024);
- snprintf( spare, 255, "%d", tmp_option_memory_cache_size );
+ snprintf( spare, 255, "%u", tmp_option_memory_cache_size );
set_text( SETTINGS_STR_MAX_MEM_CACHE, spare, 4 );
tmp_option_disc_cache_size = nsoption_int(disc_cache_size) / (1024*1024);
- snprintf( spare, 255, "%d", tmp_option_disc_cache_size );
+ snprintf( spare, 255, "%u", tmp_option_disc_cache_size );
set_text( SETTINGS_STR_MAX_DISC_CACHE, spare, 4 );
tmp_option_disc_cache_age = nsoption_int(disc_cache_age);
- snprintf( spare, 255, "%02d", tmp_option_disc_cache_age );
+ snprintf( spare, 255, "%02u", tmp_option_disc_cache_age );
set_text( SETTINGS_EDIT_CACHE_AGE, spare, 3 );
/* "Paths" tab: */
@@ -303,7 +303,7 @@ static void display_settings(void)
// TODO: activate this option?
tmp_option_min_reflow_period = nsoption_int(min_reflow_period);
- snprintf( spare, 255, "%04d", tmp_option_min_reflow_period );
+ snprintf( spare, 255, "%04u", tmp_option_min_reflow_period );
set_text( SETTINGS_EDIT_MIN_REFLOW_PERIOD, spare,
INPUT_MIN_REFLOW_PERIOD_MAX_LEN );
@@ -597,7 +597,7 @@ static void form_event(int index, int external)
tmp_option_memory_cache_size = 1;
if( tmp_option_memory_cache_size > 999 )
tmp_option_memory_cache_size = 999;
- snprintf( spare, 255, "%02d", tmp_option_memory_cache_size );
+ snprintf( spare, 255, "%02u", tmp_option_memory_cache_size );
set_text( SETTINGS_STR_MAX_MEM_CACHE, spare, 5 );
is_button = true;
OBJ_REDRAW(SETTINGS_STR_MAX_MEM_CACHE);
@@ -614,7 +614,7 @@ static void form_event(int index, int external)
tmp_option_disc_cache_size = 1;
if( tmp_option_disc_cache_size > 9999 )
tmp_option_disc_cache_size = 9999;
- snprintf( spare, 255, "%02d", tmp_option_disc_cache_size );
+ snprintf( spare, 255, "%02u", tmp_option_disc_cache_size );
set_text( SETTINGS_STR_MAX_DISC_CACHE, spare, 5 );
is_button = true;
OBJ_REDRAW(SETTINGS_STR_MAX_DISC_CACHE);
@@ -630,7 +630,7 @@ static void form_event(int index, int external)
if( tmp_option_disc_cache_age > 99 )
tmp_option_disc_cache_age = 0;
- snprintf( spare, 255, "%02d", tmp_option_disc_cache_age );
+ snprintf( spare, 255, "%02u", tmp_option_disc_cache_age );
set_text( SETTINGS_EDIT_CACHE_AGE, spare, 2 );
is_button = true;
OBJ_REDRAW(SETTINGS_EDIT_CACHE_AGE);
@@ -645,7 +645,7 @@ static void form_event(int index, int external)
if( tmp_option_max_cached_fetch_handles > 31 )
tmp_option_max_cached_fetch_handles = 31;
- snprintf( spare, 255, "%02d", tmp_option_max_cached_fetch_handles );
+ snprintf( spare, 255, "%02u", tmp_option_max_cached_fetch_handles );
set_text( SETTINGS_EDIT_MAX_CACHED_CONNECTIONS, spare, 2 );
is_button = true;
OBJ_REDRAW(SETTINGS_EDIT_MAX_CACHED_CONNECTIONS);
@@ -660,7 +660,7 @@ static void form_event(int index, int external)
if( tmp_option_max_fetchers > 31 )
tmp_option_max_fetchers = 31;
- snprintf( spare, 255, "%02d", tmp_option_max_fetchers );
+ snprintf( spare, 255, "%02u", tmp_option_max_fetchers );
set_text( SETTINGS_EDIT_MAX_FETCHERS, spare, 2 );
is_button = true;
OBJ_REDRAW(SETTINGS_EDIT_MAX_FETCHERS);
@@ -675,7 +675,7 @@ static void form_event(int index, int external)
if( tmp_option_max_fetchers_per_host > 31 )
tmp_option_max_fetchers_per_host = 31;
- snprintf( spare, 255, "%02d", tmp_option_max_fetchers_per_host );
+ snprintf( spare, 255, "%02u", tmp_option_max_fetchers_per_host );
set_text( SETTINGS_EDIT_MAX_FETCHERS_PER_HOST, spare, 2 );
is_button = true;
OBJ_REDRAW(SETTINGS_EDIT_MAX_FETCHERS_PER_HOST);
@@ -691,7 +691,7 @@ static void form_event(int index, int external)
if( tmp_option_expire_url > 99 )
tmp_option_expire_url = 0;
- snprintf( spare, 255, "%02d", tmp_option_expire_url );
+ snprintf( spare, 255, "%02u", tmp_option_expire_url );
set_text( SETTINGS_EDIT_HISTORY_AGE, spare, 2 );
is_button = true;
OBJ_REDRAW(SETTINGS_EDIT_HISTORY_AGE);
@@ -726,7 +726,7 @@ static void form_event(int index, int external)
if( tmp_option_font_min_size < 10 )
tmp_option_font_min_size = 10;
- snprintf( spare, 255, "%03d", tmp_option_font_min_size );
+ snprintf( spare, 255, "%03u", tmp_option_font_min_size );
set_text( SETTINGS_EDIT_MIN_FONT_SIZE, spare, 3 );
is_button = true;
OBJ_REDRAW(SETTINGS_EDIT_MIN_FONT_SIZE);
@@ -744,7 +744,7 @@ static void form_event(int index, int external)
if( tmp_option_font_size < 50 )
tmp_option_font_size = 50;
- snprintf( spare, 255, "%03d", tmp_option_font_size );
+ snprintf( spare, 255, "%03u", tmp_option_font_size );
set_text( SETTINGS_EDIT_DEF_FONT_SIZE, spare, 3 );
is_button = true;
OBJ_REDRAW(SETTINGS_EDIT_DEF_FONT_SIZE);
@@ -760,7 +760,7 @@ static void form_event(int index, int external)
if( tmp_option_min_reflow_period > 9999 )
tmp_option_min_reflow_period = 10;
- snprintf( spare, 255, "%04d", tmp_option_min_reflow_period );
+ snprintf( spare, 255, "%04u", tmp_option_min_reflow_period );
set_text( SETTINGS_EDIT_MIN_REFLOW_PERIOD, spare, 4 );
is_button = true;
OBJ_REDRAW(SETTINGS_EDIT_MIN_REFLOW_PERIOD);
@@ -980,12 +980,12 @@ void open_settings(void)
void close_settings(void)
{
- LOG("closing");
+ NSLOG(netsurf, INFO, "closing");
gemtk_wm_remove(settings_guiwin);
settings_guiwin = NULL;
wind_close(h_aes_win);
wind_delete(h_aes_win);
h_aes_win = 0;
- LOG("Done");
+ NSLOG(netsurf, INFO, "Done");
}
diff --git a/frontends/atari/statusbar.c b/frontends/atari/statusbar.c
index 3a216f9a8..fe2008c82 100644
--- a/frontends/atari/statusbar.c
+++ b/frontends/atari/statusbar.c
@@ -166,7 +166,7 @@ CMP_STATUSBAR sb_create( struct gui_window * gw )
void sb_destroy( CMP_STATUSBAR s )
{
- LOG("%s\n", __FUNCTION__);
+ NSLOG(netsurf, INFO, "%s\n", __FUNCTION__);
if( s ) {
if( s->comp ){
mt_CompDelete( &app, s->comp );
@@ -206,7 +206,7 @@ CMP_STATUSBAR sb_create( struct gui_window * gw )
void sb_destroy( CMP_STATUSBAR s )
{
- LOG("%s\n", __FUNCTION__);
+ NSLOG(netsurf, INFO, "%s\n", __FUNCTION__);
if( s ) {
free( s );
}
diff --git a/frontends/atari/toolbar.c b/frontends/atari/toolbar.c
index 1b9371763..fdfedcbee 100644
--- a/frontends/atari/toolbar.c
+++ b/frontends/atari/toolbar.c
@@ -269,7 +269,7 @@ struct s_toolbar *toolbar_create(struct s_gui_win_root *owner)
int i;
struct s_toolbar *t;
- LOG("owner %p", owner);
+ NSLOG(netsurf, INFO, "owner %p", owner);
assert(init == true);
@@ -327,8 +327,9 @@ struct s_toolbar *toolbar_create(struct s_gui_win_root *owner)
t->throbber.max_index = THROBBER_MAX_INDEX;
t->throbber.running = false;
- LOG("created toolbar: %p, root: %p, textarea: %p, throbber: %p",
- t, owner, t->url.textarea, &t->throbber);
+ NSLOG(netsurf, INFO,
+ "created toolbar: %p, root: %p, textarea: %p, throbber: %p", t,
+ owner, t->url.textarea, &t->throbber);
return( t );
}
@@ -458,7 +459,7 @@ toolbar_update_buttons(struct s_toolbar *tb,
struct browser_window *bw,
short button)
{
- LOG("tb %p", tb);
+ NSLOG(netsurf, INFO, "tb %p", tb);
struct s_tb_button * bt;
bool enable = false;
@@ -582,7 +583,7 @@ void toolbar_set_dimensions(struct s_toolbar *tb, GRECT *area)
void toolbar_set_url(struct s_toolbar *tb, const char *text)
{
- LOG("tb %p", tb);
+ NSLOG(netsurf, INFO, "tb %p", tb);
textarea_set_text(tb->url.textarea, text);
@@ -668,7 +669,7 @@ bool toolbar_text_input(struct s_toolbar *tb, char *text)
{
bool handled = true;
- LOG("tb %p", tb);
+ NSLOG(netsurf, INFO, "tb %p", tb);
return(handled);
}
@@ -757,7 +758,7 @@ void toolbar_mouse_input(struct s_toolbar *tb, short obj, short button)
short mx, my, mb, kstat;
struct gui_window * gw;
- LOG("tb %p", tb);
+ NSLOG(netsurf, INFO, "tb %p", tb);
if (obj==TOOLBAR_AREA_URL) {
diff --git a/frontends/atari/treeview.c b/frontends/atari/treeview.c
index abc1fa780..23db41309 100644
--- a/frontends/atari/treeview.c
+++ b/frontends/atari/treeview.c
@@ -362,8 +362,8 @@ static short handle_event(GUIWIN *win, EVMULT_OUT *ev_out, short msg[8])
on_keybd_event(cw, ev_out, msg);
}
if ((ev_out->emo_events & MU_BUTTON) != 0 ) {
- LOG("Treeview click at: %d,%d\n",
- ev_out->emo_mouse.p_x, ev_out->emo_mouse.p_y);
+ NSLOG(netsurf, INFO, "Treeview click at: %d,%d\n",
+ ev_out->emo_mouse.p_x, ev_out->emo_mouse.p_y);
on_mbutton_event(cw, ev_out, msg);
}
@@ -541,7 +541,7 @@ atari_treeview_create(GUIWIN *win, struct atari_treeview_callbacks * callbacks,
tv = calloc(1, sizeof(struct atari_treeview_window));
if (tv == NULL) {
- LOG("calloc failed");
+ NSLOG(netsurf, INFO, "calloc failed");
atari_warn_user(messages_get_errorcode(NSERROR_NOMEM), 0);
return NULL;
}
diff --git a/frontends/atari/verify_ssl.c b/frontends/atari/verify_ssl.c
index 33136eebd..b099fe488 100644
--- a/frontends/atari/verify_ssl.c
+++ b/frontends/atari/verify_ssl.c
@@ -80,7 +80,9 @@ static void __CDECL cert_info_draw( WINDOW * win, short buf[8], void * data)
if( line == NULL )
return;
- LOG("Cert info draw, win: %p, data: %p, scrollx: %d", win, data, dp->scrollx );
+ NSLOG(netsurf, INFO,
+ "Cert info draw, win: %p, data: %p, scrollx: %d", win, data,
+ dp->scrollx);
WindGet( win, WF_WORKXYWH, &x, &y, &w, &h );
/*using static values here, as RsrcUserDraw has mem leaks & a very small stack */
@@ -158,7 +160,7 @@ static void do_popup( WINDOW *win, int index, int mode, void *data)
char * items[dp->num_certs];
short x, y;
unsigned int i;
- LOG("do_popup: num certs: %d", dp->num_certs);
+ NSLOG(netsurf, INFO, "do_popup: num certs: %d", dp->num_certs);
for( i = 0; i<dp->num_certs; i++) {
items[i] = malloc( 48 );
strncpy(items[i], (char*)&dp->cert_infos_n[i].issuer, 46 );
@@ -246,7 +248,7 @@ verify_ssl_form_do(const char * url,
break;
case VERIFY_BT_SCROLL_R:
- LOG("scroll r!");
+ NSLOG(netsurf, INFO, "scroll r!");
cont = true;
dp.scrollx += 1;
if( dp.scrollx > (dp.cols - (272 / 8 )) )
diff --git a/frontends/beos/bitmap.cpp b/frontends/beos/bitmap.cpp
index 68d8442ab..c4b008755 100644
--- a/frontends/beos/bitmap.cpp
+++ b/frontends/beos/bitmap.cpp
@@ -377,7 +377,7 @@ nsbeos_bitmap_get_pretile_x(struct bitmap* bitmap)
if (!bitmap->pretile_x) {
int width = bitmap->primary->Bounds().Width() + 1;
int xmult = (MIN_PRETILE_WIDTH + width - 1)/width;
- LOG("Pretiling %p for X*%d", bitmap, xmult);
+ NSLOG(netsurf, INFO, "Pretiling %p for X*%d", bitmap, xmult);
bitmap->pretile_x = nsbeos_bitmap_generate_pretile(bitmap->primary, xmult, 1);
}
return bitmap->pretile_x;
@@ -396,7 +396,7 @@ nsbeos_bitmap_get_pretile_y(struct bitmap* bitmap)
if (!bitmap->pretile_y) {
int height = bitmap->primary->Bounds().Height() + 1;
int ymult = (MIN_PRETILE_HEIGHT + height - 1)/height;
- LOG("Pretiling %p for Y*%d", bitmap, ymult);
+ NSLOG(netsurf, INFO, "Pretiling %p for Y*%d", bitmap, ymult);
bitmap->pretile_y = nsbeos_bitmap_generate_pretile(bitmap->primary, 1, ymult);
}
return bitmap->pretile_y;
@@ -416,7 +416,8 @@ nsbeos_bitmap_get_pretile_xy(struct bitmap* bitmap)
int height = bitmap->primary->Bounds().Height() + 1;
int xmult = (MIN_PRETILE_WIDTH + width - 1)/width;
int ymult = (MIN_PRETILE_HEIGHT + height - 1)/height;
- LOG("Pretiling %p for X*%d Y*%d", bitmap, xmult, ymult);
+ NSLOG(netsurf, INFO, "Pretiling %p for X*%d Y*%d", bitmap,
+ xmult, ymult);
bitmap->pretile_xy = nsbeos_bitmap_generate_pretile(bitmap->primary, xmult, ymult);
}
return bitmap->pretile_xy;
diff --git a/frontends/beos/fetch_rsrc.cpp b/frontends/beos/fetch_rsrc.cpp
index e77f4c96e..ae3648354 100644
--- a/frontends/beos/fetch_rsrc.cpp
+++ b/frontends/beos/fetch_rsrc.cpp
@@ -71,13 +71,15 @@ BResources *gAppResources = NULL;
static bool fetch_rsrc_initialise(lwc_string *scheme)
{
- LOG("fetch_rsrc_initialise called for %s", lwc_string_data(scheme));
+ NSLOG(netsurf, INFO, "fetch_rsrc_initialise called for %s",
+ lwc_string_data(scheme));
return true;
}
static void fetch_rsrc_finalise(lwc_string *scheme)
{
- LOG("fetch_rsrc_finalise called for %s", lwc_string_data(scheme));
+ NSLOG(netsurf, INFO, "fetch_rsrc_finalise called for %s",
+ lwc_string_data(scheme));
}
static bool fetch_rsrc_can_fetch(const nsurl *url)
@@ -162,7 +164,7 @@ static bool fetch_rsrc_process(struct fetch_rsrc_context *c)
* rsrc://[TYPE][@NUM]/name[,mime]
*/
- LOG("*** Processing %s", c->url);
+ NSLOG(netsurf, INFO, "*** Processing %s", c->url);
if (strlen(c->url) < 7) {
/* 7 is the minimum possible length (rsrc://) */
@@ -199,11 +201,13 @@ static bool fetch_rsrc_process(struct fetch_rsrc_context *c)
uint8 c1, c2, c3, c4;
if (sscanf(params, "%c%c%c%c", &c1, &c2, &c3, &c4) > 3) {
type = c1 << 24 | c2 << 16 | c3 << 8 | c4;
- LOG("fetch_rsrc: type:%4.4s\n", (char *)&type);
+ NSLOG(netsurf, INFO, "fetch_rsrc: type:%4.4s\n",
+ (char *)&type);
}
}
- LOG("fetch_rsrc: 0x%08lx, %ld, '%s'\n", type, id, c->name);
+ NSLOG(netsurf, INFO, "fetch_rsrc: 0x%08lx, %ld, '%s'\n", type, id,
+ c->name);
bool found;
if (id)
@@ -278,7 +282,10 @@ static void fetch_rsrc_poll(lwc_string *scheme)
char header[64];
fetch_set_http_code(c->parent_fetch, 200);
- LOG("setting rsrc: MIME type to %s, length to %zd", c->mimetype, c->datalen);
+ NSLOG(netsurf, INFO,
+ "setting rsrc: MIME type to %s, length to %zd",
+ c->mimetype,
+ c->datalen);
/* Any callback can result in the fetch being aborted.
* Therefore, we _must_ check for this after _every_
* call to fetch_rsrc_send_callback().
@@ -308,7 +315,8 @@ static void fetch_rsrc_poll(lwc_string *scheme)
fetch_rsrc_send_callback(&msg, c);
}
} else {
- LOG("Processing of %s failed!", c->url);
+ NSLOG(netsurf, INFO, "Processing of %s failed!",
+ c->url);
/* Ensure that we're unlocked here. If we aren't,
* then fetch_rsrc_process() is broken.
diff --git a/frontends/beos/font.cpp b/frontends/beos/font.cpp
index 407918f0c..81113032d 100644
--- a/frontends/beos/font.cpp
+++ b/frontends/beos/font.cpp
@@ -204,8 +204,8 @@ static nserror beos_font_position(const plot_font_style_t *fstyle,
const char *string, size_t length,
int x, size_t *char_offset, int *actual_x)
{
- //LOG("(, '%s', %d, %d, , )", string, length, x);
- //fprintf(stderr, "%s(, '%s', %d, %d, , )\n", __FUNCTION__, string, length, x);
+ NSLOG(netsurf, DEEPDEBUG, "(, '%s', %d, %d, , )", string, length, x);
+
int index;
BFont font;
@@ -261,8 +261,7 @@ static nserror beos_font_split(const plot_font_style_t *fstyle,
const char *string, size_t length,
int x, size_t *char_offset, int *actual_x)
{
- //fprintf(stderr, "%s(, '%s', %d, %d, , )\n", __FUNCTION__, string, length, x);
- //LOG("(, '%s', %d, %d, , )", string, length, x);
+ NSLOG(netsurf, DEEPDEBUG, "(, '%s', %d, %d, , )", string, length, x);
int index = 0;
BFont font;
diff --git a/frontends/beos/gui.cpp b/frontends/beos/gui.cpp
index d3321b58d..19f8eac49 100644
--- a/frontends/beos/gui.cpp
+++ b/frontends/beos/gui.cpp
@@ -112,7 +112,7 @@ static int sEventPipe[2];
/* exported function defined in beos/gui.h */
nserror beos_warn_user(const char *warning, const char *detail)
{
- LOG("warn_user: %s (%s)", warning, detail);
+ NSLOG(netsurf, INFO, "warn_user: %s (%s)", warning, detail);
BAlert *alert;
BString text(warning);
if (detail)
@@ -354,14 +354,15 @@ static void check_homedir(void)
if (err < B_OK) {
/* we really can't continue without a home directory. */
- LOG("Can't find user settings directory - nowhere to store state!");
+ NSLOG(netsurf, INFO,
+ "Can't find user settings directory - nowhere to store state!");
die("NetSurf needs to find the user settings directory in order to run.\n");
}
path.Append("NetSurf");
err = create_directory(path.Path(), 0644);
if (err < B_OK) {
- LOG("Unable to create %s", path.Path());
+ NSLOG(netsurf, INFO, "Unable to create %s", path.Path());
die("NetSurf could not create its settings directory.\n");
}
}
@@ -387,7 +388,7 @@ static nsurl *gui_get_resource_url(const char *path)
path = "favicon.png";
u << path;
- LOG("(%s) -> '%s'\n", path, u.String());
+ NSLOG(netsurf, INFO, "(%s) -> '%s'\n", path, u.String());
nsurl_create(u.String(), &url);
return url;
}
@@ -588,7 +589,7 @@ static void gui_init(int argc, char** argv)
die("Unable to load throbber image.\n");
find_resource(buf, "Choices", "%/Choices");
- LOG("Using '%s' as Preferences file", buf);
+ NSLOG(netsurf, INFO, "Using '%s' as Preferences file", buf);
options_file_location = strdup(buf);
nsoption_read(buf, NULL);
@@ -631,12 +632,12 @@ static void gui_init(int argc, char** argv)
if (nsoption_charp(cookie_file) == NULL) {
find_resource(buf, "Cookies", "%/Cookies");
- LOG("Using '%s' as Cookies file", buf);
+ NSLOG(netsurf, INFO, "Using '%s' as Cookies file", buf);
nsoption_set_charp(cookie_file, strdup(buf));
}
if (nsoption_charp(cookie_jar) == NULL) {
find_resource(buf, "Cookies", "%/Cookies");
- LOG("Using '%s' as Cookie Jar file", buf);
+ NSLOG(netsurf, INFO, "Using '%s' as Cookie Jar file", buf);
nsoption_set_charp(cookie_jar, strdup(buf));
}
if ((nsoption_charp(cookie_file) == NULL) ||
@@ -645,13 +646,13 @@ static void gui_init(int argc, char** argv)
if (nsoption_charp(url_file) == NULL) {
find_resource(buf, "URLs", "%/URLs");
- LOG("Using '%s' as URL file", buf);
+ NSLOG(netsurf, INFO, "Using '%s' as URL file", buf);
nsoption_set_charp(url_file, strdup(buf));
}
if (nsoption_charp(ca_path) == NULL) {
find_resource(buf, "certs", "/etc/ssl/certs");
- LOG("Using '%s' as certificate path", buf);
+ NSLOG(netsurf, INFO, "Using '%s' as certificate path", buf);
nsoption_set_charp(ca_path, strdup(buf));
}
@@ -763,17 +764,21 @@ void nsbeos_gui_poll(void)
timeout.tv_sec = (long)(next_schedule / 1000000LL);
timeout.tv_usec = (long)(next_schedule % 1000000LL);
- //LOG("gui_poll: select(%d, ..., %Ldus", max_fd, next_schedule);
+ NSLOG(netsurf, DEEPDEBUG,
+ "gui_poll: select(%d, ..., %Ldus",
+ max_fd, next_schedule);
fd_count = select(max_fd, &read_fd_set, &write_fd_set, &exc_fd_set,
&timeout);
- //LOG("select: %d\n", fd_count);
+ NSLOG(netsurf, DEEPDEBUG, "select: %d\n", fd_count);
if (fd_count > 0 && FD_ISSET(sEventPipe[0], &read_fd_set)) {
BMessage *message;
int len = read(sEventPipe[0], &message, sizeof(void *));
- //LOG("gui_poll: BMessage ? %d read", len);
+ NSLOG(netsurf, DEEPDEBUG, "gui_poll: BMessage ? %d read", len);
if (len == sizeof(void *)) {
- //LOG("gui_poll: BMessage.what %-4.4s\n", &(message->what));
+ NSLOG(netsurf, DEEPDEBUG,
+ "gui_poll: BMessage.what %-4.4s\n",
+ &(message->what));
nsbeos_dispatch_event(message);
}
}
@@ -1038,7 +1043,7 @@ int main(int argc, char** argv)
char path[12];
sprintf(path,"%.2s/Messages", getenv("LC_MESSAGES"));
- LOG("Loading messages from resource %s\n", path);
+ NSLOG(netsurf, INFO, "Loading messages from resource %s\n", path);
const uint8_t* res = (const uint8_t*)resources.LoadResource('data', path, &size);
if (size > 0 && res != NULL) {
@@ -1061,6 +1066,12 @@ int main(int argc, char** argv)
netsurf_exit();
+ /* finalise options */
+ nsoption_finalise(nsoptions, nsoptions_default);
+
+ /* finalise logging */
+ nslog_finalise();
+
return 0;
}
diff --git a/frontends/beos/plotters.cpp b/frontends/beos/plotters.cpp
index c77e6353e..c4903e045 100644
--- a/frontends/beos/plotters.cpp
+++ b/frontends/beos/plotters.cpp
@@ -538,7 +538,7 @@ nsbeos_plot_path(const struct redraw_context *ctx,
}
if (p[0] != PLOTTER_PATH_MOVE) {
- LOG("path doesn't start with a move");
+ NSLOG(netsurf, INFO, "path doesn't start with a move");
return NSERROR_INVALID;
}
@@ -563,7 +563,7 @@ nsbeos_plot_path(const struct redraw_context *ctx,
shape.BezierTo(pt);
i += 7;
} else {
- LOG("bad path command %f", p[i]);
+ NSLOG(netsurf, INFO, "bad path command %f", p[i]);
return NSERROR_INVALID;
}
}
diff --git a/frontends/beos/scaffolding.cpp b/frontends/beos/scaffolding.cpp
index 7efdb5962..e6fb6e5a1 100644
--- a/frontends/beos/scaffolding.cpp
+++ b/frontends/beos/scaffolding.cpp
@@ -796,7 +796,7 @@ int32 nsbeos_replicant_main_thread(void *_arg)
static void nsbeos_window_destroy_event(NSBrowserWindow *window, nsbeos_scaffolding *g, BMessage *event)
{
- LOG("Being Destroyed = %d", g->being_destroyed);
+ NSLOG(netsurf, INFO, "Being Destroyed = %d", g->being_destroyed);
if (--open_windows == 0)
nsbeos_done = true;
@@ -854,7 +854,9 @@ void nsbeos_scaffolding_dispatch_event(nsbeos_scaffolding *scaffold, BMessage *m
bw = nsbeos_get_browser_for_gui(scaffold->top_level);
bool reloadAll = false;
- LOG("nsbeos_scaffolding_dispatch_event() what = 0x%08lx", message->what);
+ NSLOG(netsurf, INFO,
+ "nsbeos_scaffolding_dispatch_event() what = 0x%08lx",
+ message->what);
switch (message->what) {
case B_QUIT_REQUESTED:
nsbeos_scaffolding_destroy(scaffold);
@@ -997,7 +999,7 @@ void nsbeos_scaffolding_dispatch_event(nsbeos_scaffolding *scaffold, BMessage *m
browser_window_key_press(bw, NS_KEY_PASTE);
break;
case B_SELECT_ALL:
- LOG("Selecting all text");
+ NSLOG(netsurf, INFO, "Selecting all text");
browser_window_key_press(bw, NS_KEY_SELECT_ALL);
break;
case B_NETPOSITIVE_BACK:
@@ -1359,7 +1361,8 @@ void nsbeos_scaffolding_dispatch_event(nsbeos_scaffolding *scaffold, BMessage *m
void nsbeos_scaffolding_destroy(nsbeos_scaffolding *scaffold)
{
- LOG("Being Destroyed = %d", scaffold->being_destroyed);
+ NSLOG(netsurf, INFO, "Being Destroyed = %d",
+ scaffold->being_destroyed);
if (scaffold->being_destroyed) return;
scaffold->being_destroyed = 1;
nsbeos_window_destroy_event(scaffold->window, scaffold, NULL);
@@ -1444,7 +1447,7 @@ static void recursively_set_menu_items_target(BMenu *menu, BHandler *handler)
void nsbeos_attach_toplevel_view(nsbeos_scaffolding *g, BView *view)
{
- LOG("Attaching view to scaffolding %p", g);
+ NSLOG(netsurf, INFO, "Attaching view to scaffolding %p", g);
// this is a replicant,... and it went bad
if (!g->window) {
@@ -1722,7 +1725,8 @@ nsbeos_scaffolding *nsbeos_new_scaffolding(struct gui_window *toplevel)
{
struct beos_scaffolding *g = (struct beos_scaffolding *)malloc(sizeof(*g));
- LOG("Constructing a scaffold of %p for gui_window %p", g, toplevel);
+ NSLOG(netsurf, INFO,
+ "Constructing a scaffold of %p for gui_window %p", g, toplevel);
g->top_level = toplevel;
g->being_destroyed = 0;
diff --git a/frontends/beos/schedule.cpp b/frontends/beos/schedule.cpp
index e96e56d81..7877a838b 100644
--- a/frontends/beos/schedule.cpp
+++ b/frontends/beos/schedule.cpp
@@ -28,11 +28,7 @@ extern "C" {
#include "netsurf/content_type.h"
#include "netsurf/browser_window.h"
-#ifdef DEBUG_BEOS_SCHEDULE
#include "utils/log.h"
-#else
-#define LOG(x...)
-#endif
}
/** Killable callback closure embodiment. */
@@ -58,7 +54,10 @@ nsbeos_schedule_kill_callback(void *_target, void *_match)
_nsbeos_callback_t *match = (_nsbeos_callback_t *)_match;
if ((target->callback == match->callback) &&
(target->context == match->context)) {
- LOG("Found match for %p(%p), killing.", target->callback, target->context);
+ NSLOG(schedule, DEBUG,
+ "Found match for %p(%p), killing.",
+ target->callback,
+ target->context);
target->callback = NULL;
target->context = NULL;
target->callback_killed = true;
@@ -69,7 +68,9 @@ nsbeos_schedule_kill_callback(void *_target, void *_match)
static void
schedule_remove(void (*callback)(void *p), void *p)
{
- LOG("schedule_remove() for %p(%p)", cb->callback, cb->context);
+ NSLOG(schedule, DEBUG,
+ "schedule_remove() for %p(%p)",
+ callback, p);
if (callbacks == NULL)
return;
_nsbeos_callback_t cb_match;
@@ -81,7 +82,7 @@ schedule_remove(void (*callback)(void *p), void *p)
nserror beos_schedule(int t, void (*callback)(void *p), void *p)
{
- LOG("t:%d cb:%p p:%p", t, cb->callback, cb->context);
+ NSLOG(schedule, DEBUG, "t:%d cb:%p p:%p", t, callback, p);
if (callbacks == NULL) {
callbacks = new BList;
@@ -111,7 +112,7 @@ nserror beos_schedule(int t, void (*callback)(void *p), void *p)
bool
schedule_run(void)
{
- LOG("schedule_run()");
+ NSLOG(schedule, DEBUG, "schedule_run()");
earliest_callback_timeout = B_INFINITE_TIMEOUT;
if (callbacks == NULL)
@@ -120,7 +121,9 @@ schedule_run(void)
bigtime_t now = system_time();
int32 i;
- LOG("Checking %ld callbacks to for deadline.", this_run->CountItems());
+ NSLOG(schedule, DEBUG,
+ "Checking %ld callbacks to for deadline.",
+ callbacks->CountItems());
/* Run all the callbacks which made it this far. */
for (i = 0; i < callbacks->CountItems(); ) {
@@ -132,7 +135,11 @@ schedule_run(void)
i++;
continue;
}
- LOG("Running callbacks %p(%p).", cb->callback, cb->context);
+ NSLOG(schedule, DEBUG,
+ "Running callbacks %p(%p).",
+ cb->callback,
+ cb->context);
+
if (!cb->callback_killed)
cb->callback(cb->context);
callbacks->RemoveItem(cb);
diff --git a/frontends/beos/throbber.cpp b/frontends/beos/throbber.cpp
index fe40b3edc..315afef83 100644
--- a/frontends/beos/throbber.cpp
+++ b/frontends/beos/throbber.cpp
@@ -50,18 +50,21 @@ bool nsbeos_throbber_initialise_from_png(const int frames, ...)
if (frames < 2) {
/* we need at least two frames - one for idle, one for active */
- LOG("Insufficent number of frames in throbber animation!");
- LOG("(called with %d frames, where 2 is a minimum.)", frames);
+ NSLOG(netsurf, INFO,
+ "Insufficent number of frames in throbber animation!");
+ NSLOG(netsurf, INFO,
+ "(called with %d frames, where 2 is a minimum.)",
+ frames);
return false;
}
BResources *res = get_app_resources();
if (res == NULL) {
- LOG("Can't find resources for throbber!");
+ NSLOG(netsurf, INFO, "Can't find resources for throbber!");
return false;
}
- throb = (struct nsbeos_throbber *)malloc(sizeof(throb));
+ throb = (struct nsbeos_throbber *)malloc(sizeof(*throb));
throb->nframes = frames;
throb->framedata = (BBitmap **)malloc(sizeof(BBitmap *) * throb->nframes);
@@ -74,14 +77,17 @@ bool nsbeos_throbber_initialise_from_png(const int frames, ...)
data = res->LoadResource('data', fn, &size);
throb->framedata[i] = NULL;
if (!data) {
- LOG("Error when loading resource %s", fn);
+ NSLOG(netsurf, INFO, "Error when loading resource %s",
+ fn);
errors_when_loading = true;
continue;
}
BMemoryIO mem(data, size);
throb->framedata[i] = BTranslationUtils::GetBitmap(&mem);
if (throb->framedata[i] == NULL) {
- LOG("Error when loading %s: GetBitmap() returned NULL", fn);
+ NSLOG(netsurf, INFO,
+ "Error when loading %s: GetBitmap() returned NULL",
+ fn);
errors_when_loading = true;
}
}
diff --git a/frontends/beos/window.cpp b/frontends/beos/window.cpp
index 8acb20a37..f4229207b 100644
--- a/frontends/beos/window.cpp
+++ b/frontends/beos/window.cpp
@@ -354,7 +354,8 @@ static struct gui_window *gui_window_create(struct browser_window *bw,
return 0;
}
- LOG("Creating gui window %p for browser window %p", g, bw);
+ NSLOG(netsurf, INFO, "Creating gui window %p for browser window %p",
+ g, bw);
g->bw = bw;
g->mouse.state = 0;
@@ -436,25 +437,27 @@ void nsbeos_dispatch_event(BMessage *message)
continue;
if (gui && gui != z) {
- LOG("discarding event for destroyed gui_window");
+ NSLOG(netsurf, INFO,
+ "discarding event for destroyed gui_window");
delete message;
return;
}
if (scaffold && (!y || scaffold != y->scaffold)) {
- LOG("discarding event for destroyed scaffolding");
+ NSLOG(netsurf, INFO,
+ "discarding event for destroyed scaffolding");
delete message;
return;
}
// messages for top-level
if (scaffold) {
- LOG("dispatching to top-level");
+ NSLOG(netsurf, INFO, "dispatching to top-level");
nsbeos_scaffolding_dispatch_event(scaffold, message);
delete message;
return;
}
- //LOG("processing message");
+ NSLOG(netsurf, DEEPDEBUG, "processing message");
switch (message->what) {
case B_QUIT_REQUESTED:
// from the BApplication
@@ -763,7 +766,8 @@ void nsbeos_window_keypress_event(BView *view, gui_window *g, BMessage *event)
if (!numbytes)
numbytes = strlen(bytes);
- LOG("mods 0x%08lx key %ld raw %ld byte[0] %d", mods, key, raw_char, buff[0]);
+ NSLOG(netsurf, INFO, "mods 0x%08lx key %ld raw %ld byte[0] %d", mods,
+ key, raw_char, buff[0]);
char byte;
if (numbytes == 1) {
@@ -930,10 +934,10 @@ static void gui_window_destroy(struct gui_window *g)
g->next->prev = g->prev;
- LOG("Destroying gui_window %p", g);
+ NSLOG(netsurf, INFO, "Destroying gui_window %p", g);
assert(g != NULL);
assert(g->bw != NULL);
- LOG(" Scaffolding: %p", g->scaffold);
+ NSLOG(netsurf, INFO, " Scaffolding: %p", g->scaffold);
if (g->view == NULL)
return;
@@ -1000,8 +1004,6 @@ beos_window_invalidate_area(struct gui_window *g, const struct rect *rect)
return NSERROR_OK;
}
- nsbeos_current_gc_set(g->view);
-
if (rect != NULL) {
//XXX +1 ??
g->view->Invalidate(BRect(rect->x0, rect->y0,
@@ -1010,7 +1012,6 @@ beos_window_invalidate_area(struct gui_window *g, const struct rect *rect)
g->view->Invalidate();
}
- nsbeos_current_gc_set(NULL);
g->view->UnlockLooper();
return NSERROR_OK;
@@ -1093,8 +1094,9 @@ static void gui_window_update_extent(struct gui_window *g)
x_max -= g->view->Bounds().Width() + 1;
y_max -= g->view->Bounds().Height() + 1;
- LOG("x_max = %d y_max = %d x_prop = %f y_prop = %f\n",
- x_max, y_max, x_prop, y_prop);
+ NSLOG(netsurf, INFO,
+ "x_max = %d y_max = %d x_prop = %f y_prop = %f\n", x_max,
+ y_max, x_prop, y_prop);
if (g->view->ScrollBar(B_HORIZONTAL)) {
g->view->ScrollBar(B_HORIZONTAL)->SetRange(0, x_max);
diff --git a/frontends/framebuffer/bitmap.c b/frontends/framebuffer/bitmap.c
index 027e0122b..1fc9f46a2 100644
--- a/frontends/framebuffer/bitmap.c
+++ b/frontends/framebuffer/bitmap.c
@@ -51,7 +51,8 @@ static void *bitmap_create(int width, int height, unsigned int state)
{
nsfb_t *bm;
- LOG("width %d, height %d, state %u", width, height, state);
+ NSLOG(netsurf, INFO, "width %d, height %d, state %u", width, height,
+ state);
bm = nsfb_new(NSFB_SURFACE_RAM);
if (bm == NULL) {
@@ -69,7 +70,7 @@ static void *bitmap_create(int width, int height, unsigned int state)
return NULL;
}
- LOG("bitmap %p", bm);
+ NSLOG(netsurf, INFO, "bitmap %p", bm);
return bm;
}
@@ -197,11 +198,11 @@ static bool bitmap_test_opaque(void *bitmap)
while (tst-- > 0) {
if (bmpptr[(tst << 2) + 3] != 0xff) {
- LOG("bitmap %p has transparency", bm);
+ NSLOG(netsurf, INFO, "bitmap %p has transparency", bm);
return false;
}
}
- LOG("bitmap %p is opaque", bm);
+ NSLOG(netsurf, INFO, "bitmap %p is opaque", bm);
return true;
}
@@ -282,14 +283,14 @@ bitmap_render(struct bitmap *bitmap,
nsfb_get_geometry(tbm, &width, &height, NULL);
- LOG("width %d, height %d", width, height);
+ NSLOG(netsurf, INFO, "width %d, height %d", width, height);
/* Calculate size of buffer to render the content into */
- /* We get the width from the content width, unless it exceeds 1024,
- * in which case we use 1024. This means we never create excessively
- * large render buffers for huge contents, which would eat memory and
- * cripple performance. */
- cwidth = min(content_get_width(content), 1024);
+ /* We get the width from the largest of the bitmap width and the content
+ * width, unless it exceeds 1024, in which case we use 1024. This means
+ * we never create excessively large render buffers for huge contents,
+ * which would eat memory and cripple performance. */
+ cwidth = max(width, min(content_get_width(content), 1024));
/* The height is set in proportion with the width, according to the
* aspect ratio of the required thumbnail. */
cheight = ((cwidth * height) + (width / 2)) / width;
diff --git a/frontends/framebuffer/clipboard.c b/frontends/framebuffer/clipboard.c
index 1254c36f3..20a00e038 100644
--- a/frontends/framebuffer/clipboard.c
+++ b/frontends/framebuffer/clipboard.c
@@ -53,8 +53,8 @@ static void gui_get_clipboard(char **buffer, size_t *length)
if (gui_clipboard.length > 0) {
assert(gui_clipboard.buffer != NULL);
- LOG("Pasting %zd bytes: \"%s\"\n",
- gui_clipboard.length, gui_clipboard.buffer);
+ NSLOG(netsurf, INFO, "Pasting %zd bytes: \"%s\"\n",
+ gui_clipboard.length, gui_clipboard.buffer);
*buffer = malloc(gui_clipboard.length);
diff --git a/frontends/framebuffer/fbtk.h b/frontends/framebuffer/fbtk.h
index 3cc326cef..86bdc864b 100644
--- a/frontends/framebuffer/fbtk.h
+++ b/frontends/framebuffer/fbtk.h
@@ -21,12 +21,6 @@
#include "netsurf/types.h"
-#ifdef FBTK_LOGGING
-#define FBTK_LOG(x) LOG(x)
-#else
-#define FBTK_LOG(x)
-#endif
-
#define FB_SCROLL_COLOUR 0xFFAAAAAA
#define FB_FRAME_COLOUR 0xFFDDDDDD
#define FB_COLOUR_BLACK 0xFF000000
diff --git a/frontends/framebuffer/fbtk/event.c b/frontends/framebuffer/fbtk/event.c
index a48e63809..84c6c3791 100644
--- a/frontends/framebuffer/fbtk/event.c
+++ b/frontends/framebuffer/fbtk/event.c
@@ -51,7 +51,7 @@ fbtk_input(fbtk_widget_t *root, nsfb_event_t *event)
/* obtain widget with input focus */
input = root->u.root.input;
if (input == NULL) {
- LOG("No widget has input focus.");
+ NSLOG(netsurf, INFO, "No widget has input focus.");
return; /* no widget with input */
}
@@ -84,7 +84,7 @@ fbtk_click(fbtk_widget_t *widget, nsfb_event_t *event)
x = fbtk_get_absx(clicked);
y = fbtk_get_absy(clicked);
- LOG("clicked %p at %d,%d", clicked, x, y);
+ NSLOG(netsurf, INFO, "clicked %p at %d,%d", clicked, x, y);
/* post the click */
fbtk_post_callback(clicked, FBTK_CBT_CLICK, event, cloc.x0 - x, cloc.y0 - y);
diff --git a/frontends/framebuffer/fbtk/fbtk.c b/frontends/framebuffer/fbtk/fbtk.c
index c63a6d8c9..91f6e2570 100644
--- a/frontends/framebuffer/fbtk/fbtk.c
+++ b/frontends/framebuffer/fbtk/fbtk.c
@@ -53,7 +53,7 @@ dump_tk_tree(fbtk_widget_t *widget)
int indent = 0;
while (widget != NULL) {
- LOG("%*s%p", indent, "", widget);
+ NSLOG(fbtk, DEBUG, "%*s%p", indent, "", widget);
if (widget->first_child != NULL) {
widget = widget->first_child;
indent += 6;
@@ -100,9 +100,13 @@ fbtk_request_redraw(fbtk_widget_t *widget)
widget->redraw.width = widget->width;
widget->redraw.height = widget->height;
-#ifdef FBTK_LOGGING
- LOG("redrawing %p %d,%d %d,%d", widget, widget->redraw.x, widget->redraw.y, widget->redraw.width, widget->redraw.height);
-#endif
+ NSLOG(fbtk, DEBUG,
+ "redrawing %p %d,%d %d,%d",
+ widget,
+ widget->redraw.x,
+ widget->redraw.y,
+ widget->redraw.width,
+ widget->redraw.height);
cwidget = widget->last_child;
while (cwidget != NULL) {
@@ -122,7 +126,7 @@ fbtk_request_redraw(fbtk_widget_t *widget)
int
fbtk_set_mapping(fbtk_widget_t *widget, bool map)
{
- LOG("setting mapping on %p to %d", widget, map);
+ NSLOG(netsurf, INFO, "setting mapping on %p to %d", widget, map);
widget->mapped = map;
if (map) {
fbtk_request_redraw(widget);
@@ -132,9 +136,11 @@ fbtk_set_mapping(fbtk_widget_t *widget, bool map)
return 0;
}
-/** swap the widget given with the next sibling.
- *
+
+/**
* Swap a sibling widget with the next deepest in the hierachy
+ *
+ * \param lw The widget to swap
*/
static void
swap_siblings(fbtk_widget_t *lw)
@@ -145,7 +151,7 @@ swap_siblings(fbtk_widget_t *lw)
assert(rw != NULL);
- LOG("Swapping %p with %p", lw, rw);
+ NSLOG(netsurf, INFO, "Swapping %p with %p", lw, rw);
before = lw->prev;
after = rw->next;
@@ -401,7 +407,6 @@ fbtk_set_ptr(fbtk_widget_t *widget, fbtk_callback_info *cbi)
}
-
/* internally exported function documented in widget.h */
fbtk_widget_t *
fbtk_get_root_widget(fbtk_widget_t *widget)
@@ -411,7 +416,8 @@ fbtk_get_root_widget(fbtk_widget_t *widget)
/* check root widget was found */
if (widget->type != FB_WIDGET_TYPE_ROOT) {
- LOG("Widget with null parent that is not the root widget!");
+ NSLOG(netsurf, INFO,
+ "Widget with null parent that is not the root widget!");
return NULL;
}
@@ -433,6 +439,7 @@ fbtk_get_absx(fbtk_widget_t *widget)
return x;
}
+
/* exported function documented in fbtk.h */
int
fbtk_get_absy(fbtk_widget_t *widget)
@@ -447,6 +454,7 @@ fbtk_get_absy(fbtk_widget_t *widget)
return y;
}
+
/* exported function documented in fbtk.h */
int
fbtk_get_height(fbtk_widget_t *widget)
@@ -551,9 +559,7 @@ fbtk_widget_new(fbtk_widget_t *parent,
if (neww == NULL)
return NULL;
-#ifdef FBTK_LOGGING
- LOG("creating %p %d,%d %d,%d", neww, x, y, width, height);
-#endif
+ NSLOG(fbtk, DEBUG, "creating %p %d,%d %d,%d", neww, x, y, width, height);
/* make new window fit inside parent */
if (width == 0) {
@@ -574,9 +580,8 @@ fbtk_widget_new(fbtk_widget_t *parent,
height = parent->height - y;
}
-#ifdef FBTK_LOGGING
- LOG("using %p %d,%d %d,%d", neww, x, y, width, height);
-#endif
+ NSLOG(fbtk, DEBUG, "using %p %d,%d %d,%d", neww, x, y, width, height);
+
/* set values */
neww->type = type;
neww->x = x;
@@ -634,9 +639,12 @@ do_redraw(nsfb_t *nsfb, fbtk_widget_t *widget)
plot_ctx.x1 = plot_ctx.x0 + widget->redraw.width;
plot_ctx.y1 = plot_ctx.y0 + widget->redraw.height;
-#ifdef FBTK_LOGGING
- LOG("clipping %p %d,%d %d,%d", widget, plot_ctx.x0, plot_ctx.y0, plot_ctx.x1, plot_ctx.y1);
-#endif
+ NSLOG(fbtk, DEBUG,
+ "clipping %p %d,%d %d,%d",
+ widget,
+ plot_ctx.x0, plot_ctx.y0,
+ plot_ctx.x1, plot_ctx.y1);
+
if (nsfb_plot_set_clip(nsfb, &plot_ctx) == true) {
fbtk_post_callback(widget, FBTK_CBT_REDRAW);
}
diff --git a/frontends/framebuffer/fbtk/scroll.c b/frontends/framebuffer/fbtk/scroll.c
index cc98fb2dd..b056ac81f 100644
--- a/frontends/framebuffer/fbtk/scroll.c
+++ b/frontends/framebuffer/fbtk/scroll.c
@@ -334,7 +334,7 @@ hscroll_redraw(fbtk_widget_t *widget, fbtk_callback_info *cbi)
hpos = 0;
}
- LOG("hscroll %d", hscroll);
+ NSLOG(netsurf, INFO, "hscroll %d", hscroll);
rect.x0 = bbox.x0 + 3 + hpos;
rect.y0 = bbox.y0 + 5;
@@ -362,7 +362,7 @@ hscrolll_click(fbtk_widget_t *widget, fbtk_callback_info *cbi)
newpos = scrollw->u.scroll.minimum;
if (newpos == scrollw->u.scroll.position) {
- LOG("horiz scroll was the same %d", newpos);
+ NSLOG(netsurf, INFO, "horiz scroll was the same %d", newpos);
return 0;
}
diff --git a/frontends/framebuffer/fbtk/text.c b/frontends/framebuffer/fbtk/text.c
index 31417c2e0..4f3a2385d 100644
--- a/frontends/framebuffer/fbtk/text.c
+++ b/frontends/framebuffer/fbtk/text.c
@@ -388,6 +388,22 @@ text_input(fbtk_widget_t *widget, fbtk_callback_info *cbi)
}
break;
+ case NSFB_KEY_HOME:
+ if (widget->u.text.idx > 0) {
+ widget->u.text.idx = 0;
+
+ caret_moved = true;
+ }
+ break;
+
+ case NSFB_KEY_END:
+ if (widget->u.text.idx < widget->u.text.len) {
+ widget->u.text.idx = widget->u.text.len;
+
+ caret_moved = true;
+ }
+ break;
+
case NSFB_KEY_PAGEUP:
case NSFB_KEY_PAGEDOWN:
case NSFB_KEY_UP:
diff --git a/frontends/framebuffer/fetch.c b/frontends/framebuffer/fetch.c
index 801b87a74..23cbb4f21 100644
--- a/frontends/framebuffer/fetch.c
+++ b/frontends/framebuffer/fetch.c
@@ -65,7 +65,7 @@ static nsurl *get_resource_url(const char *path)
static const char *fetch_filetype(const char *unix_path)
{
int l;
- LOG("unix path %s", unix_path);
+ NSLOG(netsurf, INFO, "unix path %s", unix_path);
l = strlen(unix_path);
if (2 < l && strcasecmp(unix_path + l - 3, "css") == 0)
return "text/css";
diff --git a/frontends/framebuffer/font_freetype.c b/frontends/framebuffer/font_freetype.c
index e7c07f5ff..9e47e4b99 100644
--- a/frontends/framebuffer/font_freetype.c
+++ b/frontends/framebuffer/font_freetype.c
@@ -90,12 +90,13 @@ ft_face_requester(FTC_FaceID face_id,
error = FT_New_Face(library, fb_face->fontfile, fb_face->index, face);
if (error) {
- LOG("Could not find font (code %d)", error);
+ NSLOG(netsurf, INFO, "Could not find font (code %d)", error);
} else {
error = FT_Select_Charmap(*face, FT_ENCODING_UNICODE);
if (error) {
- LOG("Could not select charmap (code %d)", error);
+ NSLOG(netsurf, INFO,
+ "Could not select charmap (code %d)", error);
} else {
for (cidx = 0; cidx < (*face)->num_charmaps; cidx++) {
if ((*face)->charmap == (*face)->charmaps[cidx]) {
@@ -105,7 +106,7 @@ ft_face_requester(FTC_FaceID face_id,
}
}
}
- LOG("Loaded face from %s", fb_face->fontfile);
+ NSLOG(netsurf, INFO, "Loaded face from %s", fb_face->fontfile);
return error;
}
@@ -132,7 +133,8 @@ fb_new_face(const char *option, const char *resname, const char *fontname)
error = FTC_Manager_LookupFace(ft_cmanager, (FTC_FaceID)newf, &aface);
if (error) {
- LOG("Could not find font face %s (code %d)", fontname, error);
+ NSLOG(netsurf, INFO, "Could not find font face %s (code %d)",
+ fontname, error);
free(newf->fontfile);
free(newf);
newf = NULL;
@@ -152,7 +154,8 @@ bool fb_font_init(void)
/* freetype library initialise */
error = FT_Init_FreeType( &library );
if (error) {
- LOG("Freetype could not initialised (code %d)", error);
+ NSLOG(netsurf, INFO,
+ "Freetype could not initialised (code %d)", error);
return false;
}
@@ -172,7 +175,9 @@ bool fb_font_init(void)
NULL,
&ft_cmanager);
if (error) {
- LOG("Freetype could not initialise cache manager (code %d)", error);
+ NSLOG(netsurf, INFO,
+ "Freetype could not initialise cache manager (code %d)",
+ error);
FT_Done_FreeType(library);
return false;
}
@@ -189,7 +194,7 @@ bool fb_font_init(void)
NETSURF_FB_FONT_SANS_SERIF);
if (fb_face == NULL) {
/* The sans serif font is the default and must be found. */
- LOG("Could not find the default font");
+ NSLOG(netsurf, INFO, "Could not find the default font");
FTC_Manager_Done(ft_cmanager);
FT_Done_FreeType(library);
return false;
diff --git a/frontends/framebuffer/framebuffer.c b/frontends/framebuffer/framebuffer.c
index de8a3695d..2ccc75062 100644
--- a/frontends/framebuffer/framebuffer.c
+++ b/frontends/framebuffer/framebuffer.c
@@ -271,7 +271,7 @@ framebuffer_plot_path(const struct redraw_context *ctx,
float width,
const float transform[6])
{
- LOG("path unimplemented");
+ NSLOG(netsurf, INFO, "path unimplemented");
return NSERROR_OK;
}
@@ -564,7 +564,7 @@ static bool framebuffer_format_from_bpp(int bpp, enum nsfb_format_e *fmt)
break;
default:
- LOG("Bad bits per pixel (%d)\n", bpp);
+ NSLOG(netsurf, INFO, "Bad bits per pixel (%d)\n", bpp);
return false;
}
@@ -586,18 +586,19 @@ framebuffer_initialise(const char *fename, int width, int height, int bpp)
fbtype = nsfb_type_from_name(fename);
if (fbtype == NSFB_SURFACE_NONE) {
- LOG("The %s surface is not available from libnsfb\n", fename);
+ NSLOG(netsurf, INFO,
+ "The %s surface is not available from libnsfb\n", fename);
return NULL;
}
nsfb = nsfb_new(fbtype);
if (nsfb == NULL) {
- LOG("Unable to create %s fb surface\n", fename);
+ NSLOG(netsurf, INFO, "Unable to create %s fb surface\n", fename);
return NULL;
}
if (nsfb_set_geometry(nsfb, width, height, fbfmt) == -1) {
- LOG("Unable to set surface geometry\n");
+ NSLOG(netsurf, INFO, "Unable to set surface geometry\n");
nsfb_free(nsfb);
return NULL;
}
@@ -605,7 +606,7 @@ framebuffer_initialise(const char *fename, int width, int height, int bpp)
nsfb_cursor_init(nsfb);
if (nsfb_init(nsfb) == -1) {
- LOG("Unable to initialise nsfb surface\n");
+ NSLOG(netsurf, INFO, "Unable to initialise nsfb surface\n");
nsfb_free(nsfb);
return NULL;
}
@@ -625,7 +626,7 @@ framebuffer_resize(nsfb_t *nsfb, int width, int height, int bpp)
}
if (nsfb_set_geometry(nsfb, width, height, fbfmt) == -1) {
- LOG("Unable to change surface geometry\n");
+ NSLOG(netsurf, INFO, "Unable to change surface geometry\n");
return false;
}
diff --git a/frontends/framebuffer/gui.c b/frontends/framebuffer/gui.c
index 1460c77f6..e252f25f3 100644
--- a/frontends/framebuffer/gui.c
+++ b/frontends/framebuffer/gui.c
@@ -120,7 +120,7 @@ static void die(const char *error)
*/
static nserror fb_warn_user(const char *warning, const char *detail)
{
- LOG("%s %s", warning, detail);
+ NSLOG(netsurf, INFO, "%s %s", warning, detail);
return NSERROR_OK;
}
@@ -153,7 +153,7 @@ widget_scroll_y(struct gui_window *gw, int y, bool abs)
int content_width, content_height;
int height;
- LOG("window scroll");
+ NSLOG(netsurf, INFO, "window scroll");
if (abs) {
bwidget->pany = y - bwidget->scrolly;
} else {
@@ -237,7 +237,7 @@ fb_pan(fbtk_widget_t *widget,
height = fbtk_get_height(widget);
width = fbtk_get_width(widget);
- LOG("panning %d, %d", bwidget->panx, bwidget->pany);
+ NSLOG(netsurf, INFO, "panning %d, %d", bwidget->panx, bwidget->pany);
x = fbtk_get_absx(widget);
y = fbtk_get_absy(widget);
@@ -413,7 +413,8 @@ fb_browser_window_redraw(fbtk_widget_t *widget, fbtk_callback_info *cbi)
bwidget = fbtk_get_userpw(widget);
if (bwidget == NULL) {
- LOG("browser widget from widget %p was null", widget);
+ NSLOG(netsurf, INFO,
+ "browser widget from widget %p was null", widget);
return -1;
}
@@ -465,7 +466,7 @@ process_cmdline(int argc, char** argv)
{0, 0, 0, 0 }
}; /* no long options */
- LOG("argc %d, argv %p", argc, argv);
+ NSLOG(netsurf, INFO, "argc %d, argv %p", argc, argv);
fename = "sdl";
febpp = 32;
@@ -534,7 +535,7 @@ static nserror set_defaults(struct nsoption_s *defaults)
if (nsoption_charp(cookie_file) == NULL ||
nsoption_charp(cookie_jar) == NULL) {
- LOG("Failed initialising cookie options");
+ NSLOG(netsurf, INFO, "Failed initialising cookie options");
return NSERROR_BAD_PARAMETER;
}
@@ -612,7 +613,7 @@ static void framebuffer_run(void)
static void gui_quit(void)
{
- LOG("gui_quit");
+ NSLOG(netsurf, INFO, "gui_quit");
urldb_save_cookies(nsoption_charp(cookie_jar));
@@ -639,7 +640,8 @@ fb_browser_window_click(fbtk_widget_t *widget, fbtk_callback_info *cbi)
cbi->event->type != NSFB_EVENT_KEY_UP)
return 0;
- LOG("browser window clicked at %d,%d", cbi->x, cbi->y);
+ NSLOG(netsurf, INFO, "browser window clicked at %d,%d", cbi->x,
+ cbi->y);
switch (cbi->event->type) {
case NSFB_EVENT_KEY_DOWN:
@@ -824,7 +826,7 @@ fb_browser_window_input(fbtk_widget_t *widget, fbtk_callback_info *cbi)
static fbtk_modifier_type modifier = FBTK_MOD_CLEAR;
int ucs4 = -1;
- LOG("got value %d", cbi->event->value.keycode);
+ NSLOG(netsurf, INFO, "got value %d", cbi->event->value.keycode);
switch (cbi->event->type) {
case NSFB_EVENT_KEY_DOWN:
@@ -1200,7 +1202,7 @@ create_toolbar(struct gui_window *gw,
toolbar_layout = NSFB_TOOLBAR_DEFAULT_LAYOUT;
}
- LOG("Using toolbar layout %s", toolbar_layout);
+ NSLOG(netsurf, INFO, "Using toolbar layout %s", toolbar_layout);
itmtype = toolbar_layout;
@@ -1234,7 +1236,7 @@ create_toolbar(struct gui_window *gw,
(*itmtype != 0) &&
(xdir !=0)) {
- LOG("toolbar adding %c", *itmtype);
+ NSLOG(netsurf, INFO, "toolbar adding %c", *itmtype);
switch (*itmtype) {
@@ -1376,7 +1378,9 @@ create_toolbar(struct gui_window *gw,
default:
widget = NULL;
xdir = 0;
- LOG("Unknown element %c in toolbar layout", *itmtype);
+ NSLOG(netsurf, INFO,
+ "Unknown element %c in toolbar layout",
+ *itmtype);
break;
}
@@ -1385,7 +1389,7 @@ create_toolbar(struct gui_window *gw,
xpos += (xdir * (fbtk_get_width(widget) + padding));
}
- LOG("xpos is %d", xpos);
+ NSLOG(netsurf, INFO, "xpos is %d", xpos);
itmtype += xdir;
}
@@ -1595,7 +1599,7 @@ create_normal_browser_window(struct gui_window *gw, int furniture_width)
int statusbar_width = 0;
int toolbar_height = nsoption_int(fb_toolbar_size);
- LOG("Normal window");
+ NSLOG(netsurf, INFO, "Normal window");
gw->window = fbtk_create_window(fbtk, 0, 0, 0, 0, 0);
@@ -1626,7 +1630,8 @@ create_normal_browser_window(struct gui_window *gw, int furniture_width)
false);
fbtk_set_handler(gw->status, FBTK_CBT_POINTERENTER, set_ptr_default_move, NULL);
- LOG("status bar %p at %d,%d", gw->status, fbtk_get_absx(gw->status), fbtk_get_absy(gw->status));
+ NSLOG(netsurf, INFO, "status bar %p at %d,%d", gw->status,
+ fbtk_get_absx(gw->status), fbtk_get_absy(gw->status));
/* create horizontal scrollbar */
gw->hscroll = fbtk_create_hscroll(gw->window,
@@ -2183,7 +2188,7 @@ main(int argc, char** argv)
/* create an initial browser window */
- LOG("calling browser_window_create");
+ NSLOG(netsurf, INFO, "calling browser_window_create");
ret = nsurl_create(feurl, &url);
if (ret == NSERROR_OK) {
@@ -2205,11 +2210,14 @@ main(int argc, char** argv)
netsurf_exit();
if (fb_font_finalise() == false)
- LOG("Font finalisation failed.");
+ NSLOG(netsurf, INFO, "Font finalisation failed.");
/* finalise options */
nsoption_finalise(nsoptions, nsoptions_default);
+ /* finalise logging */
+ nslog_finalise();
+
return 0;
}
diff --git a/frontends/framebuffer/schedule.c b/frontends/framebuffer/schedule.c
index 581ad72f1..6d1711236 100644
--- a/frontends/framebuffer/schedule.c
+++ b/frontends/framebuffer/schedule.c
@@ -24,12 +24,6 @@
#include "framebuffer/schedule.h"
-#ifdef DEBUG_SCHEDULER
-#define SRLOG(x...) LOG(x)
-#else
-#define SRLOG(x...) ((void) 0)
-#endif
-
/* linked list of scheduled callbacks */
static struct nscallback *schedule_list = NULL;
@@ -63,7 +57,7 @@ static nserror schedule_remove(void (*callback)(void *p), void *p)
return NSERROR_OK;
}
- SRLOG("removing %p, %p", callback, p);
+ NSLOG(schedule, DEBUG, "removing %p, %p", callback, p);
cur_nscb = schedule_list;
prev_nscb = NULL;
@@ -73,7 +67,8 @@ static nserror schedule_remove(void (*callback)(void *p), void *p)
(cur_nscb->p == p)) {
/* item to remove */
- SRLOG("callback entry %p removing %p(%p)",
+ NSLOG(schedule, DEBUG,
+ "callback entry %p removing %p(%p)",
cur_nscb, cur_nscb->callback, cur_nscb->p);
/* remove callback */
@@ -109,7 +104,7 @@ nserror framebuffer_schedule(int tival, void (*callback)(void *p), void *p)
return ret;
}
- SRLOG("Adding %p(%p) in %d", callback, p, tival);
+ NSLOG(schedule, DEBUG, "Adding %p(%p) in %d", callback, p, tival);
tv.tv_sec = tival / 1000; /* miliseconds to seconds */
tv.tv_usec = (tival % 1000) * 1000; /* remainder to microseconds */
@@ -190,7 +185,9 @@ int schedule_run(void)
/* make rettime relative to now */
timersub(&nexttime, &tv, &rettime);
- SRLOG("returning time to next event as %ldms",(rettime.tv_sec * 1000) + (rettime.tv_usec / 1000));
+ NSLOG(schedule, DEBUG,
+ "returning time to next event as %ldms",
+ (rettime.tv_sec * 1000) + (rettime.tv_usec / 1000));
/* return next event time in milliseconds (24days max wait) */
return (rettime.tv_sec * 1000) + (rettime.tv_usec / 1000);
@@ -203,12 +200,14 @@ void list_schedule(void)
gettimeofday(&tv, NULL);
- LOG("schedule list at %ld:%ld", tv.tv_sec, tv.tv_usec);
+ NSLOG(netsurf, INFO, "schedule list at %ld:%ld", tv.tv_sec,
+ tv.tv_usec);
cur_nscb = schedule_list;
while (cur_nscb != NULL) {
- LOG("Schedule %p at %ld:%ld", cur_nscb, cur_nscb->tv.tv_sec, cur_nscb->tv.tv_usec);
+ NSLOG(netsurf, INFO, "Schedule %p at %ld:%ld", cur_nscb,
+ cur_nscb->tv.tv_sec, cur_nscb->tv.tv_usec);
cur_nscb = cur_nscb->next;
}
}
diff --git a/frontends/gtk/cookies.c b/frontends/gtk/cookies.c
index 500cd07f6..1f7833cca 100644
--- a/frontends/gtk/cookies.c
+++ b/frontends/gtk/cookies.c
@@ -164,8 +164,9 @@ static void nsgtk_cookies_init_menu(struct nsgtk_cookie_window *ncwin)
w = GTK_WIDGET(gtk_builder_get_object(ncwin->builder,
event->widget));
if (w == NULL) {
- LOG("Unable to connect menu widget ""%s""",
- event->widget);
+ NSLOG(netsurf, INFO,
+ "Unable to connect menu widget ""%s""",
+ event->widget);
} else {
g_signal_connect(G_OBJECT(w),
"activate",
@@ -253,7 +254,7 @@ static nserror nsgtk_cookies_init(void)
res = nsgtk_builder_new_from_resname("cookies", &ncwin->builder);
if (res != NSERROR_OK) {
- LOG("Cookie UI builder init failed");
+ NSLOG(netsurf, INFO, "Cookie UI builder init failed");
free(ncwin);
return res;
}
diff --git a/frontends/gtk/corewindow.c b/frontends/gtk/corewindow.c
index ddc61c717..6ca5d228f 100644
--- a/frontends/gtk/corewindow.c
+++ b/frontends/gtk/corewindow.c
@@ -145,6 +145,7 @@ nsgtk_cw_button_release_event(GtkWidget *widget,
{
struct nsgtk_corewindow *nsgtk_cw = (struct nsgtk_corewindow *)g;
struct nsgtk_corewindow_mouse *mouse = &nsgtk_cw->mouse_state;
+ bool was_drag = false;
/* only button 1 clicks are considered double clicks. If the
* mouse state is PRESS then we are waiting for a release to
@@ -168,9 +169,11 @@ nsgtk_cw_button_release_event(GtkWidget *widget,
} else if (mouse->state & BROWSER_MOUSE_HOLDING_1) {
mouse->state ^= (BROWSER_MOUSE_HOLDING_1 |
BROWSER_MOUSE_DRAG_ON);
+ was_drag = true;
} else if (mouse->state & BROWSER_MOUSE_HOLDING_2) {
mouse->state ^= (BROWSER_MOUSE_HOLDING_2 |
BROWSER_MOUSE_DRAG_ON);
+ was_drag = true;
}
/* Handle modifiers being removed */
@@ -188,9 +191,10 @@ nsgtk_cw_button_release_event(GtkWidget *widget,
}
/* end drag with modifiers */
- if (mouse->state & (BROWSER_MOUSE_MOD_1 |
- BROWSER_MOUSE_MOD_2 |
- BROWSER_MOUSE_MOD_3)) {
+ if (was_drag && (mouse->state & (
+ BROWSER_MOUSE_MOD_1 |
+ BROWSER_MOUSE_MOD_2 |
+ BROWSER_MOUSE_MOD_3))) {
mouse->state = BROWSER_MOUSE_HOVER;
}
@@ -413,14 +417,14 @@ nsgtk_cw_keypress_event(GtkWidget *widget, GdkEventKey *event, gpointer g)
if (res == NSERROR_OK) {
return TRUE;
} else if (res != NSERROR_NOT_IMPLEMENTED) {
- LOG("%s", messages_get_errorcode(res));
+ NSLOG(netsurf, INFO, "%s", messages_get_errorcode(res));
return FALSE;
}
/* deal with unprocessed keypress */
res = nsgtk_cw_key(nsgtk_cw, nskey);
if (res != NSERROR_OK) {
- LOG("%s", messages_get_errorcode(res));
+ NSLOG(netsurf, INFO, "%s", messages_get_errorcode(res));
return FALSE;
}
return TRUE;
diff --git a/frontends/gtk/download.c b/frontends/gtk/download.c
index 8c8161459..d11036ea8 100644
--- a/frontends/gtk/download.c
+++ b/frontends/gtk/download.c
@@ -331,6 +331,7 @@ static gboolean nsgtk_download_update(gboolean force_update)
switch (dl->status) {
case NSGTK_DOWNLOAD_WORKING:
pulse_mode = TRUE;
+ /* Fall through */
case NSGTK_DOWNLOAD_NONE:
dl->speed = dl->size_downloaded /
@@ -347,6 +348,7 @@ static gboolean nsgtk_download_update(gboolean force_update)
nsgtk_downloads_num_active++;
update = TRUE;
+ /* Fall through */
case NSGTK_DOWNLOAD_COMPLETE:
downloaded += dl->size_downloaded;
@@ -475,7 +477,7 @@ nserror nsgtk_download_init(void)
res = nsgtk_builder_new_from_resname("downloads", &builder);
if (res != NSERROR_OK) {
- LOG("Download UI builder init failed");
+ NSLOG(netsurf, INFO, "Download UI builder init failed");
return res;
}
diff --git a/frontends/gtk/fetch.c b/frontends/gtk/fetch.c
index 154f43708..7286aec34 100644
--- a/frontends/gtk/fetch.c
+++ b/frontends/gtk/fetch.c
@@ -90,7 +90,8 @@ void gtk_fetch_filetype_init(const char *mimefile)
fh = fopen(mimefile, "r");
if (fh == NULL) {
- LOG("Unable to open a mime.types file, so using a minimal one for you.");
+ NSLOG(netsurf, INFO,
+ "Unable to open a mime.types file, so using a minimal one for you.");
return;
}
diff --git a/frontends/gtk/gdk.c b/frontends/gtk/gdk.c
index 9ed90bd8e..fd82af5b2 100644
--- a/frontends/gtk/gdk.c
+++ b/frontends/gtk/gdk.c
@@ -86,7 +86,7 @@ nsgdk_pixbuf_get_from_surface(cairo_surface_t *surface, int scwidth, int scheigh
if (cairo_surface_status(scsurface) != CAIRO_STATUS_SUCCESS) {
cairo_surface_destroy(scsurface);
g_object_unref(pixbuf);
- LOG("Surface creation failed");
+ NSLOG(netsurf, INFO, "Surface creation failed");
return NULL;
}
diff --git a/frontends/gtk/global_history.c b/frontends/gtk/global_history.c
index 360eb4e1a..f204168d0 100644
--- a/frontends/gtk/global_history.c
+++ b/frontends/gtk/global_history.c
@@ -214,8 +214,9 @@ nsgtk_global_history_init_menu(struct nsgtk_global_history_window *ghwin)
w = GTK_WIDGET(gtk_builder_get_object(ghwin->builder,
event->widget));
if (w == NULL) {
- LOG("Unable to connect menu widget ""%s""",
- event->widget);
+ NSLOG(netsurf, INFO,
+ "Unable to connect menu widget ""%s""",
+ event->widget);
} else {
g_signal_connect(G_OBJECT(w),
"activate",
@@ -306,7 +307,7 @@ static nserror nsgtk_global_history_init(void)
res = nsgtk_builder_new_from_resname("globalhistory", &ncwin->builder);
if (res != NSERROR_OK) {
- LOG("History UI builder init failed");
+ NSLOG(netsurf, INFO, "History UI builder init failed");
free(ncwin);
return res;
}
diff --git a/frontends/gtk/gui.c b/frontends/gtk/gui.c
index a183e521f..0f79a1b8e 100644
--- a/frontends/gtk/gui.c
+++ b/frontends/gtk/gui.c
@@ -208,7 +208,8 @@ static nserror set_defaults(struct nsoption_s *defaults)
(nsoption_charp(hotlist_path) == NULL) ||
(nsoption_charp(downloads_directory) == NULL) ||
(nsoption_charp(ca_path) == NULL)) {
- LOG("Failed initialising default resource paths");
+ NSLOG(netsurf, INFO,
+ "Failed initialising default resource paths");
return NSERROR_BAD_PARAMETER;
}
@@ -238,7 +239,7 @@ static nserror nsgtk_init(int argc, char** argv, char **respath)
error = nsgtk_builder_new_from_resname("warning", &warning_builder);
if (error != NSERROR_OK) {
- LOG("Unable to initialise warning dialog");
+ NSLOG(netsurf, INFO, "Unable to initialise warning dialog");
return error;
}
@@ -248,7 +249,7 @@ static nserror nsgtk_init(int argc, char** argv, char **respath)
error = nsgdk_pixbuf_new_from_resname("netsurf.xpm",
&win_default_icon_pixbuf);
if (error == NSERROR_OK) {
- LOG("Seting default window icon");
+ NSLOG(netsurf, INFO, "Seting default window icon");
gtk_window_set_default_icon(win_default_icon_pixbuf);
}
@@ -256,7 +257,8 @@ static nserror nsgtk_init(int argc, char** argv, char **respath)
resource_filename = filepath_find(respath, "SearchEngines");
search_web_init(resource_filename);
if (resource_filename != NULL) {
- LOG("Using '%s' as Search Engines file", resource_filename);
+ NSLOG(netsurf, INFO, "Using '%s' as Search Engines file",
+ resource_filename);
free(resource_filename);
}
@@ -278,13 +280,20 @@ static nserror nsgtk_init(int argc, char** argv, char **respath)
/* initialise throbber */
error = nsgtk_throbber_init();
if (error != NSERROR_OK) {
- LOG("Unable to initialise throbber.");
+ NSLOG(netsurf, INFO, "Unable to initialise throbber.");
return error;
}
/* Initialise completions - cannot fail */
nsgtk_completion_init();
+ /* The tree view system needs to know the screen's DPI, so we
+ * find that out here, rather than when we create a first browser
+ * window.
+ */
+ browser_set_dpi(gdk_screen_get_resolution(gdk_screen_get_default()));
+ NSLOG(netsurf, INFO, "Set CSS DPI to %d", browser_get_dpi());
+
filepath_sfinddef(respath, buf, "mime.types", "/etc/");
gtk_fetch_filetype_init(buf);
@@ -295,17 +304,10 @@ static nserror nsgtk_init(int argc, char** argv, char **respath)
hotlist_init(nsoption_charp(hotlist_path),
nsoption_charp(hotlist_path));
- /* The tree view system needs to know the screen's DPI, so we
- * find that out here, rather than when we create a first browser
- * window.
- */
- browser_set_dpi(gdk_screen_get_resolution(gdk_screen_get_default()));
- LOG("Set CSS DPI to %d", browser_get_dpi());
-
/* Initialise top level UI elements */
error = nsgtk_download_init();
if (error != NSERROR_OK) {
- LOG("Unable to initialise download window.");
+ NSLOG(netsurf, INFO, "Unable to initialise download window.");
return error;
}
@@ -426,7 +428,7 @@ static void gui_quit(void)
{
nserror res;
- LOG("Quitting GUI");
+ NSLOG(netsurf, INFO, "Quitting GUI");
/* Ensure all scaffoldings are destroyed before we go into exit */
nsgtk_download_destroy();
@@ -435,32 +437,34 @@ static void gui_quit(void)
res = nsgtk_cookies_destroy();
if (res != NSERROR_OK) {
- LOG("Error finalising cookie viewer: %s",
- messages_get_errorcode(res));
+ NSLOG(netsurf, INFO, "Error finalising cookie viewer: %s",
+ messages_get_errorcode(res));
}
res = nsgtk_local_history_destroy();
if (res != NSERROR_OK) {
- LOG("Error finalising local history viewer: %s",
- messages_get_errorcode(res));
+ NSLOG(netsurf, INFO,
+ "Error finalising local history viewer: %s",
+ messages_get_errorcode(res));
}
res = nsgtk_global_history_destroy();
if (res != NSERROR_OK) {
- LOG("Error finalising global history viewer: %s",
- messages_get_errorcode(res));
+ NSLOG(netsurf, INFO,
+ "Error finalising global history viewer: %s",
+ messages_get_errorcode(res));
}
res = nsgtk_hotlist_destroy();
if (res != NSERROR_OK) {
- LOG("Error finalising hotlist viewer: %s",
- messages_get_errorcode(res));
+ NSLOG(netsurf, INFO, "Error finalising hotlist viewer: %s",
+ messages_get_errorcode(res));
}
res = hotlist_fini();
if (res != NSERROR_OK) {
- LOG("Error finalising hotlist: %s",
- messages_get_errorcode(res));
+ NSLOG(netsurf, INFO, "Error finalising hotlist: %s",
+ messages_get_errorcode(res));
}
free(nsgtk_config_home);
@@ -492,7 +496,7 @@ nserror nsgtk_warning(const char *warning, const char *detail)
static GtkWindow *nsgtk_warning_window;
GtkLabel *WarningLabel;
- LOG("%s %s", warning, detail ? detail : "");
+ NSLOG(netsurf, INFO, "%s %s", warning, detail ? detail : "");
fflush(stdout);
nsgtk_warning_window = GTK_WINDOW(gtk_builder_get_object(warning_builder, "wndWarning"));
@@ -600,7 +604,7 @@ static void nsgtk_pdf_password(char **owner_pass, char **user_pass, char *path)
res = nsgtk_builder_new_from_resname("password", &password_builder);
if (res != NSERROR_OK) {
- LOG("Password UI builder init failed");
+ NSLOG(netsurf, INFO, "Password UI builder init failed");
return;
}
@@ -821,7 +825,7 @@ static nserror get_config_home(char **config_home_out)
if (home_dir != NULL) {
ret = check_dirname(home_dir, ".netsurf", &config_home);
if (ret == NSERROR_OK) {
- LOG("\"%s\"", config_home);
+ NSLOG(netsurf, INFO, "\"%s\"", config_home);
*config_home_out = config_home;
return ret;
}
@@ -861,7 +865,7 @@ static nserror get_config_home(char **config_home_out)
}
}
- LOG("\"%s\"", config_home);
+ NSLOG(netsurf, INFO, "\"%s\"", config_home);
*config_home_out = config_home;
return NSERROR_OK;
@@ -874,7 +878,7 @@ static nserror create_config_home(char **config_home_out)
char *xdg_config_dir;
nserror ret;
- LOG("Attempting to create configuration directory");
+ NSLOG(netsurf, INFO, "Attempting to create configuration directory");
/* $XDG_CONFIG_HOME defines the base directory
* relative to which user specific configuration files
@@ -910,7 +914,7 @@ static nserror create_config_home(char **config_home_out)
/* strip the trailing separator */
config_home[strlen(config_home) - 1] = 0;
- LOG("\"%s\"", config_home);
+ NSLOG(netsurf, INFO, "\"%s\"", config_home);
*config_home_out = config_home;
@@ -959,7 +963,7 @@ static nserror get_cache_home(char **cache_home_out)
}
}
- LOG("\"%s\"", cache_home);
+ NSLOG(netsurf, INFO, "\"%s\"", cache_home);
*cache_home_out = cache_home;
return NSERROR_OK;
@@ -972,7 +976,7 @@ static nserror create_cache_home(char **cache_home_out)
char *xdg_cache_dir;
nserror ret;
- LOG("Attempting to create configuration directory");
+ NSLOG(netsurf, INFO, "Attempting to create configuration directory");
/* $XDG_CACHE_HOME defines the base directory
* relative to which user specific cache files
@@ -1008,7 +1012,7 @@ static nserror create_cache_home(char **cache_home_out)
/* strip the trailing separator */
cache_home[strlen(cache_home) - 1] = 0;
- LOG("\"%s\"", cache_home);
+ NSLOG(netsurf, INFO, "\"%s\"", cache_home);
*cache_home_out = cache_home;
@@ -1115,7 +1119,8 @@ int main(int argc, char** argv)
ret = create_config_home(&nsgtk_config_home);
}
if (ret != NSERROR_OK) {
- LOG("Unable to locate a configuration directory.");
+ NSLOG(netsurf, INFO,
+ "Unable to locate a configuration directory.");
nsgtk_config_home = NULL;
}
@@ -1155,7 +1160,7 @@ int main(int argc, char** argv)
if (ret != NSERROR_OK) {
fprintf(stderr, "Unable to load translated messages (%s)\n",
messages_get_errorcode(ret));
- LOG("Unable to load translated messages");
+ NSLOG(netsurf, INFO, "Unable to load translated messages");
/** \todo decide if message load faliure should be fatal */
}
@@ -1166,7 +1171,7 @@ int main(int argc, char** argv)
ret = create_cache_home(&cache_home);
}
if (ret != NSERROR_OK) {
- LOG("Unable to locate a cache directory.");
+ NSLOG(netsurf, INFO, "Unable to locate a cache directory.");
}
/* core initialisation */
@@ -1193,5 +1198,8 @@ int main(int argc, char** argv)
/* finalise options */
nsoption_finalise(nsoptions, nsoptions_default);
+ /* finalise logging */
+ nslog_finalise();
+
return 0;
}
diff --git a/frontends/gtk/hotlist.c b/frontends/gtk/hotlist.c
index 936573a0b..843e47736 100644
--- a/frontends/gtk/hotlist.c
+++ b/frontends/gtk/hotlist.c
@@ -236,8 +236,9 @@ static void nsgtk_hotlist_init_menu(struct nsgtk_hotlist_window *hlwin)
w = GTK_WIDGET(gtk_builder_get_object(hlwin->builder,
event->widget));
if (w == NULL) {
- LOG("Unable to connect menu widget ""%s""",
- event->widget);
+ NSLOG(netsurf, INFO,
+ "Unable to connect menu widget ""%s""",
+ event->widget);
} else {
g_signal_connect(G_OBJECT(w),
"activate",
@@ -326,7 +327,7 @@ static nserror nsgtk_hotlist_init(void)
res = nsgtk_builder_new_from_resname("hotlist", &ncwin->builder);
if (res != NSERROR_OK) {
- LOG("Hotlist UI builder init failed");
+ NSLOG(netsurf, INFO, "Hotlist UI builder init failed");
free(ncwin);
return res;
}
diff --git a/frontends/gtk/layout_pango.c b/frontends/gtk/layout_pango.c
index fb065b127..a5964eb37 100644
--- a/frontends/gtk/layout_pango.c
+++ b/frontends/gtk/layout_pango.c
@@ -30,6 +30,7 @@
#include "utils/log.h"
#include "utils/nsoption.h"
+#include "netsurf/inttypes.h"
#include "netsurf/layout.h"
#include "netsurf/plot_style.h"
@@ -42,12 +43,12 @@ static PangoLayout *nsfont_pango_layout = NULL;
static inline void nsfont_pango_check(void)
{
if (nsfont_pango_context == NULL) {
- LOG("Creating nsfont_pango_context.");
+ NSLOG(netsurf, INFO, "Creating nsfont_pango_context.");
nsfont_pango_context = gdk_pango_context_get();
}
if (nsfont_pango_layout == NULL) {
- LOG("Creating nsfont_pango_layout.");
+ NSLOG(netsurf, INFO, "Creating nsfont_pango_layout.");
nsfont_pango_layout = pango_layout_new(nsfont_pango_context);
}
}
@@ -84,9 +85,10 @@ nsfont_width(const plot_font_style_t *fstyle,
pango_layout_get_pixel_size(nsfont_pango_layout, width, 0);
- /* LOG("fstyle: %p string:\"%.*s\", length: %u, width: %dpx",
- fstyle, length, string, length, *width);
- */
+ NSLOG(netsurf, DEEPDEBUG,
+ "fstyle: %p string:\"%.*s\", length: %" PRIsizet ", width: %dpx",
+ fstyle, (int)length, string, length, *width);
+
return NSERROR_OK;
}
diff --git a/frontends/gtk/local_history.c b/frontends/gtk/local_history.c
index cc9580130..35b7a4ad6 100644
--- a/frontends/gtk/local_history.c
+++ b/frontends/gtk/local_history.c
@@ -148,7 +148,7 @@ nsgtk_local_history_init(struct browser_window *bw,
res = nsgtk_builder_new_from_resname("localhistory", &ncwin->builder);
if (res != NSERROR_OK) {
- LOG("Local history UI builder init failed");
+ NSLOG(netsurf, INFO, "Local history UI builder init failed");
free(ncwin);
return res;
}
diff --git a/frontends/gtk/login.c b/frontends/gtk/login.c
index 3e29903fe..91d8b37f0 100644
--- a/frontends/gtk/login.c
+++ b/frontends/gtk/login.c
@@ -222,7 +222,7 @@ void gui_401login_open(nsurl *url,
res = create_login_window(url, host, realm, cb, cbpw);
if (res != NSERROR_OK) {
- LOG("Login init failed");
+ NSLOG(netsurf, INFO, "Login init failed");
/* creating login failed so cancel navigation */
cb(false, cbpw);
diff --git a/frontends/gtk/plotters.c b/frontends/gtk/plotters.c
index c57b03294..88e7760c6 100644
--- a/frontends/gtk/plotters.c
+++ b/frontends/gtk/plotters.c
@@ -413,7 +413,7 @@ nsgtk_plot_path(const struct redraw_context *ctx,
return NSERROR_OK;
if (p[0] != PLOTTER_PATH_MOVE) {
- LOG("Path does not start with move");
+ NSLOG(netsurf, INFO, "Path does not start with move");
return NSERROR_INVALID;
}
@@ -451,7 +451,7 @@ nsgtk_plot_path(const struct redraw_context *ctx,
p[i+5], p[i+6]);
i += 7;
} else {
- LOG("bad path command %f", p[i]);
+ NSLOG(netsurf, INFO, "bad path command %f", p[i]);
/* Reset matrix for safety */
cairo_set_matrix(current_cr, &old_ctm);
return NSERROR_INVALID;
diff --git a/frontends/gtk/preferences.c b/frontends/gtk/preferences.c
index e51e77014..65f41ed27 100644
--- a/frontends/gtk/preferences.c
+++ b/frontends/gtk/preferences.c
@@ -621,7 +621,7 @@ comboboxLanguage_add_from_file(GtkListStore *liststore,
gtk_list_store_clear(liststore);
- LOG("Used %s for languages", file_location);
+ NSLOG(netsurf, INFO, "Used %s for languages", file_location);
while (fgets(buf, sizeof(buf), fp)) {
/* Ignore blank lines */
if (buf[0] == '\0')
@@ -668,7 +668,7 @@ nsgtk_preferences_comboboxLanguage_realize(GtkWidget *widget,
const char *accept_language;
if (priv->content_language == NULL) {
- LOG("content language list store unavailable");
+ NSLOG(netsurf, INFO, "content language list store unavailable");
return;
}
@@ -697,7 +697,7 @@ nsgtk_preferences_comboboxLanguage_realize(GtkWidget *widget,
}
}
if (res != NSERROR_OK) {
- LOG("error populatiung languages combo");
+ NSLOG(netsurf, INFO, "error populatiung languages combo");
}
}
@@ -989,14 +989,15 @@ GtkWidget* nsgtk_preferences(struct browser_window *bw, GtkWindow *parent)
res = nsgtk_builder_new_from_resname("options", &preferences_builder);
if (res != NSERROR_OK) {
- LOG("Preferences UI builder init failed");
+ NSLOG(netsurf, INFO, "Preferences UI builder init failed");
return NULL;
}
priv->dialog = gtk_builder_get_object(preferences_builder,
"dialogPreferences");
if (priv->dialog == NULL) {
- LOG("Unable to get object for preferences dialog");
+ NSLOG(netsurf, INFO,
+ "Unable to get object for preferences dialog");
/* release builder as were done with it */
g_object_unref(G_OBJECT(preferences_builder));
return NULL;
diff --git a/frontends/gtk/print.c b/frontends/gtk/print.c
index 54edeee61..8f71230a6 100644
--- a/frontends/gtk/print.c
+++ b/frontends/gtk/print.c
@@ -145,8 +145,9 @@ static inline void nsgtk_print_set_dashed(void)
static nserror
nsgtk_print_plot_clip(const struct redraw_context *ctx, const struct rect *clip)
{
- LOG("Clipping. x0: %i ;\t y0: %i ;\t x1: %i ;\t y1: %i",
- clip->x0, clip->y0, clip->x1, clip->y1);
+ NSLOG(netsurf, INFO,
+ "Clipping. x0: %i ;\t y0: %i ;\t x1: %i ;\t y1: %i", clip->x0,
+ clip->y0, clip->x1, clip->y1);
/* Normalize cllipping area - to prevent overflows.
* See comment in pdf_plot_fill. */
@@ -324,8 +325,8 @@ nsgtk_print_plot_rectangle(const struct redraw_context *ctx,
const plot_style_t *style,
const struct rect *rect)
{
- LOG("x0: %i ;\t y0: %i ;\t x1: %i ;\t y1: %i",
- rect->x0, rect->y0, rect->x1, rect->y1);
+ NSLOG(netsurf, INFO, "x0: %i ;\t y0: %i ;\t x1: %i ;\t y1: %i",
+ rect->x0, rect->y0, rect->x1, rect->y1);
if (style->fill_type != PLOT_OP_TYPE_NONE) {
int x0,y0,x1,y1;
@@ -395,7 +396,7 @@ nsgtk_print_plot_polygon(const struct redraw_context *ctx,
{
unsigned int i;
- LOG("Plotting polygon.");
+ NSLOG(netsurf, INFO, "Plotting polygon.");
nsgtk_print_set_colour(style->fill_colour);
nsgtk_print_set_solid();
@@ -403,11 +404,12 @@ nsgtk_print_plot_polygon(const struct redraw_context *ctx,
cairo_set_line_width(gtk_print_current_cr, 0);
cairo_move_to(gtk_print_current_cr, p[0], p[1]);
- LOG("Starting line at: %i\t%i", p[0], p[1]);
+ NSLOG(netsurf, INFO, "Starting line at: %i\t%i", p[0], p[1]);
for (i = 1; i != n; i++) {
cairo_line_to(gtk_print_current_cr, p[i * 2], p[i * 2 + 1]);
- LOG("Drawing line to: %i\t%i", p[i * 2], p[i * 2 + 1]);
+ NSLOG(netsurf, INFO, "Drawing line to: %i\t%i", p[i * 2],
+ p[i * 2 + 1]);
}
cairo_fill(gtk_print_current_cr);
@@ -700,7 +702,7 @@ void gtk_print_signal_begin_print (GtkPrintOperation *operation,
int page_number;
double height_on_page, height_to_print;
- LOG("Begin print");
+ NSLOG(netsurf, INFO, "Begin print");
settings = user_data;
@@ -719,7 +721,11 @@ void gtk_print_signal_begin_print (GtkPrintOperation *operation,
} else {
- LOG("page_width: %f ;page_height: %f; content height: %lf", settings->page_width, settings->page_height, height_to_print);
+ NSLOG(netsurf, INFO,
+ "page_width: %f ;page_height: %f; content height: %lf",
+ settings->page_width,
+ settings->page_height,
+ height_to_print);
height_on_page = settings->page_height;
height_on_page = height_on_page -
@@ -743,7 +749,7 @@ void gtk_print_signal_begin_print (GtkPrintOperation *operation,
void gtk_print_signal_draw_page(GtkPrintOperation *operation,
GtkPrintContext *context, gint page_nr, gpointer user_data)
{
- LOG("Draw Page");
+ NSLOG(netsurf, INFO, "Draw Page");
gtk_print_current_cr = gtk_print_context_get_cairo_context(context);
print_draw_next_page(&gtk_printer, settings);
}
@@ -755,7 +761,7 @@ void gtk_print_signal_draw_page(GtkPrintOperation *operation,
void gtk_print_signal_end_print(GtkPrintOperation *operation,
GtkPrintContext *context, gpointer user_data)
{
- LOG("End print");
+ NSLOG(netsurf, INFO, "End print");
print_cleanup(content_to_print, &gtk_printer, user_data);
}
diff --git a/frontends/gtk/res/options.gtk2.ui b/frontends/gtk/res/options.gtk2.ui
index d5542ba5d..a1162585d 100644
--- a/frontends/gtk/res/options.gtk2.ui
+++ b/frontends/gtk/res/options.gtk2.ui
@@ -2,6 +2,297 @@
<interface>
<requires lib="gtk+" version="2.16"/>
<!-- interface-naming-policy project-wide -->
+ <object class="GtkAdjustment" id="adjustment_animation_time">
+ <property name="lower">0.10000000000000001</property>
+ <property name="upper">10</property>
+ <property name="value">0.10000000000000001</property>
+ <property name="step_increment">0.10000000000000001</property>
+ <property name="page_increment">1</property>
+ </object>
+ <object class="GtkAdjustment" id="adjustment_cache_disc_size">
+ <property name="upper">4096</property>
+ <property name="value">1024</property>
+ <property name="step_increment">32</property>
+ <property name="page_increment">256</property>
+ </object>
+ <object class="GtkAdjustment" id="adjustment_cache_memory_size">
+ <property name="upper">2048</property>
+ <property name="value">16</property>
+ <property name="step_increment">4</property>
+ <property name="page_increment">16</property>
+ </object>
+ <object class="GtkAdjustment" id="adjustment_disc_cache_age">
+ <property name="upper">999</property>
+ <property name="value">28</property>
+ <property name="step_increment">1</property>
+ <property name="page_increment">10</property>
+ </object>
+ <object class="GtkAdjustment" id="adjustment_fetching_cached">
+ <property name="upper">100</property>
+ <property name="value">1</property>
+ <property name="step_increment">1</property>
+ <property name="page_increment">10</property>
+ </object>
+ <object class="GtkAdjustment" id="adjustment_fetching_max">
+ <property name="lower">1</property>
+ <property name="upper">100</property>
+ <property name="value">10</property>
+ <property name="step_increment">1</property>
+ <property name="page_increment">10</property>
+ </object>
+ <object class="GtkAdjustment" id="adjustment_fetching_perhost">
+ <property name="lower">1</property>
+ <property name="upper">100</property>
+ <property name="value">1</property>
+ <property name="step_increment">1</property>
+ <property name="page_increment">10</property>
+ </object>
+ <object class="GtkAdjustment" id="adjustment_font_default_size">
+ <property name="lower">1</property>
+ <property name="upper">99.900000000000006</property>
+ <property name="value">16</property>
+ <property name="step_increment">0.10000000000000001</property>
+ <property name="page_increment">2</property>
+ </object>
+ <object class="GtkAdjustment" id="adjustment_history_age">
+ <property name="upper">999</property>
+ <property name="value">28</property>
+ <property name="step_increment">1</property>
+ <property name="page_increment">28</property>
+ </object>
+ <object class="GtkAdjustment" id="adjustment_pdf_lmargin">
+ <property name="upper">999</property>
+ <property name="step_increment">1</property>
+ <property name="page_increment">10</property>
+ </object>
+ <object class="GtkAdjustment" id="adjustment_pdf_scale">
+ <property name="lower">1</property>
+ <property name="upper">1000</property>
+ <property name="value">100</property>
+ <property name="step_increment">1</property>
+ <property name="page_increment">10</property>
+ </object>
+ <object class="GtkAdjustment" id="adjustment_proxy_port">
+ <property name="lower">1</property>
+ <property name="upper">65535</property>
+ <property name="value">3128</property>
+ <property name="step_increment">1</property>
+ <property name="page_increment">10</property>
+ </object>
+ <object class="GtkImage" id="image1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="xpad">3</property>
+ <property name="stock">gtk-apply</property>
+ </object>
+ <object class="GtkListStore" id="liststore_content_language">
+ <columns>
+ <!-- column-name Code -->
+ <column type="gchararray"/>
+ <!-- column-name Description -->
+ <column type="gchararray"/>
+ </columns>
+ <data>
+ <row>
+ <col id="0" translatable="yes">en</col>
+ <col id="1" translatable="yes">English</col>
+ </row>
+ </data>
+ </object>
+ <object class="GtkListStore" id="liststore_defaultfont">
+ <columns>
+ <!-- column-name Type -->
+ <column type="gchararray"/>
+ </columns>
+ <data>
+ <row>
+ <col id="0" translatable="yes">preferencesFonttypeSans</col>
+ </row>
+ <row>
+ <col id="0" translatable="yes">preferencesFonttypeSerif</col>
+ </row>
+ <row>
+ <col id="0" translatable="yes">preferencesFonttypeMonospace</col>
+ </row>
+ <row>
+ <col id="0" translatable="yes">preferencesFonttypeCursive</col>
+ </row>
+ <row>
+ <col id="0" translatable="yes">preferencesFonttypeFantasy</col>
+ </row>
+ </data>
+ </object>
+ <object class="GtkListStore" id="liststore_developer_view">
+ <columns>
+ <!-- column-name Type -->
+ <column type="gchararray"/>
+ </columns>
+ <data>
+ <row>
+ <col id="0" translatable="yes">preferencesDeveloperViewWindow</col>
+ </row>
+ <row>
+ <col id="0" translatable="yes">preferencesDeveloperViewTab</col>
+ </row>
+ <row>
+ <col id="0" translatable="yes">preferencesDeveloperViewEditor</col>
+ </row>
+ </data>
+ </object>
+ <object class="GtkListStore" id="liststore_image_loading">
+ <columns>
+ <!-- column-name Type -->
+ <column type="gchararray"/>
+ </columns>
+ <data>
+ <row>
+ <col id="0" translatable="yes">preferencesImageLoadBoth</col>
+ </row>
+ <row>
+ <col id="0" translatable="yes">preferencesImageLoadFore</col>
+ </row>
+ <row>
+ <col id="0" translatable="yes">preferencesImageLoadBack</col>
+ </row>
+ <row>
+ <col id="0" translatable="yes">preferencesImageLoadNone</col>
+ </row>
+ </data>
+ </object>
+ <object class="GtkListStore" id="liststore_proxy_type">
+ <columns>
+ <!-- column-name Type -->
+ <column type="gchararray"/>
+ </columns>
+ <data>
+ <row>
+ <col id="0" translatable="yes">preferencesProxyTypeDirect</col>
+ </row>
+ <row>
+ <col id="0" translatable="yes">preferencesProxyTypeManual</col>
+ </row>
+ <row>
+ <col id="0" translatable="yes">preferencesProxyTypeBasic</col>
+ </row>
+ <row>
+ <col id="0" translatable="yes">preferencesProxyTypeNLTM</col>
+ </row>
+ <row>
+ <col id="0" translatable="yes">preferencesProxyTypeSystem</col>
+ </row>
+ </data>
+ </object>
+ <object class="GtkListStore" id="liststore_search_provider">
+ <columns>
+ <!-- column-name Provider -->
+ <column type="gchararray"/>
+ </columns>
+ <data>
+ <row>
+ <col id="0">Google</col>
+ </row>
+ <row>
+ <col id="0">Yahoo!</col>
+ </row>
+ <row>
+ <col id="0">Microsoft Live</col>
+ </row>
+ <row>
+ <col id="0">Buisiness.com</col>
+ </row>
+ <row>
+ <col id="0">Omgili</col>
+ </row>
+ <row>
+ <col id="0">BBC News</col>
+ </row>
+ <row>
+ <col id="0">Ubuntu Packages</col>
+ </row>
+ <row>
+ <col id="0">Creative Commons</col>
+ </row>
+ <row>
+ <col id="0">Ask</col>
+ </row>
+ <row>
+ <col id="0">Answers</col>
+ </row>
+ <row>
+ <col id="0">Dictionary.com</col>
+ </row>
+ <row>
+ <col id="0">YouTube</col>
+ </row>
+ <row>
+ <col id="0">AeroMP3</col>
+ </row>
+ <row>
+ <col id="0">AOL</col>
+ </row>
+ <row>
+ <col id="0">Baidu</col>
+ </row>
+ <row>
+ <col id="0">Amazon</col>
+ </row>
+ <row>
+ <col id="0">Ebay</col>
+ </row>
+ <row>
+ <col id="0">IMBD</col>
+ </row>
+ <row>
+ <col id="0">ESPN</col>
+ </row>
+ <row>
+ <col id="0">Wikipedia</col>
+ </row>
+ <row>
+ <col id="0">DuckDuckGo</col>
+ </row>
+ </data>
+ </object>
+ <object class="GtkListStore" id="liststore_tab_position">
+ <columns>
+ <!-- column-name Position -->
+ <column type="gchararray"/>
+ </columns>
+ <data>
+ <row>
+ <col id="0" translatable="yes">preferencesTabLocTop</col>
+ </row>
+ <row>
+ <col id="0" translatable="yes">preferencesTabLocLeft</col>
+ </row>
+ <row>
+ <col id="0" translatable="yes">preferencesTabLocRight</col>
+ </row>
+ <row>
+ <col id="0" translatable="yes">preferencesTabLocBottom</col>
+ </row>
+ </data>
+ </object>
+ <object class="GtkListStore" id="liststore_toolbar_buttontype">
+ <columns>
+ <!-- column-name Type -->
+ <column type="gchararray"/>
+ </columns>
+ <data>
+ <row>
+ <col id="0" translatable="yes">preferencesButtonTypeSmall</col>
+ </row>
+ <row>
+ <col id="0" translatable="yes">preferencesButtonTypeLarge</col>
+ </row>
+ <row>
+ <col id="0" translatable="yes">preferencesButtonTypeLargeText</col>
+ </row>
+ <row>
+ <col id="0" translatable="yes">preferencesButtonTypeText</col>
+ </row>
+ </data>
+ </object>
<object class="GtkDialog" id="dialogPreferences">
<property name="can_focus">False</property>
<property name="border_width">5</property>
@@ -2178,7 +2469,6 @@
</child>
<child>
<object class="GtkVBox" id="vbox_pdfexport">
- <property name="visible">True</property>
<property name="can_focus">False</property>
<property name="spacing">6</property>
<child>
@@ -2583,6 +2873,12 @@
<property name="x_options">GTK_EXPAND</property>
</packing>
</child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
</object>
<packing>
<property name="expand">True</property>
@@ -2710,295 +3006,4 @@
<action-widget response="-7">close</action-widget>
</action-widgets>
</object>
- <object class="GtkListStore" id="liststore_search_provider">
- <columns>
- <!-- column-name Provider -->
- <column type="gchararray"/>
- </columns>
- <data>
- <row>
- <col id="0">Google</col>
- </row>
- <row>
- <col id="0">Yahoo!</col>
- </row>
- <row>
- <col id="0">Microsoft Live</col>
- </row>
- <row>
- <col id="0">Buisiness.com</col>
- </row>
- <row>
- <col id="0">Omgili</col>
- </row>
- <row>
- <col id="0">BBC News</col>
- </row>
- <row>
- <col id="0">Ubuntu Packages</col>
- </row>
- <row>
- <col id="0">Creative Commons</col>
- </row>
- <row>
- <col id="0">Ask</col>
- </row>
- <row>
- <col id="0">Answers</col>
- </row>
- <row>
- <col id="0">Dictionary.com</col>
- </row>
- <row>
- <col id="0">YouTube</col>
- </row>
- <row>
- <col id="0">AeroMP3</col>
- </row>
- <row>
- <col id="0">AOL</col>
- </row>
- <row>
- <col id="0">Baidu</col>
- </row>
- <row>
- <col id="0">Amazon</col>
- </row>
- <row>
- <col id="0">Ebay</col>
- </row>
- <row>
- <col id="0">IMBD</col>
- </row>
- <row>
- <col id="0">ESPN</col>
- </row>
- <row>
- <col id="0">Wikipedia</col>
- </row>
- <row>
- <col id="0">DuckDuckGo</col>
- </row>
- </data>
- </object>
- <object class="GtkListStore" id="liststore_tab_position">
- <columns>
- <!-- column-name Position -->
- <column type="gchararray"/>
- </columns>
- <data>
- <row>
- <col id="0" translatable="yes">preferencesTabLocTop</col>
- </row>
- <row>
- <col id="0" translatable="yes">preferencesTabLocLeft</col>
- </row>
- <row>
- <col id="0" translatable="yes">preferencesTabLocRight</col>
- </row>
- <row>
- <col id="0" translatable="yes">preferencesTabLocBottom</col>
- </row>
- </data>
- </object>
- <object class="GtkListStore" id="liststore_toolbar_buttontype">
- <columns>
- <!-- column-name Type -->
- <column type="gchararray"/>
- </columns>
- <data>
- <row>
- <col id="0" translatable="yes">preferencesButtonTypeSmall</col>
- </row>
- <row>
- <col id="0" translatable="yes">preferencesButtonTypeLarge</col>
- </row>
- <row>
- <col id="0" translatable="yes">preferencesButtonTypeLargeText</col>
- </row>
- <row>
- <col id="0" translatable="yes">preferencesButtonTypeText</col>
- </row>
- </data>
- </object>
- <object class="GtkListStore" id="liststore_image_loading">
- <columns>
- <!-- column-name Type -->
- <column type="gchararray"/>
- </columns>
- <data>
- <row>
- <col id="0" translatable="yes">preferencesImageLoadBoth</col>
- </row>
- <row>
- <col id="0" translatable="yes">preferencesImageLoadFore</col>
- </row>
- <row>
- <col id="0" translatable="yes">preferencesImageLoadBack</col>
- </row>
- <row>
- <col id="0" translatable="yes">preferencesImageLoadNone</col>
- </row>
- </data>
- </object>
- <object class="GtkListStore" id="liststore_defaultfont">
- <columns>
- <!-- column-name Type -->
- <column type="gchararray"/>
- </columns>
- <data>
- <row>
- <col id="0" translatable="yes">preferencesFonttypeSans</col>
- </row>
- <row>
- <col id="0" translatable="yes">preferencesFonttypeSerif</col>
- </row>
- <row>
- <col id="0" translatable="yes">preferencesFonttypeMonospace</col>
- </row>
- <row>
- <col id="0" translatable="yes">preferencesFonttypeCursive</col>
- </row>
- <row>
- <col id="0" translatable="yes">preferencesFonttypeFantasy</col>
- </row>
- </data>
- </object>
- <object class="GtkImage" id="image1">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="xpad">3</property>
- <property name="stock">gtk-apply</property>
- </object>
- <object class="GtkListStore" id="liststore_proxy_type">
- <columns>
- <!-- column-name Type -->
- <column type="gchararray"/>
- </columns>
- <data>
- <row>
- <col id="0" translatable="yes">preferencesProxyTypeDirect</col>
- </row>
- <row>
- <col id="0" translatable="yes">preferencesProxyTypeManual</col>
- </row>
- <row>
- <col id="0" translatable="yes">preferencesProxyTypeBasic</col>
- </row>
- <row>
- <col id="0" translatable="yes">preferencesProxyTypeNLTM</col>
- </row>
- <row>
- <col id="0" translatable="yes">preferencesProxyTypeSystem</col>
- </row>
- </data>
- </object>
- <object class="GtkAdjustment" id="adjustment_animation_time">
- <property name="value">0.10000000000000001</property>
- <property name="lower">0.10000000000000001</property>
- <property name="upper">10</property>
- <property name="step_increment">0.10000000000000001</property>
- <property name="page_increment">1</property>
- </object>
- <object class="GtkAdjustment" id="adjustment_font_default_size">
- <property name="value">16</property>
- <property name="lower">1</property>
- <property name="upper">99.900000000000006</property>
- <property name="step_increment">0.10000000000000001</property>
- <property name="page_increment">2</property>
- </object>
- <object class="GtkAdjustment" id="adjustment_history_age">
- <property name="value">28</property>
- <property name="upper">999</property>
- <property name="step_increment">1</property>
- <property name="page_increment">28</property>
- </object>
- <object class="GtkAdjustment" id="adjustment_cache_memory_size">
- <property name="value">16</property>
- <property name="upper">2048</property>
- <property name="step_increment">4</property>
- <property name="page_increment">16</property>
- </object>
- <object class="GtkAdjustment" id="adjustment_cache_disc_size">
- <property name="value">1024</property>
- <property name="upper">4096</property>
- <property name="step_increment">32</property>
- <property name="page_increment">256</property>
- </object>
- <object class="GtkAdjustment" id="adjustment_disc_cache_age">
- <property name="value">28</property>
- <property name="upper">999</property>
- <property name="step_increment">1</property>
- <property name="page_increment">10</property>
- </object>
- <object class="GtkAdjustment" id="adjustment_proxy_port">
- <property name="value">3128</property>
- <property name="lower">1</property>
- <property name="upper">65535</property>
- <property name="step_increment">1</property>
- <property name="page_increment">10</property>
- </object>
- <object class="GtkAdjustment" id="adjustment_fetching_max">
- <property name="value">10</property>
- <property name="lower">1</property>
- <property name="upper">100</property>
- <property name="step_increment">1</property>
- <property name="page_increment">10</property>
- </object>
- <object class="GtkAdjustment" id="adjustment_fetching_perhost">
- <property name="value">1</property>
- <property name="lower">1</property>
- <property name="upper">100</property>
- <property name="step_increment">1</property>
- <property name="page_increment">10</property>
- </object>
- <object class="GtkAdjustment" id="adjustment_fetching_cached">
- <property name="value">1</property>
- <property name="upper">100</property>
- <property name="step_increment">1</property>
- <property name="page_increment">10</property>
- </object>
- <object class="GtkAdjustment" id="adjustment_pdf_scale">
- <property name="value">100</property>
- <property name="lower">1</property>
- <property name="upper">1000</property>
- <property name="step_increment">1</property>
- <property name="page_increment">10</property>
- </object>
- <object class="GtkAdjustment" id="adjustment_pdf_lmargin">
- <property name="upper">999</property>
- <property name="step_increment">1</property>
- <property name="page_increment">10</property>
- </object>
- <object class="GtkListStore" id="liststore_content_language">
- <columns>
- <!-- column-name Code -->
- <column type="gchararray"/>
- <!-- column-name Description -->
- <column type="gchararray"/>
- </columns>
- <data>
- <row>
- <col id="0" translatable="yes">en</col>
- <col id="1" translatable="yes">English</col>
- </row>
- </data>
- </object>
- <object class="GtkListStore" id="liststore_developer_view">
- <columns>
- <!-- column-name Type -->
- <column type="gchararray"/>
- </columns>
- <data>
- <row>
- <col id="0" translatable="yes">preferencesDeveloperViewWindow</col>
- </row>
- <row>
- <col id="0" translatable="yes">preferencesDeveloperViewTab</col>
- </row>
- <row>
- <col id="0" translatable="yes">preferencesDeveloperViewEditor</col>
- </row>
- </data>
- </object>
</interface>
diff --git a/frontends/gtk/res/toolbar.gtk2.ui b/frontends/gtk/res/toolbar.gtk2.ui
index d84db5c8c..4e8805a6f 100644
--- a/frontends/gtk/res/toolbar.gtk2.ui
+++ b/frontends/gtk/res/toolbar.gtk2.ui
@@ -1,67 +1,84 @@
-<?xml version="1.0"?>
-<!--*- mode: xml -*-->
+<?xml version="1.0" encoding="UTF-8"?>
<interface>
- <object class="GtkWindow" id="toolbarwindow">
+ <!-- interface-requires gtk+ 2.12 -->
+ <!-- interface-naming-policy toplevel-contextual -->
+ <object class="GtkDialog" id="dialogToolbar">
<property name="width_request">700</property>
<property name="height_request">450</property>
- <property name="title" translatable="yes"/>
- <property name="type">GTK_WINDOW_TOPLEVEL</property>
- <property name="window_position">GTK_WIN_POS_NONE</property>
- <property name="modal">False</property>
- <property name="resizable">True</property>
- <property name="destroy_with_parent">False</property>
- <property name="decorated">True</property>
- <property name="skip_taskbar_hint">False</property>
- <property name="skip_pager_hint">False</property>
- <property name="type_hint">GDK_WINDOW_TYPE_HINT_NORMAL</property>
- <property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
- <property name="focus_on_map">True</property>
- <property name="urgency_hint">False</property>
- <child>
- <object class="GtkVBox" id="windowvbox">
+ <property name="can_focus">False</property>
+ <property name="border_width">5</property>
+ <property name="title" translatable="yes">gtkToolBarTitle</property>
+ <property name="window_position">center-on-parent</property>
+ <property name="destroy_with_parent">True</property>
+ <property name="type_hint">dialog</property>
+ <child internal-child="vbox">
+ <object class="GtkVBox" id="dialog-vbox1">
<property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">0</property>
+ <property name="can_focus">False</property>
+ <property name="spacing">2</property>
<child>
- <object class="GtkLabel" id="toolbarlabel">
+ <object class="GtkHBox" id="hbox1">
<property name="visible">True</property>
- <property name="label" translatable="yes">Move items from store to toolbar Rearrange items in toolbar Move items from toolbar to store</property>
- <property name="use_underline">False</property>
- <property name="use_markup">False</property>
- <property name="justify">GTK_JUSTIFY_LEFT</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">0.5</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
+ <property name="can_focus">False</property>
+ <property name="homogeneous">True</property>
+ <child>
+ <object class="GtkLabel" id="label1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes">Move items from store to toolbar</property>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes">Rearrange items in toolbar</property>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label3">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes">Move items from toolbar to store</property>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
</object>
<packing>
- <property name="padding">0</property>
<property name="expand">False</property>
<property name="fill">True</property>
+ <property name="padding">2</property>
+ <property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkScrolledWindow" id="scrolledwindow1">
<property name="visible">True</property>
- <property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
- <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
- <property name="shadow_type">GTK_SHADOW_NONE</property>
- <property name="window_placement">GTK_CORNER_TOP_LEFT</property>
+ <property name="can_focus">False</property>
+ <property name="hscrollbar_policy">automatic</property>
+ <property name="vscrollbar_policy">automatic</property>
<child>
<object class="GtkViewport" id="viewport1">
<property name="visible">True</property>
- <property name="shadow_type">GTK_SHADOW_IN</property>
+ <property name="can_focus">False</property>
<child>
<object class="GtkVBox" id="widgetvbox">
<property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">0</property>
+ <property name="can_focus">False</property>
<child>
<placeholder/>
</child>
@@ -71,119 +88,85 @@
</child>
</object>
<packing>
- <property name="padding">0</property>
<property name="expand">True</property>
<property name="fill">True</property>
+ <property name="position">1</property>
</packing>
</child>
- <child>
- <object class="GtkHBox" id="buttonhbox">
+ <child internal-child="action_area">
+ <object class="GtkHButtonBox" id="dialog-action_area1">
<property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">0</property>
+ <property name="can_focus">False</property>
+ <property name="layout_style">end</property>
<child>
- <object class="GtkButton" id="resetbutton">
+ <object class="GtkButton" id="reset">
<property name="visible">True</property>
<property name="can_focus">True</property>
- <property name="relief">GTK_RELIEF_NORMAL</property>
- <property name="focus_on_click">True</property>
+ <property name="receives_default">False</property>
<child>
<object class="GtkHBox" id="button1hbox">
<property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">0</property>
+ <property name="can_focus">False</property>
<child>
<object class="GtkImage" id="image1">
<property name="visible">True</property>
+ <property name="can_focus">False</property>
<property name="stock">gtk-refresh</property>
- <property name="icon_size">4</property>
- <property name="xalign">0.5</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
</object>
<packing>
- <property name="padding">0</property>
<property name="expand">False</property>
<property name="fill">True</property>
+ <property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="refreshbuttonlabel">
<property name="visible">True</property>
+ <property name="can_focus">False</property>
<property name="label" translatable="yes">Reset to defaults</property>
- <property name="use_underline">False</property>
- <property name="use_markup">False</property>
- <property name="justify">GTK_JUSTIFY_LEFT</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">0.5</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
</object>
<packing>
- <property name="padding">0</property>
<property name="expand">True</property>
<property name="fill">True</property>
+ <property name="position">1</property>
</packing>
</child>
</object>
</child>
</object>
<packing>
- <property name="padding">10</property>
<property name="expand">False</property>
<property name="fill">True</property>
- </packing>
- </child>
- <child>
- <placeholder/>
- </child>
- <child>
- <object class="GtkButton" id="okbutton">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="has_focus">True</property>
- <property name="label">gtk-apply</property>
- <property name="use_stock">True</property>
- <property name="relief">GTK_RELIEF_NORMAL</property>
- <property name="focus_on_click">True</property>
- </object>
- <packing>
<property name="padding">10</property>
- <property name="expand">False</property>
- <property name="fill">True</property>
+ <property name="position">0</property>
</packing>
</child>
<child>
- <object class="GtkButton" id="cancelbutton">
+ <object class="GtkButton" id="close">
+ <property name="label">gtk-close</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
- <property name="label">gtk-cancel</property>
+ <property name="receives_default">True</property>
<property name="use_stock">True</property>
- <property name="relief">GTK_RELIEF_NORMAL</property>
- <property name="focus_on_click">True</property>
</object>
<packing>
- <property name="padding">0</property>
<property name="expand">False</property>
- <property name="fill">True</property>
+ <property name="fill">False</property>
+ <property name="position">1</property>
</packing>
</child>
</object>
<packing>
- <property name="padding">0</property>
<property name="expand">False</property>
<property name="fill">True</property>
+ <property name="position">2</property>
</packing>
</child>
</object>
</child>
+ <action-widgets>
+ <action-widget response="0">reset</action-widget>
+ <action-widget response="0">close</action-widget>
+ </action-widgets>
</object>
</interface>
diff --git a/frontends/gtk/res/toolbar.gtk3.ui b/frontends/gtk/res/toolbar.gtk3.ui
index d84db5c8c..1f1148703 100644
--- a/frontends/gtk/res/toolbar.gtk3.ui
+++ b/frontends/gtk/res/toolbar.gtk3.ui
@@ -1,186 +1,134 @@
-<?xml version="1.0"?>
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.18.3 -->
<!--*- mode: xml -*-->
<interface>
- <object class="GtkWindow" id="toolbarwindow">
+ <requires lib="gtk+" version="3.0"/>
+ <object class="GtkImage" id="image2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="stock">gtk-refresh</property>
+ </object>
+ <object class="GtkDialog" id="dialogToolbar">
<property name="width_request">700</property>
<property name="height_request">450</property>
- <property name="title" translatable="yes"/>
- <property name="type">GTK_WINDOW_TOPLEVEL</property>
- <property name="window_position">GTK_WIN_POS_NONE</property>
- <property name="modal">False</property>
- <property name="resizable">True</property>
- <property name="destroy_with_parent">False</property>
- <property name="decorated">True</property>
- <property name="skip_taskbar_hint">False</property>
- <property name="skip_pager_hint">False</property>
- <property name="type_hint">GDK_WINDOW_TYPE_HINT_NORMAL</property>
- <property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
- <property name="focus_on_map">True</property>
- <property name="urgency_hint">False</property>
- <child>
- <object class="GtkVBox" id="windowvbox">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">0</property>
- <child>
- <object class="GtkLabel" id="toolbarlabel">
- <property name="visible">True</property>
- <property name="label" translatable="yes">Move items from store to toolbar Rearrange items in toolbar Move items from toolbar to store</property>
- <property name="use_underline">False</property>
- <property name="use_markup">False</property>
- <property name="justify">GTK_JUSTIFY_LEFT</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">0.5</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </object>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">True</property>
- </packing>
- </child>
- <child>
- <object class="GtkScrolledWindow" id="scrolledwindow1">
- <property name="visible">True</property>
- <property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
- <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
- <property name="shadow_type">GTK_SHADOW_NONE</property>
- <property name="window_placement">GTK_CORNER_TOP_LEFT</property>
+ <property name="can_focus">False</property>
+ <property name="title" translatable="yes">gtkToolBarTitle</property>
+ <property name="type_hint">dialog</property>
+ <child internal-child="vbox">
+ <object class="GtkBox" id="dialog-vbox1">
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">2</property>
+ <child internal-child="action_area">
+ <object class="GtkButtonBox" id="dialog-action_area1">
+ <property name="can_focus">False</property>
+ <property name="layout_style">end</property>
<child>
- <object class="GtkViewport" id="viewport1">
+ <object class="GtkButton" id="reset">
+ <property name="label" translatable="yes">Reset To Defaults</property>
<property name="visible">True</property>
- <property name="shadow_type">GTK_SHADOW_IN</property>
- <child>
- <object class="GtkVBox" id="widgetvbox">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">0</property>
- <child>
- <placeholder/>
- </child>
- </object>
- </child>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="image">image2</property>
+ <property name="yalign">0.52999997138977051</property>
+ <property name="always_show_image">True</property>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="close">
+ <property name="label">gtk-close</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use_stock">True</property>
</object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
</child>
</object>
<packing>
- <property name="padding">0</property>
- <property name="expand">True</property>
- <property name="fill">True</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">2</property>
</packing>
</child>
<child>
- <object class="GtkHBox" id="buttonhbox">
+ <object class="GtkGrid" id="grid1">
<property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">0</property>
+ <property name="can_focus">False</property>
+ <property name="column_homogeneous">True</property>
<child>
- <object class="GtkButton" id="resetbutton">
+ <object class="GtkLabel" id="label1">
<property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="relief">GTK_RELIEF_NORMAL</property>
- <property name="focus_on_click">True</property>
- <child>
- <object class="GtkHBox" id="button1hbox">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">0</property>
- <child>
- <object class="GtkImage" id="image1">
- <property name="visible">True</property>
- <property name="stock">gtk-refresh</property>
- <property name="icon_size">4</property>
- <property name="xalign">0.5</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- </object>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">True</property>
- </packing>
- </child>
- <child>
- <object class="GtkLabel" id="refreshbuttonlabel">
- <property name="visible">True</property>
- <property name="label" translatable="yes">Reset to defaults</property>
- <property name="use_underline">False</property>
- <property name="use_markup">False</property>
- <property name="justify">GTK_JUSTIFY_LEFT</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">0.5</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </object>
- <packing>
- <property name="padding">0</property>
- <property name="expand">True</property>
- <property name="fill">True</property>
- </packing>
- </child>
- </object>
- </child>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes">Move items from store to toolbar</property>
</object>
<packing>
- <property name="padding">10</property>
- <property name="expand">False</property>
- <property name="fill">True</property>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
</packing>
</child>
<child>
- <placeholder/>
- </child>
- <child>
- <object class="GtkButton" id="okbutton">
+ <object class="GtkLabel" id="label2">
<property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="has_focus">True</property>
- <property name="label">gtk-apply</property>
- <property name="use_stock">True</property>
- <property name="relief">GTK_RELIEF_NORMAL</property>
- <property name="focus_on_click">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes">Rearrange items in toolbar</property>
</object>
<packing>
- <property name="padding">10</property>
- <property name="expand">False</property>
- <property name="fill">True</property>
+ <property name="left_attach">1</property>
+ <property name="top_attach">0</property>
</packing>
</child>
<child>
- <object class="GtkButton" id="cancelbutton">
+ <object class="GtkLabel" id="label3">
<property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="label">gtk-cancel</property>
- <property name="use_stock">True</property>
- <property name="relief">GTK_RELIEF_NORMAL</property>
- <property name="focus_on_click">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes">Move items from toolbar to store</property>
</object>
<packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">True</property>
+ <property name="left_attach">2</property>
+ <property name="top_attach">0</property>
</packing>
</child>
</object>
<packing>
- <property name="padding">0</property>
<property name="expand">False</property>
<property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkScrolledWindow" id="scrolledwindow1">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <child>
+ <object class="GtkViewport" id="viewport1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <child>
+ <object class="GtkVBox" id="widgetvbox">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
</packing>
</child>
</object>
diff --git a/frontends/gtk/resources.c b/frontends/gtk/resources.c
index 4f9afb034..ef92fefc8 100644
--- a/frontends/gtk/resources.c
+++ b/frontends/gtk/resources.c
@@ -198,10 +198,12 @@ init_resource(char **respath, struct nsgtk_resource_s *resource)
/* found an entry in the resources */
resource->path = resname;
resource->type = NSGTK_RESOURCE_GLIB;
- LOG("Found gresource path %s", resource->path);
+ NSLOG(netsurf, INFO, "Found gresource path %s",
+ resource->path);
return NSERROR_OK;
}
- /*LOG("gresource \"%s\" not found", resname);*/
+ NSLOG(netsurf, DEEPDEBUG,
+ "gresource \"%s\" not found", resname);
free(resname);
langc++;
@@ -221,18 +223,20 @@ init_resource(char **respath, struct nsgtk_resource_s *resource)
/* found an entry in the resources */
resource->path = resname;
resource->type = NSGTK_RESOURCE_GLIB;
- LOG("Found gresource path %s", resource->path);
+ NSLOG(netsurf, INFO, "Found gresource path %s",
+ resource->path);
return NSERROR_OK;
}
- /*LOG("gresource \"%s\" not found", resname);*/
+ NSLOG(netsurf, DEEPDEBUG, "gresource \"%s\" not found", resname);
free(resname);
#endif
resname = filepath_find(respath, resource->name);
if (resname == NULL) {
- LOG("Unable to find resource %s on resource path",
- resource->name);
+ NSLOG(netsurf, INFO,
+ "Unable to find resource %s on resource path",
+ resource->name);
return NSERROR_NOT_FOUND;
}
@@ -240,7 +244,7 @@ init_resource(char **respath, struct nsgtk_resource_s *resource)
resource->path = resname;
resource->type = NSGTK_RESOURCE_FILE;
- LOG("Found file resource path %s", resource->path);
+ NSLOG(netsurf, INFO, "Found file resource path %s", resource->path);
return NSERROR_OK;
}
@@ -295,21 +299,21 @@ init_pixbuf_resource(char **respath, struct nsgtk_resource_s *resource)
if (strncmp(resource->name, "menu_cursor.png", resource->len) == 0) {
resource->path = (char *)&menu_cursor_pixdata[0];
resource->type = NSGTK_RESOURCE_INLINE;
- LOG("Found builtin for %s", resource->name);
+ NSLOG(netsurf, INFO, "Found builtin for %s", resource->name);
return NSERROR_OK;
}
if (strncmp(resource->name, "netsurf.xpm", resource->len) == 0) {
resource->path = (char *)&netsurf_pixdata[0];
resource->type = NSGTK_RESOURCE_INLINE;
- LOG("Found builtin for %s", resource->name);
+ NSLOG(netsurf, INFO, "Found builtin for %s", resource->name);
return NSERROR_OK;
}
if (strncmp(resource->name, "favicon.png", resource->len) == 0) {
resource->path = (char *)&favicon_pixdata[0];
resource->type = NSGTK_RESOURCE_INLINE;
- LOG("Found builtin for %s", resource->name);
+ NSLOG(netsurf, INFO, "Found builtin for %s", resource->name);
return NSERROR_OK;
}
#endif
@@ -389,13 +393,13 @@ static void list_gresource(void)
G_RESOURCE_LOOKUP_FLAGS_NONE,
&gerror);
if (gerror) {
- LOG("gerror %s", gerror->message);
+ NSLOG(netsurf, INFO, "gerror %s", gerror->message);
g_error_free(gerror);
} else {
cur = reslist;
while (cur != NULL && *cur != NULL) {
- LOG("gres %s", *cur);
+ NSLOG(netsurf, INFO, "gres %s", *cur);
cur++;
}
g_strfreev(reslist);
@@ -488,12 +492,17 @@ nsgdk_pixbuf_new_from_resname(const char *resname, GdkPixbuf **pixbuf_out)
if (new_pixbuf == NULL) {
if (error != NULL) {
- LOG("Unable to create pixbuf from file for %s with path %s \"%s\"",
- resource->name, resource->path, error->message);
+ NSLOG(netsurf, INFO,
+ "Unable to create pixbuf from file for %s with path %s \"%s\"",
+ resource->name,
+ resource->path,
+ error->message);
g_error_free(error);
} else {
- LOG("Unable to create pixbuf from file for %s with path %s",
- resource->name, resource->path);
+ NSLOG(netsurf, INFO,
+ "Unable to create pixbuf from file for %s with path %s",
+ resource->name,
+ resource->path);
}
return NSERROR_INIT_FAILED;
}
@@ -521,8 +530,11 @@ nsgtk_builder_new_from_resname(const char *resname, GtkBuilder **builder_out)
if (!gtk_builder_add_from_file(new_builder,
ui_res->path,
&error)) {
- LOG("Unable to add UI builder from file for %s with path %s \"%s\"",
- ui_res->name, ui_res->path, error->message);
+ NSLOG(netsurf, INFO,
+ "Unable to add UI builder from file for %s with path %s \"%s\"",
+ ui_res->name,
+ ui_res->path,
+ error->message);
g_error_free(error);
g_object_unref(G_OBJECT(new_builder));
return NSERROR_INIT_FAILED;
@@ -531,8 +543,11 @@ nsgtk_builder_new_from_resname(const char *resname, GtkBuilder **builder_out)
if (!nsgtk_builder_add_from_resource(new_builder,
ui_res->path,
&error)) {
- LOG("Unable to add UI builder from resource for %s with path %s \"%s\"",
- ui_res->name, ui_res->path, error->message);
+ NSLOG(netsurf, INFO,
+ "Unable to add UI builder from resource for %s with path %s \"%s\"",
+ ui_res->name,
+ ui_res->path,
+ error->message);
g_error_free(error);
g_object_unref(G_OBJECT(new_builder));
return NSERROR_INIT_FAILED;
diff --git a/frontends/gtk/scaffolding.c b/frontends/gtk/scaffolding.c
index 25f36c5d3..6f81e91db 100644
--- a/frontends/gtk/scaffolding.c
+++ b/frontends/gtk/scaffolding.c
@@ -269,7 +269,7 @@ static void scaffolding_window_destroy(GtkWidget *widget, gpointer data)
{
struct nsgtk_scaffolding *gs = data;
- LOG("scaffold:%p", gs);
+ NSLOG(netsurf, INFO, "scaffold:%p", gs);
nsgtk_local_history_hide();
@@ -282,7 +282,7 @@ static void scaffolding_window_destroy(GtkWidget *widget, gpointer data)
gs->next->prev = gs->prev;
}
- LOG("scaffold list head: %p", scaf_list);
+ NSLOG(netsurf, INFO, "scaffold list head: %p", scaf_list);
if (scaf_list == NULL) {
/* no more open windows - stop the browser */
@@ -805,7 +805,10 @@ MULTIHANDLER(savepage)
path = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(fc));
d = opendir(path);
if (d == NULL) {
- LOG("Unable to open directory %s for complete save: %s", path, strerror(errno));
+ NSLOG(netsurf, INFO,
+ "Unable to open directory %s for complete save: %s",
+ path,
+ strerror(errno));
if (errno == ENOTDIR)
nsgtk_warning("NoDirError", path);
else
@@ -837,7 +840,7 @@ MULTIHANDLER(pdf)
char *url_name;
nserror res;
- LOG("Print preview (generating PDF) started.");
+ NSLOG(netsurf, INFO, "Print preview (generating PDF) started.");
res = nsurl_nice(browser_window_get_url(bw), &url_name, true);
if (res != NSERROR_OK) {
@@ -1221,10 +1224,10 @@ MULTIHANDLER(selectall)
struct browser_window *bw = nsgtk_get_browser_window(g->top_level);
if (nsgtk_widget_has_focus(GTK_WIDGET(g->url_bar))) {
- LOG("Selecting all URL bar text");
+ NSLOG(netsurf, INFO, "Selecting all URL bar text");
gtk_editable_select_region(GTK_EDITABLE(g->url_bar), 0, -1);
} else {
- LOG("Selecting all document text");
+ NSLOG(netsurf, INFO, "Selecting all document text");
browser_window_key_press(bw, NS_KEY_SELECT_ALL);
}
@@ -1590,7 +1593,8 @@ MULTIHANDLER(localhistory)
res = nsgtk_local_history_present(g->window, bw);
if (res != NSERROR_OK) {
- LOG("Unable to initialise local history window.");
+ NSLOG(netsurf, INFO,
+ "Unable to initialise local history window.");
}
return TRUE;
}
@@ -1600,7 +1604,8 @@ MULTIHANDLER(globalhistory)
nserror res;
res = nsgtk_global_history_present();
if (res != NSERROR_OK) {
- LOG("Unable to initialise global history window.");
+ NSLOG(netsurf, INFO,
+ "Unable to initialise global history window.");
}
return TRUE;
}
@@ -1620,7 +1625,7 @@ MULTIHANDLER(showbookmarks)
nserror res;
res = nsgtk_hotlist_present();
if (res != NSERROR_OK) {
- LOG("Unable to initialise bookmark window.");
+ NSLOG(netsurf, INFO, "Unable to initialise bookmark window.");
}
return TRUE;
}
@@ -1630,7 +1635,7 @@ MULTIHANDLER(showcookies)
nserror res;
res = nsgtk_cookies_present();
if (res != NSERROR_OK) {
- LOG("Unable to initialise cookies window.");
+ NSLOG(netsurf, INFO, "Unable to initialise cookies window.");
}
return TRUE;
}
@@ -2068,12 +2073,13 @@ struct nsgtk_scaffolding *nsgtk_new_scaffolding(struct gui_window *toplevel)
int i;
GtkAccelGroup *group;
- gs = malloc(sizeof(*gs));
+ gs = calloc(1, sizeof(*gs));
if (gs == NULL) {
return NULL;
}
- LOG("Constructing a scaffold of %p for gui_window %p", gs, toplevel);
+ NSLOG(netsurf, INFO,
+ "Constructing a scaffold of %p for gui_window %p", gs, toplevel);
gs->top_level = toplevel;
@@ -2278,7 +2284,7 @@ struct nsgtk_scaffolding *nsgtk_new_scaffolding(struct gui_window *toplevel)
/* finally, show the window. */
gtk_widget_show(GTK_WIDGET(gs->window));
- LOG("creation complete");
+ NSLOG(netsurf, INFO, "creation complete");
return gs;
}
@@ -2466,7 +2472,8 @@ gui_search_web_provider_update(const char *provider_name,
GdkPixbuf *srch_pixbuf = NULL;
char *searchcontent;
- LOG("name:%s bitmap %p", provider_name, provider_bitmap);
+ NSLOG(netsurf, INFO, "name:%s bitmap %p", provider_name,
+ provider_bitmap);
if (provider_bitmap != NULL) {
srch_pixbuf = nsgdk_pixbuf_get_from_surface(provider_bitmap->surface, 16, 16);
@@ -2484,7 +2491,11 @@ gui_search_web_provider_update(const char *provider_name,
/* set the search provider parameters up in each scaffold */
for (current = scaf_list; current != NULL; current = current->next) {
- /* add ico to each window's toolbar */
+ if (current->webSearchEntry == NULL) {
+ continue;
+ }
+
+ /* add ico to each window's toolbar */
if (srch_pixbuf != NULL) {
nsgtk_entry_set_icon_from_pixbuf(current->webSearchEntry,
GTK_ENTRY_ICON_PRIMARY,
diff --git a/frontends/gtk/schedule.c b/frontends/gtk/schedule.c
index cf0333388..d5b45674b 100644
--- a/frontends/gtk/schedule.c
+++ b/frontends/gtk/schedule.c
@@ -21,14 +21,10 @@
#include <stdbool.h>
#include "utils/errors.h"
+#include "utils/log.h"
#include "gtk/schedule.h"
-#ifdef DEBUG_GTK_SCHEDULE
-#include "utils/log.h"
-#else
-#define LOG(format, args...) ((void) 0)
-#endif
/** Killable callback closure embodiment. */
typedef struct {
@@ -50,7 +46,7 @@ nsgtk_schedule_generic_callback(gpointer data)
_nsgtk_callback_t *cb = (_nsgtk_callback_t *)(data);
if (cb->callback_killed) {
/* This callback instance has been killed. */
- LOG("CB at %p already dead.", cb);
+ NSLOG(schedule, DEBUG, "CB at %p already dead.", cb);
}
queued_callbacks = g_list_remove(queued_callbacks, cb);
pending_callbacks = g_list_append(pending_callbacks, cb);
@@ -64,7 +60,9 @@ nsgtk_schedule_kill_callback(void *_target, void *_match)
_nsgtk_callback_t *match = (_nsgtk_callback_t *)_match;
if ((target->callback == match->callback) &&
(target->context == match->context)) {
- LOG("Found match for %p(%p), killing.", target->callback, target->context);
+ NSLOG(schedule, DEBUG,
+ "Found match for %p(%p), killing.",
+ target->callback, target->context);
target->callback = NULL;
target->context = NULL;
target->callback_killed = true;
@@ -122,7 +120,9 @@ schedule_run(void)
/* Clear the pending list. */
pending_callbacks = NULL;
- LOG("Captured a run of %d callbacks to fire.", g_list_length(this_run));
+ NSLOG(schedule, DEBUG,
+ "Captured a run of %d callbacks to fire.",
+ g_list_length(this_run));
/* Run all the callbacks which made it this far. */
while (this_run != NULL) {
diff --git a/frontends/gtk/ssl_cert.c b/frontends/gtk/ssl_cert.c
index 5388f0194..9d98db1f6 100644
--- a/frontends/gtk/ssl_cert.c
+++ b/frontends/gtk/ssl_cert.c
@@ -183,7 +183,7 @@ nserror gtk_cert_verify(struct nsurl *url,
res = nsgtk_builder_new_from_resname("ssl", &ncwin->builder);
if (res != NSERROR_OK) {
- LOG("SSL UI builder init failed");
+ NSLOG(netsurf, INFO, "SSL UI builder init failed");
free(ncwin);
return res;
}
diff --git a/frontends/gtk/tabs.c b/frontends/gtk/tabs.c
index 6adce3a06..dbe9d405b 100644
--- a/frontends/gtk/tabs.c
+++ b/frontends/gtk/tabs.c
@@ -147,18 +147,20 @@ nsgtk_tab_switch_page_after(GtkNotebook *notebook,
if ((srcpagenum != -1) &&
(srcpagenum != (gint)selpagenum)) {
/* ensure the add tab is not actually selected */
- LOG("src %d sel %d", srcpagenum, selpagenum);
+ NSLOG(netsurf, INFO, "src %d sel %d", srcpagenum,
+ selpagenum);
srcpage = gtk_notebook_get_nth_page(notebook, srcpagenum);
gw = g_object_get_data(G_OBJECT(srcpage), "gui_window");
if ((gw != NULL) && (nsgtk_get_scaffold(gw) != NULL)) {
error = nsgtk_scaffolding_new_tab(gw);
if (error != NSERROR_OK) {
- LOG("Failed to open new tab.");
+ NSLOG(netsurf, INFO,
+ "Failed to open new tab.");
}
}
}
} else {
- LOG("sel %d", selpagenum);
+ NSLOG(netsurf, INFO, "sel %d", selpagenum);
/* tab with page in it */
gw = g_object_get_data(G_OBJECT(selpage), "gui_window");
if (gw != NULL) {
diff --git a/frontends/gtk/throbber.c b/frontends/gtk/throbber.c
index 9392c3909..b8efceca1 100644
--- a/frontends/gtk/throbber.c
+++ b/frontends/gtk/throbber.c
@@ -59,12 +59,14 @@ nserror nsgtk_throbber_init(void)
if (res != NSERROR_OK) {
break;
}
- LOG("%s",resname);
+ NSLOG(netsurf, INFO, "%s", resname);
}
if (frame < 1) {
/* we need at least two frames - one for idle, one for active */
- LOG("Insufficent number of frames (%d) in throbber animation.", frame);
+ NSLOG(netsurf, INFO,
+ "Insufficent number of frames (%d) in throbber animation.",
+ frame);
res = NSERROR_INIT_FAILED;
}
diff --git a/frontends/gtk/toolbar.c b/frontends/gtk/toolbar.c
index 1f8dbbb7c..e93bd49f9 100644
--- a/frontends/gtk/toolbar.c
+++ b/frontends/gtk/toolbar.c
@@ -26,6 +26,7 @@
#include "utils/log.h"
#include "utils/messages.h"
#include "utils/nsoption.h"
+#include "utils/file.h"
#include "gtk/gui.h"
#include "gtk/warn.h"
@@ -44,7 +45,7 @@ static bool edit_mode = false;
struct nsgtk_toolbar_custom_store {
GtkWidget *window;
- GtkWidget *store_buttons[PLACEHOLDER_BUTTON];
+ GtkWidget *store_buttons[PLACEHOLDER_BUTTON];
GtkWidget *widgetvbox;
GtkWidget *currentbar;
char numberh; /* current horizontal location while adding */
@@ -107,13 +108,13 @@ static char *remove_underscores(const char *s, bool replacespace)
ret = malloc(len + 1);
if (ret == NULL) {
return NULL;
- }
+ }
for (i = 0, ii = 0; i < len; i++) {
if (s[i] != '_') {
ret[ii++] = s[i];
- } else if (replacespace) {
+ } else if (replacespace) {
ret[ii++] = ' ';
- }
+ }
}
ret[ii] = '\0';
return ret;
@@ -208,18 +209,18 @@ nsgtk_theme_searchimage_default(nsgtk_search_buttons tbbutton,
switch (tbbutton) {
case (SEARCH_BACK_BUTTON):
- image = GTK_IMAGE(nsgtk_image_new_from_stock(NSGTK_STOCK_GO_BACK,
- iconsize));
+ image = GTK_IMAGE(nsgtk_image_new_from_stock(
+ NSGTK_STOCK_GO_BACK, iconsize));
break;
case (SEARCH_FORWARD_BUTTON):
- image = GTK_IMAGE(nsgtk_image_new_from_stock(NSGTK_STOCK_GO_FORWARD,
- iconsize));
+ image = GTK_IMAGE(nsgtk_image_new_from_stock(
+ NSGTK_STOCK_GO_FORWARD, iconsize));
break;
case (SEARCH_CLOSE_BUTTON):
- image = GTK_IMAGE(nsgtk_image_new_from_stock(NSGTK_STOCK_CLOSE,
- iconsize));
+ image = GTK_IMAGE(nsgtk_image_new_from_stock(
+ NSGTK_STOCK_CLOSE, iconsize));
break;
default:
@@ -227,7 +228,8 @@ nsgtk_theme_searchimage_default(nsgtk_search_buttons tbbutton,
}
if (usedef && (image == NULL)) {
- image = GTK_IMAGE(nsgtk_image_new_from_stock("gtk-missing-image", iconsize));
+ image = GTK_IMAGE(nsgtk_image_new_from_stock(
+ "gtk-missing-image", iconsize));
}
return image;
@@ -255,7 +257,6 @@ static struct nsgtk_theme *nsgtk_theme_load(GtkIconSize iconsize, bool usedef)
theme->image[btnloop] = nsgtk_theme_image_default(btnloop,
iconsize,
usedef);
-
}
for (btnloop = SEARCH_BACK_BUTTON;
@@ -823,8 +824,9 @@ static void nsgtk_toolbar_close(struct nsgtk_scaffolding *g)
*/
static gboolean nsgtk_toolbar_cancel_clicked(GtkWidget *widget, gpointer data)
{
- edit_mode = false;
struct nsgtk_scaffolding *g = (struct nsgtk_scaffolding *)data;
+
+ edit_mode = false;
/* reset g->buttons->location */
for (int i = BACK_BUTTON; i < PLACEHOLDER_BUTTON; i++) {
nsgtk_scaffolding_button(g, i)->location =
@@ -950,6 +952,7 @@ void nsgtk_toolbar_customization_load(struct nsgtk_scaffolding *g)
*/
static nserror nsgtk_toolbar_customization_save(struct nsgtk_scaffolding *g)
{
+ char *choices = NULL;
char *order;
int order_len = PLACEHOLDER_BUTTON * 12; /* length of order buffer */
int tbidx;
@@ -971,7 +974,8 @@ static nserror nsgtk_toolbar_customization_save(struct nsgtk_scaffolding *g)
nsgtk_scaffolding_button(g, tbidx)->location);
if (plen == order_len) {
/* ran out of space, bail early */
- LOG("toolbar ordering exceeded available space");
+ NSLOG(netsurf, INFO,
+ "toolbar ordering exceeded available space");
break;
}
cur += plen;
@@ -980,6 +984,13 @@ static nserror nsgtk_toolbar_customization_save(struct nsgtk_scaffolding *g)
nsoption_set_charp(toolbar_order, order);
+ /* ensure choices are saved */
+ netsurf_mkpath(&choices, NULL, 2, nsgtk_config_home, "Choices");
+ if (choices != NULL) {
+ nsoption_write(choices, NULL, NULL);
+ free(choices);
+ }
+
return NSERROR_OK;
}
@@ -989,8 +1000,9 @@ static nserror nsgtk_toolbar_customization_save(struct nsgtk_scaffolding *g)
*/
static gboolean nsgtk_toolbar_persist(GtkWidget *widget, gpointer data)
{
- edit_mode = false;
struct nsgtk_scaffolding *g = (struct nsgtk_scaffolding *)data;
+
+ edit_mode = false;
/* save state to file, update toolbars for all windows */
nsgtk_toolbar_customization_save(g);
nsgtk_toolbar_cast(g);
@@ -1097,7 +1109,6 @@ nsgtk_toolbar_store_action(GtkWidget *widget, GdkDragContext *gdc,
*/
static void nsgtk_toolbar_window_open(struct nsgtk_scaffolding *g)
{
- int x = 0, y = 0;
struct nsgtk_theme *theme;
nserror res;
@@ -1110,8 +1121,8 @@ static void nsgtk_toolbar_window_open(struct nsgtk_scaffolding *g)
res = nsgtk_builder_new_from_resname("toolbar", &window->builder);
if (res != NSERROR_OK) {
- LOG("Toolbar UI builder init failed");
- nsgtk_warning(messages_get("NoMemory"), 0);
+ NSLOG(netsurf, INFO, "Toolbar UI builder init failed");
+ nsgtk_warning("Toolbar UI builder init failed", 0);
nsgtk_toolbar_cancel_clicked(NULL, g);
free(theme);
return;
@@ -1119,8 +1130,8 @@ static void nsgtk_toolbar_window_open(struct nsgtk_scaffolding *g)
gtk_builder_connect_signals(window->builder, NULL);
- window->window = GTK_WIDGET(gtk_builder_get_object(window->builder,
- "toolbarwindow"));
+ window->window = GTK_WIDGET(gtk_builder_get_object(
+ window->builder, "dialogToolbar"));
if (window->window == NULL) {
nsgtk_warning(messages_get("NoMemory"), 0);
nsgtk_toolbar_cancel_clicked(NULL, g);
@@ -1128,8 +1139,11 @@ static void nsgtk_toolbar_window_open(struct nsgtk_scaffolding *g)
return;
}
- window->widgetvbox = GTK_WIDGET(gtk_builder_get_object(window->builder,
- "widgetvbox"));
+ gtk_window_set_transient_for(GTK_WINDOW(window->window),
+ nsgtk_scaffolding_window(g));
+
+ window->widgetvbox = GTK_WIDGET(gtk_builder_get_object(
+ window->builder, "widgetvbox"));
if (window->widgetvbox == NULL) {
nsgtk_warning(messages_get("NoMemory"), 0);
nsgtk_toolbar_cancel_clicked(NULL, g);
@@ -1137,9 +1151,12 @@ static void nsgtk_toolbar_window_open(struct nsgtk_scaffolding *g)
return;
}
- window->numberh = NSGTK_STORE_WIDTH; /* preset to width [in buttons] of */
+ /* preset to width [in buttons] of */
+ window->numberh = NSGTK_STORE_WIDTH;
+
/* store to cause creation of a new toolbar */
window->currentbutton = -1;
+
/* load toolbuttons */
/* add toolbuttons to window */
/* set event handlers */
@@ -1159,33 +1176,20 @@ static void nsgtk_toolbar_window_open(struct nsgtk_scaffolding *g)
}
free(theme);
- gtk_window_set_transient_for(GTK_WINDOW(window->window),
- nsgtk_scaffolding_window(g));
- gtk_window_set_title(GTK_WINDOW(window->window), messages_get(
- "gtkToolBarTitle"));
+
gtk_window_set_accept_focus(GTK_WINDOW(window->window), FALSE);
+
gtk_drag_dest_set(GTK_WIDGET(window->window), GTK_DEST_DEFAULT_MOTION |
GTK_DEST_DEFAULT_DROP, &entry, 1, GDK_ACTION_COPY);
- gtk_widget_show_all(window->window);
- gtk_window_set_position(GTK_WINDOW(window->window),
- GTK_WIN_POS_CENTER_ON_PARENT);
- gtk_window_get_position(nsgtk_scaffolding_window(g), &x, &y);
- gtk_window_move(GTK_WINDOW(window->window), x, y + 100);
-
- g_signal_connect(GTK_WIDGET(gtk_builder_get_object(window->builder,
- "cancelbutton")),
- "clicked",
- G_CALLBACK(nsgtk_toolbar_cancel_clicked),
- g);
- g_signal_connect(GTK_WIDGET(gtk_builder_get_object(window->builder,
- "okbutton")),
+ g_signal_connect(GTK_WIDGET(gtk_builder_get_object(
+ window->builder, "close")),
"clicked",
G_CALLBACK(nsgtk_toolbar_persist),
g);
- g_signal_connect(GTK_WIDGET(gtk_builder_get_object(window->builder,
- "resetbutton")),
+ g_signal_connect(GTK_WIDGET(gtk_builder_get_object(
+ window->builder, "reset")),
"clicked",
G_CALLBACK(nsgtk_toolbar_reset),
g);
@@ -1198,6 +1202,8 @@ static void nsgtk_toolbar_window_open(struct nsgtk_scaffolding *g)
g_signal_connect(window->window, "drag-motion",
G_CALLBACK(nsgtk_toolbar_store_action), g);
+
+ gtk_widget_show_all(window->window);
}
/**
@@ -1341,33 +1347,37 @@ nsgtk_toolbar_set_handler(struct nsgtk_scaffolding *g, nsgtk_toolbar_button i)
case URL_BAR_ITEM:
nsgtk_scaffolding_update_url_bar_ref(g);
g_signal_connect(GTK_WIDGET(nsgtk_scaffolding_urlbar(g)),
- "activate", G_CALLBACK(
- nsgtk_window_url_activate_event), g);
+ "activate", G_CALLBACK(
+ nsgtk_window_url_activate_event), g);
g_signal_connect(GTK_WIDGET(nsgtk_scaffolding_urlbar(g)),
- "changed", G_CALLBACK(
- nsgtk_window_url_changed), g);
+ "changed", G_CALLBACK(
+ nsgtk_window_url_changed), g);
break;
+
case THROBBER_ITEM:
nsgtk_scaffolding_update_throbber_ref(g);
break;
+
case WEBSEARCH_ITEM:
nsgtk_scaffolding_update_websearch_ref(g);
g_signal_connect(GTK_WIDGET(nsgtk_scaffolding_websearch(g)),
- "activate", G_CALLBACK(
- nsgtk_websearch_activate), g);
+ "activate", G_CALLBACK(
+ nsgtk_websearch_activate), g);
g_signal_connect(GTK_WIDGET(nsgtk_scaffolding_websearch(g)),
- "button-press-event", G_CALLBACK(
- nsgtk_websearch_clear), g);
+ "button-press-event", G_CALLBACK(
+ nsgtk_websearch_clear), g);
break;
+
default:
if ((nsgtk_scaffolding_button(g, i)->bhandler != NULL) &&
- (nsgtk_scaffolding_button(g, i)->button
- != NULL))
- g_signal_connect(nsgtk_scaffolding_button(g, i)->
- button, "clicked",
- G_CALLBACK(nsgtk_scaffolding_button(g,
- i)->bhandler), g);
- break;
+ (nsgtk_scaffolding_button(g, i)->button != NULL)) {
+ g_signal_connect(
+ nsgtk_scaffolding_button(g, i)->button,
+ "clicked",
+ G_CALLBACK(nsgtk_scaffolding_button(
+ g, i)->bhandler), g);
+ }
+ break;
}
}
@@ -1459,7 +1469,8 @@ DATAHANDLER(prevtab, PREVTAB, window)
DATAHANDLER(guide, GUIDE, window)
DATAHANDLER(info, INFO, window)
#undef DATAHANDLER
-#define DATAHANDLER(p, q, r)\
+
+#define DATAHANDLER(p, q, r) \
gboolean nsgtk_toolbar_##p##_button_data(GtkWidget *widget, GdkDragContext\
*cont, GtkSelectionData *selection, guint info, guint time,\
gpointer data)\
@@ -1480,5 +1491,3 @@ gboolean nsgtk_toolbar_##p##_toolbar_button_data(GtkWidget *widget,\
DATAHANDLER(throbber, THROBBER, window)
DATAHANDLER(websearch, WEBSEARCH, window)
#undef DATAHANDLER
-
-
diff --git a/frontends/gtk/viewdata.c b/frontends/gtk/viewdata.c
index 6ed9dd9ac..d633238d0 100644
--- a/frontends/gtk/viewdata.c
+++ b/frontends/gtk/viewdata.c
@@ -371,7 +371,7 @@ window_init(const char *title,
res = nsgtk_builder_new_from_resname("viewdata", &newctx->builder);
if (res != NSERROR_OK) {
- LOG("Viewdata UI builder init failed");
+ NSLOG(netsurf, INFO, "Viewdata UI builder init failed");
free(newctx);
return res;
}
@@ -381,7 +381,7 @@ window_init(const char *title,
window = GTK_WINDOW(gtk_builder_get_object(newctx->builder,
"ViewDataWindow"));
if (window == NULL) {
- LOG("Unable to find window in builder ");
+ NSLOG(netsurf, INFO, "Unable to find window in builder ");
/* free the builder */
g_object_unref(G_OBJECT(newctx->builder));
@@ -616,7 +616,7 @@ static char** xdg_data_strvec(void)
xdg_data_home, xdg_data_dirs);
}
- LOG("%s", xdg_data_path);
+ NSLOG(netsurf, INFO, "%s", xdg_data_path);
svec = filepath_path_to_strvec(xdg_data_path);
free(xdg_data_path);
@@ -651,7 +651,7 @@ static char *xdg_get_default_app(const char *path, const char *mimetype)
fname = malloc(fname_len);
snprintf(fname, fname_len, "%s/applications/defaults.list", path);
- LOG("Checking %s", fname);
+ NSLOG(netsurf, INFO, "Checking %s", fname);
fp = fopen(fname, "r");
free(fname);
@@ -674,8 +674,11 @@ static char *xdg_get_default_app(const char *path, const char *mimetype)
ret = strdup(line + mimetype_len + 1);
- LOG("Found line match for %s length %zu\n", mimetype, rd);
- LOG("Result %s", ret);
+ NSLOG(netsurf, INFO,
+ "Found line match for %s length %zu\n",
+ mimetype,
+ rd);
+ NSLOG(netsurf, INFO, "Result %s", ret);
break;
}
@@ -714,7 +717,7 @@ static char *xdg_get_exec_cmd(const char *path, const char *desktop)
fname = malloc(fname_len);
snprintf(fname, fname_len, "%s/applications/%s", path, desktop);
- LOG("Checking %s", fname);
+ NSLOG(netsurf, INFO, "Checking %s", fname);
fp = fopen(fname, "r");
free(fname);
@@ -735,8 +738,8 @@ static char *xdg_get_exec_cmd(const char *path, const char *desktop)
ret = strdup(line + SLEN("Exec="));
- LOG("Found Exec length %zu", rd);
- LOG("Result %s", ret);
+ NSLOG(netsurf, INFO, "Found Exec length %zu", rd);
+ NSLOG(netsurf, INFO, "Result %s", ret);
break;
}
@@ -801,7 +804,7 @@ static char **build_exec_argv(const char *fname, const char *exec_cmd)
argv[aidx] = exec_arg(start, cur - start, fname);
if (argv[aidx] != NULL) {
- LOG("adding \"%s\"", argv[aidx]);
+ NSLOG(netsurf, INFO, "adding \"%s\"", argv[aidx]);
aidx++;
}
}
diff --git a/frontends/gtk/window.c b/frontends/gtk/window.c
index de5311e2e..7f24d40ac 100644
--- a/frontends/gtk/window.c
+++ b/frontends/gtk/window.c
@@ -42,7 +42,6 @@
#include "netsurf/plotters.h"
#include "netsurf/form.h"
#include "netsurf/keypress.h"
-#include "desktop/textarea.h"
#include "desktop/searchweb.h"
#include "desktop/textinput.h"
@@ -355,6 +354,7 @@ static gboolean nsgtk_window_button_press_event(GtkWidget *widget,
break;
case 3: /* Right button, usually. Action button, context menu. */
+ /** \todo determine if hiding the caret here is necessary */
browser_window_remove_caret(g->bw, true);
nsgtk_scaffolding_context_menu(g->scaffold,
g->mouse.pressed_x,
@@ -458,7 +458,7 @@ nsgtk_window_scroll_event(GtkWidget *widget,
break;
#endif
default:
- LOG("Unhandled mouse scroll direction");
+ NSLOG(netsurf, INFO, "Unhandled mouse scroll direction");
return TRUE;
}
@@ -741,7 +741,7 @@ gui_window_create(struct browser_window *bw,
res = nsgtk_builder_new_from_resname("tabcontents", &tab_builder);
if (res != NSERROR_OK) {
- LOG("Tab contents UI builder init failed");
+ NSLOG(netsurf, INFO, "Tab contents UI builder init failed");
return NULL;
}
@@ -754,7 +754,8 @@ gui_window_create(struct browser_window *bw,
return NULL;
}
- LOG("Creating gui window %p for browser window %p", g, bw);
+ NSLOG(netsurf, INFO, "Creating gui window %p for browser window %p",
+ g, bw);
g->bw = bw;
g->mouse.state = 0;
@@ -903,10 +904,10 @@ void nsgtk_window_destroy_browser(struct gui_window *gw)
static void gui_window_destroy(struct gui_window *g)
{
- LOG("gui_window: %p", g);
+ NSLOG(netsurf, INFO, "gui_window: %p", g);
assert(g != NULL);
assert(g->bw != NULL);
- LOG("scaffolding: %p", g->scaffold);
+ NSLOG(netsurf, INFO, "scaffolding: %p", g->scaffold);
if (g->prev) {
g->prev->next = g->next;
@@ -918,7 +919,7 @@ static void gui_window_destroy(struct gui_window *g)
g->next->prev = g->prev;
}
- LOG("window list head: %p", window_list);
+ NSLOG(netsurf, INFO, "window list head: %p", window_list);
}
/**
@@ -940,13 +941,13 @@ static void gui_window_set_icon(struct gui_window *gw, struct hlcache_handle *ic
if (icon != NULL) {
icon_bitmap = content_get_bitmap(icon);
if (icon_bitmap != NULL) {
- LOG("Using %p bitmap", icon_bitmap);
+ NSLOG(netsurf, INFO, "Using %p bitmap", icon_bitmap);
gw->icon = nsgdk_pixbuf_get_from_surface(icon_bitmap->surface, 16, 16);
}
}
if (gw->icon == NULL) {
- LOG("Using default favicon");
+ NSLOG(netsurf, INFO, "Using default favicon");
g_object_ref(favicon_pixbuf);
gw->icon = favicon_pixbuf;
}
@@ -1236,7 +1237,7 @@ gui_window_get_dimensions(struct gui_window *gw,
*width /= scale;
*height /= scale;
}
- LOG("gw:%p width:%i height:%i", gw, *width, *height);
+ NSLOG(netsurf, INFO, "gw:%p width:%i height:%i", gw, *width, *height);
return NSERROR_OK;
}
@@ -1269,8 +1270,8 @@ static void gui_window_create_form_select_menu(struct gui_window *g,
item = 0;
option = form_select_get_option(control, item);
while (option != NULL) {
- LOG("Item %"PRIdPTR" option %p text %s",
- item, option, option->text);
+ NSLOG(netsurf, INFO, "Item %"PRIdPTR" option %p text %s",
+ item, option, option->text);
menu_item = gtk_check_menu_item_new_with_label(option->text);
if (option->selected) {
gtk_check_menu_item_set_active(
@@ -1313,10 +1314,10 @@ gui_window_file_gadget_open(struct gui_window *g,
NSGTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
NULL);
- LOG("*** open dialog: %p", dialog);
+ NSLOG(netsurf, INFO, "*** open dialog: %p", dialog);
int ret = gtk_dialog_run(GTK_DIALOG(dialog));
- LOG("*** return value: %d", ret);
+ NSLOG(netsurf, INFO, "*** return value: %d", ret);
if (ret == GTK_RESPONSE_ACCEPT) {
char *filename;
diff --git a/frontends/monkey/browser.c b/frontends/monkey/browser.c
index 16d33010d..1fbbbf0b1 100644
--- a/frontends/monkey/browser.c
+++ b/frontends/monkey/browser.c
@@ -471,7 +471,7 @@ monkey_window_handle_redraw(int argc, char **argv)
clip.y1 = atoi(argv[6]);
}
- LOG("Issue redraw");
+ NSLOG(netsurf, INFO, "Issue redraw");
fprintf(stdout, "WINDOW REDRAW WIN %d START\n", atoi(argv[2]));
browser_window_redraw(gw->bw, gw->scrollx, gw->scrolly, &clip, &ctx);
fprintf(stdout, "WINDOW REDRAW WIN %d STOP\n", atoi(argv[2]));
diff --git a/frontends/monkey/dispatch.c b/frontends/monkey/dispatch.c
index b531f05f9..e60325cf1 100644
--- a/frontends/monkey/dispatch.c
+++ b/frontends/monkey/dispatch.c
@@ -40,7 +40,7 @@ monkey_register_handler(const char *cmd, handle_command_fn fn)
{
monkey_cmdhandler_t *ret = calloc(sizeof(*ret), 1);
if (ret == NULL) {
- LOG("Unable to allocate handler");
+ NSLOG(netsurf, INFO, "Unable to allocate handler");
return NSERROR_NOMEM;
}
ret->cmd = strdup(cmd);
diff --git a/frontends/monkey/filetype.c b/frontends/monkey/filetype.c
index 20bd1edad..979796baf 100644
--- a/frontends/monkey/filetype.c
+++ b/frontends/monkey/filetype.c
@@ -85,7 +85,8 @@ void monkey_fetch_filetype_init(const char *mimefile)
fh = fopen(mimefile, "r");
if (fh == NULL) {
- LOG("Unable to open a mime.types file, so using a minimal one for you.");
+ NSLOG(netsurf, INFO,
+ "Unable to open a mime.types file, so using a minimal one for you.");
return;
}
diff --git a/frontends/monkey/main.c b/frontends/monkey/main.c
index 1bea02471..53cde5a72 100644
--- a/frontends/monkey/main.c
+++ b/frontends/monkey/main.c
@@ -278,20 +278,20 @@ static void monkey_run(void)
/* setup timeout */
switch (schedtm) {
case -1:
- LOG("Iterate blocking");
+ NSLOG(netsurf, INFO, "Iterate blocking");
fprintf(stdout, "GENERIC POLL BLOCKING\n");
timeout = NULL;
break;
case 0:
- LOG("Iterate immediate");
+ NSLOG(netsurf, INFO, "Iterate immediate");
tv.tv_sec = 0;
tv.tv_usec = 0;
timeout = &tv;
break;
default:
- LOG("Iterate non-blocking");
+ NSLOG(netsurf, INFO, "Iterate non-blocking");
fprintf(stdout, "GENERIC POLL TIMED %d\n", schedtm);
tv.tv_sec = schedtm / 1000; /* miliseconds to seconds */
tv.tv_usec = (schedtm % 1000) * 1000; /* remainder to microseconds */
@@ -361,7 +361,7 @@ main(int argc, char **argv)
messages = filepath_find(respaths, "Messages");
ret = messages_add_from_file(messages);
if (ret != NSERROR_OK) {
- LOG("Messages failed to load");
+ NSLOG(netsurf, INFO, "Messages failed to load");
}
/* common initialisation */
@@ -404,5 +404,8 @@ main(int argc, char **argv)
/* finalise options */
nsoption_finalise(nsoptions, nsoptions_default);
+ /* finalise logging */
+ nslog_finalise();
+
return 0;
}
diff --git a/frontends/monkey/schedule.c b/frontends/monkey/schedule.c
index af1144a0e..3d76997f4 100644
--- a/frontends/monkey/schedule.c
+++ b/frontends/monkey/schedule.c
@@ -24,12 +24,6 @@
#include "monkey/schedule.h"
-#ifdef DEBUG_SCHEDULER
-#define SRLOG(x...) LOG(x)
-#else
-#define SRLOG(x...) ((void) 0)
-#endif
-
/* linked list of scheduled callbacks */
static struct nscallback *schedule_list = NULL;
@@ -63,7 +57,7 @@ static nserror schedule_remove(void (*callback)(void *p), void *p)
return NSERROR_OK;
}
- SRLOG("removing %p, %p", callback, p);
+ NSLOG(schedule, DEBUG, "removing %p, %p", callback, p);
cur_nscb = schedule_list;
prev_nscb = NULL;
@@ -73,7 +67,7 @@ static nserror schedule_remove(void (*callback)(void *p), void *p)
(cur_nscb->p == p)) {
/* item to remove */
- SRLOG("callback entry %p removing %p(%p)",
+ NSLOG(schedule, DEBUG, "callback entry %p removing %p(%p)",
cur_nscb, cur_nscb->callback, cur_nscb->p);
/* remove callback */
@@ -109,7 +103,7 @@ nserror monkey_schedule(int tival, void (*callback)(void *p), void *p)
return ret;
}
- SRLOG("Adding %p(%p) in %d", callback, p, tival);
+ NSLOG(schedule, DEBUG, "Adding %p(%p) in %d", callback, p, tival);
tv.tv_sec = tival / 1000; /* miliseconds to seconds */
tv.tv_usec = (tival % 1000) * 1000; /* remainder to microseconds */
@@ -190,8 +184,8 @@ int monkey_schedule_run(void)
/* make rettime relative to now */
timersub(&nexttime, &tv, &rettime);
- SRLOG("returning time to next event as %ldms",
- (rettime.tv_sec * 1000) + (rettime.tv_usec / 1000));
+ NSLOG(schedule, DEBUG, "returning time to next event as %ldms",
+ (long)((rettime.tv_sec * 1000) + (rettime.tv_usec / 1000)));
/* return next event time in milliseconds (24days max wait) */
return (rettime.tv_sec * 1000) + (rettime.tv_usec / 1000);
@@ -204,13 +198,14 @@ void monkey_schedule_list(void)
gettimeofday(&tv, NULL);
- LOG("schedule list at %lld:%ld", (long long)tv.tv_sec, tv.tv_usec);
+ NSLOG(netsurf, INFO, "schedule list at %lld:%ld",
+ (long long)tv.tv_sec, tv.tv_usec);
cur_nscb = schedule_list;
while (cur_nscb != NULL) {
- LOG("Schedule %p at %lld:%ld",
- cur_nscb, (long long)cur_nscb->tv.tv_sec, cur_nscb->tv.tv_usec);
+ NSLOG(netsurf, INFO, "Schedule %p at %lld:%ld", cur_nscb,
+ (long long)cur_nscb->tv.tv_sec, cur_nscb->tv.tv_usec);
cur_nscb = cur_nscb->next;
}
}
diff --git a/frontends/riscos/401login.c b/frontends/riscos/401login.c
index a23c01c90..4b2deb16b 100644
--- a/frontends/riscos/401login.c
+++ b/frontends/riscos/401login.c
@@ -191,7 +191,8 @@ void ro_gui_401login_close(wimp_w w)
error = xwimp_delete_window(w);
if (error) {
- LOG("xwimp_delete_window: 0x%x:%s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_delete_window: 0x%x:%s",
+ error->errnum, error->errmess);
ro_warn_user("WimpError", error->errmess);
}
ro_gui_wimp_event_finalise(w);
@@ -212,7 +213,7 @@ bool ro_gui_401login_apply(wimp_w w)
auth = malloc(strlen(session->uname) + strlen(session->pwd) + 2);
if (!auth) {
- LOG("calloc failed");
+ NSLOG(netsurf, INFO, "calloc failed");
ro_warn_user("NoMemory", 0);
return false;
}
diff --git a/frontends/riscos/bitmap.c b/frontends/riscos/bitmap.c
index 1a3524633..d554d54b4 100644
--- a/frontends/riscos/bitmap.c
+++ b/frontends/riscos/bitmap.c
@@ -287,7 +287,10 @@ bool riscos_bitmap_save(void *vbitmap, const char *path, unsigned flags)
error = xosspriteop_save_sprite_file(osspriteop_USER_AREA,
(bitmap->sprite_area), path);
if (error) {
- LOG("xosspriteop_save_sprite_file: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO,
+ "xosspriteop_save_sprite_file: 0x%x: %s",
+ error->errnum,
+ error->errmess);
ro_warn_user("SaveError", error->errmess);
return false;
}
@@ -347,7 +350,8 @@ bool riscos_bitmap_save(void *vbitmap, const char *path, unsigned flags)
error = xosfind_openoutw(0, path, NULL, &fw);
if (error) {
- LOG("xosfind_openoutw: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xosfind_openoutw: 0x%x: %s",
+ error->errnum, error->errmess);
free(chunk_buf);
ro_warn_user("SaveError", error->errmess);
return false;
@@ -361,7 +365,8 @@ bool riscos_bitmap_save(void *vbitmap, const char *path, unsigned flags)
if (!error)
error = xosgbpb_writew(fw, (byte*)p, image_size, NULL);
if (error) {
- LOG("xosgbpb_writew: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xosgbpb_writew: 0x%x: %s",
+ error->errnum, error->errmess);
free(chunk_buf);
xosfind_closew(fw);
ro_warn_user("SaveError", error->errmess);
@@ -406,7 +411,10 @@ bool riscos_bitmap_save(void *vbitmap, const char *path, unsigned flags)
}
error = xosgbpb_writew(fw, (byte*)chunk_buf, dp-chunk_buf, NULL);
if (error) {
- LOG("xosgbpb_writew: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO,
+ "xosgbpb_writew: 0x%x: %s",
+ error->errnum,
+ error->errmess);
free(chunk_buf);
xosfind_closew(fw);
ro_warn_user("SaveError", error->errmess);
@@ -416,13 +424,15 @@ bool riscos_bitmap_save(void *vbitmap, const char *path, unsigned flags)
error = xosfind_closew(fw);
if (error) {
- LOG("xosfind_closew: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xosfind_closew: 0x%x: %s",
+ error->errnum, error->errmess);
ro_warn_user("SaveError", error->errmess);
}
error = xosfile_set_type(path, osfile_TYPE_SPRITE);
if (error) {
- LOG("xosfile_set_type: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xosfile_set_type: 0x%x: %s",
+ error->errnum, error->errmess);
ro_warn_user("SaveError", error->errmess);
}
@@ -509,7 +519,8 @@ void riscos_bitmap_overlay_sprite(struct bitmap *bitmap,
(osspriteop_id)s,
&w, &h, NULL, NULL);
if (error) {
- LOG("xosspriteop_read_sprite_info: 0x%x:%s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xosspriteop_read_sprite_info: 0x%x:%s",
+ error->errnum, error->errmess);
return;
}
sp_offset = ((s->width + 1) * 4) - w;
@@ -591,7 +602,7 @@ static osspriteop_area *thumbnail_create_8bpp(struct bitmap *bitmap)
sprite_area = (osspriteop_area *)malloc(area_size);
if (!sprite_area) {
- LOG("no memory for malloc()");
+ NSLOG(netsurf, INFO, "no memory for malloc()");
return NULL;
}
sprite_area->size = area_size;
@@ -759,7 +770,8 @@ static void thumbnail_test(void)
area_size = sizeof(osspriteop_area) +
sizeof(osspriteop_header) + sizeof(int);
if ((sprite_area = (osspriteop_area *)malloc(area_size)) == NULL) {
- LOG("Insufficient memory to perform sprite test.");
+ NSLOG(netsurf, INFO,
+ "Insufficient memory to perform sprite test.");
return;
}
sprite_area->size = area_size + 1;
@@ -791,7 +803,7 @@ nserror riscos_bitmap_render(struct bitmap *bitmap,
assert(content);
assert(bitmap);
- LOG("content %p in bitmap %p", content, bitmap);
+ NSLOG(netsurf, INFO, "content %p in bitmap %p", content, bitmap);
/* check if we have access to 32bpp sprites natively */
if (thumbnail_32bpp_available == -1) {
diff --git a/frontends/riscos/buffer.c b/frontends/riscos/buffer.c
index 7176c1c1c..c63a270db 100644
--- a/frontends/riscos/buffer.c
+++ b/frontends/riscos/buffer.c
@@ -107,7 +107,12 @@ void ro_gui_buffer_open(wimp_draw *redraw)
*/
if ((clipping.x1 < clipping.x0) ||
(clipping.y1 < clipping.y0)) {
- LOG("Invalid clipping rectangle (%i, %i) to (%i,%i)", clipping.x0, clipping.y0, clipping.x1, clipping.y1);
+ NSLOG(netsurf, INFO,
+ "Invalid clipping rectangle (%i, %i) to (%i,%i)",
+ clipping.x0,
+ clipping.y0,
+ clipping.x1,
+ clipping.y1);
return;
}
@@ -138,7 +143,7 @@ void ro_gui_buffer_open(wimp_draw *redraw)
(word_width * sprite_size.y * 4) + palette_size;
buffer = (osspriteop_area *)malloc(total_size);
if (!buffer) {
- LOG("Failed to allocate memory");
+ NSLOG(netsurf, INFO, "Failed to allocate memory");
ro_gui_buffer_free();
return;
}
@@ -149,7 +154,8 @@ void ro_gui_buffer_open(wimp_draw *redraw)
mode = tinct_SPRITE_MODE;
#else
if ((error = xwimpreadsysinfo_wimp_mode(&mode)) != NULL) {
- LOG("Error reading mode '%s'", error->errmess);
+ NSLOG(netsurf, INFO, "Error reading mode '%s'",
+ error->errmess);
ro_gui_buffer_free();
return;
}
@@ -177,7 +183,9 @@ void ro_gui_buffer_open(wimp_draw *redraw)
error = xos_read_vdu_variables(PTR_OS_VDU_VAR_LIST(&vars), (int *)&vals);
if (error) {
- LOG("Error reading mode properties '%s'", error->errmess);
+ NSLOG(netsurf, INFO,
+ "Error reading mode properties '%s'",
+ error->errmess);
ro_gui_buffer_free();
return;
}
@@ -233,7 +241,9 @@ void ro_gui_buffer_open(wimp_draw *redraw)
}
break;
default:
- LOG("Unhandled 16bpp format from flags %d", vals.flags);
+ NSLOG(netsurf, INFO,
+ "Unhandled 16bpp format from flags %d",
+ vals.flags);
ro_gui_buffer_free();
return;
}
@@ -261,13 +271,16 @@ void ro_gui_buffer_open(wimp_draw *redraw)
}
break;
default:
- LOG("Unhandled 32bpp data format from flags %d", vals.flags);
+ NSLOG(netsurf, INFO,
+ "Unhandled 32bpp data format from flags %d",
+ vals.flags);
ro_gui_buffer_free();
return;
}
break;
default:
- LOG("Unhandled NCOLOUR value %d", vals.ncolour);
+ NSLOG(netsurf, INFO, "Unhandled NCOLOUR value %d",
+ vals.ncolour);
ro_gui_buffer_free();
return;
}
@@ -305,7 +318,7 @@ void ro_gui_buffer_open(wimp_draw *redraw)
buffer, buffer_name, palette,
clipping.x0, clipping.y0,
clipping.x1, clipping.y1)) != NULL) {
- LOG("Grab error '%s'", error->errmess);
+ NSLOG(netsurf, INFO, "Grab error '%s'", error->errmess);
ro_gui_buffer_free();
return;
}
@@ -314,7 +327,7 @@ void ro_gui_buffer_open(wimp_draw *redraw)
*/
if ((error = xosspriteop_read_save_area_size(osspriteop_PTR,
buffer, (osspriteop_id)(buffer + 1), &size)) != NULL) {
- LOG("Save area error '%s'", error->errmess);
+ NSLOG(netsurf, INFO, "Save area error '%s'", error->errmess);
ro_gui_buffer_free();
return;
}
@@ -329,7 +342,7 @@ void ro_gui_buffer_open(wimp_draw *redraw)
if ((error = xosspriteop_switch_output_to_sprite(osspriteop_PTR,
buffer, (osspriteop_id)(buffer + 1), save_area,
&context0, &context1, &context2, &context3)) != NULL) {
- LOG("Switching error '%s'", error->errmess);
+ NSLOG(netsurf, INFO, "Switching error '%s'", error->errmess);
free(save_area);
ro_gui_buffer_free();
return;
@@ -345,7 +358,8 @@ void ro_gui_buffer_open(wimp_draw *redraw)
*/
if ((error = xos_set_ecf_origin(-ro_plot_origin_x,
-ro_plot_origin_y)) != NULL) {
- LOG("Invalid ECF origin: '%s'", error->errmess);
+ NSLOG(netsurf, INFO, "Invalid ECF origin: '%s'",
+ error->errmess);
}
}
diff --git a/frontends/riscos/configure.c b/frontends/riscos/configure.c
index 9d28616ec..f4dced55b 100644
--- a/frontends/riscos/configure.c
+++ b/frontends/riscos/configure.c
@@ -212,7 +212,10 @@ void ro_gui_configure_open_window(wimp_open *open)
y + configure_icon_height -
CONFIGURE_ICON_PADDING_V);
if (error) {
- LOG("xwimp_resize_icon: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO,
+ "xwimp_resize_icon: 0x%x: %s",
+ error->errnum,
+ error->errmess);
}
x += configure_icon_width;
l++;
@@ -225,7 +228,8 @@ void ro_gui_configure_open_window(wimp_open *open)
error = xwimp_force_redraw(configure_window,
0, -16384, 16384, 0);
if (error) {
- LOG("xwimp_force_redraw: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_force_redraw: 0x%x: %s",
+ error->errnum, error->errmess);
ro_warn_user("WimpError", error->errmess);
}
}
@@ -248,7 +252,8 @@ void ro_gui_configure_open_window(wimp_open *open)
extent.y0 = -max_height;
error = xwimp_set_extent(open->w, &extent);
if (error) {
- LOG("xwimp_set_extent: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_set_extent: 0x%x: %s",
+ error->errnum, error->errmess);
ro_warn_user("WimpError", error->errmess);
return;
}
@@ -259,7 +264,8 @@ void ro_gui_configure_open_window(wimp_open *open)
/* open the window */
error = xwimp_open_window(open);
if (error) {
- LOG("xwimp_open_window: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_open_window: 0x%x: %s",
+ error->errnum, error->errmess);
ro_warn_user("WimpError", error->errmess);
return;
}
@@ -276,7 +282,7 @@ void ro_gui_configure_register(const char *window,
/* create our tool */
tool = calloc(sizeof(struct configure_tool), 1);
if (!tool) {
- LOG("Insufficient memory for calloc()");
+ NSLOG(netsurf, INFO, "Insufficient memory for calloc()");
die("Insufficient memory");
return; /* For the benefit of scan-build */
}
@@ -284,7 +290,7 @@ void ro_gui_configure_register(const char *window,
tool->translated[0] = '\0';
tool->validation = malloc(strlen(window) + 2);
if (!tool->validation) {
- LOG("Insufficient memory for malloc()");
+ NSLOG(netsurf, INFO, "Insufficient memory for malloc()");
die("Insufficient memory");
}
sprintf(tool->validation, "S%s", window);
@@ -311,7 +317,8 @@ void ro_gui_configure_register(const char *window,
CONFIGURE_TOOL_TRANSLATED_SIZE;
error = xwimp_create_icon(&new_icon, &tool->i);
if (error) {
- LOG("xwimp_create_icon: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_create_icon: 0x%x: %s",
+ error->errnum, error->errmess);
die(error->errmess);
}
@@ -360,7 +367,8 @@ bool ro_gui_configure_translate(void)
error = xosbyte1(osbyte_ALPHABET_NUMBER, 127, 0,
&alphabet);
if (error) {
- LOG("failed reading alphabet: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "failed reading alphabet: 0x%x: %s",
+ error->errnum, error->errmess);
/* assume Latin1 */
alphabet = territory_ALPHABET_LATIN1;
}
@@ -381,7 +389,10 @@ bool ro_gui_configure_translate(void)
error = xwimptextop_string_width(tool->translated,
strlen(tool->translated), &icon_width);
if (error) {
- LOG("xwimptextop_string_width: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO,
+ "xwimptextop_string_width: 0x%x: %s",
+ error->errnum,
+ error->errmess);
return false;
}
icon_width += CONFIGURE_ICON_PADDING_H;
@@ -395,7 +406,8 @@ bool ro_gui_configure_translate(void)
configure_icon_width,
0);
if (error) {
- LOG("xwimp_resize_icon: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_resize_icon: 0x%x: %s",
+ error->errnum, error->errmess);
}
}
diff --git a/frontends/riscos/configure/con_image.c b/frontends/riscos/configure/con_image.c
index 49dd4f76d..c7fc7f314 100644
--- a/frontends/riscos/configure/con_image.c
+++ b/frontends/riscos/configure/con_image.c
@@ -150,8 +150,9 @@ void ro_gui_options_image_redraw(wimp_draw *redraw)
icon_state.i = IMAGE_CURRENT_DISPLAY;
error = xwimp_get_icon_state(&icon_state);
if (error) {
- LOG("xwimp_get_icon_state: 0x%x: %s",
- error->errnum, error->errmess);
+ NSLOG(netsurf, INFO,
+ "xwimp_get_icon_state: 0x%x: %s",
+ error->errnum, error->errmess);
ro_warn_user("MenuError", error->errmess);
return;
}
diff --git a/frontends/riscos/configure/con_language.c b/frontends/riscos/configure/con_language.c
index 2030c65c0..77e4f6cb4 100644
--- a/frontends/riscos/configure/con_language.c
+++ b/frontends/riscos/configure/con_language.c
@@ -98,7 +98,8 @@ bool ro_gui_options_language_ok(wimp_w w)
if (temp) {
nsoption_set_charp(language, temp);
} else {
- LOG("No memory to duplicate language code");
+ NSLOG(netsurf, INFO,
+ "No memory to duplicate language code");
ro_warn_user("NoMemory", 0);
}
}
@@ -113,7 +114,8 @@ bool ro_gui_options_language_ok(wimp_w w)
if (temp) {
nsoption_set_charp(accept_language,temp);
} else {
- LOG("No memory to duplicate language code");
+ NSLOG(netsurf, INFO,
+ "No memory to duplicate language code");
ro_warn_user("NoMemory", 0);
}
}
diff --git a/frontends/riscos/configure/con_theme.c b/frontends/riscos/configure/con_theme.c
index fb0d3dfb0..28195dea9 100644
--- a/frontends/riscos/configure/con_theme.c
+++ b/frontends/riscos/configure/con_theme.c
@@ -104,20 +104,23 @@ bool ro_gui_options_theme_initialise(wimp_w w)
return false;
error = xwimp_create_window(&theme_pane_definition, &theme_pane);
if (error) {
- LOG("xwimp_create_window: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_create_window: 0x%x: %s",
+ error->errnum, error->errmess);
return false;
}
state.w = w;
error = xwimp_get_window_state(&state);
if (error) {
- LOG("xwimp_get_window_state: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_get_window_state: 0x%x: %s",
+ error->errnum, error->errmess);
return false;
}
icon_state.w = w;
icon_state.i = THEME_PANE_AREA;
error = xwimp_get_icon_state(&icon_state);
if (error) {
- LOG("xwimp_get_icon_state: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_get_icon_state: 0x%x: %s",
+ error->errnum, error->errmess);
return false;
}
state.w = theme_pane;
@@ -126,7 +129,8 @@ bool ro_gui_options_theme_initialise(wimp_w w)
state.visible.x0 += icon_state.icon.extent.x0 + 16;
state.visible.y0 = state.visible.y1 + icon_state.icon.extent.y0 + 16;
state.visible.y1 += icon_state.icon.extent.y1 - 28;
- LOG("Y0 = %i, y1 = %i", icon_state.icon.extent.y0, icon_state.icon.extent.y1);
+ NSLOG(netsurf, INFO, "Y0 = %i, y1 = %i", icon_state.icon.extent.y0,
+ icon_state.icon.extent.y1);
error = xwimp_open_window_nested(PTR_WIMP_OPEN(&state), w,
wimp_CHILD_LINKS_PARENT_VISIBLE_BOTTOM_OR_LEFT
<< wimp_CHILD_XORIGIN_SHIFT |
@@ -141,7 +145,8 @@ bool ro_gui_options_theme_initialise(wimp_w w)
wimp_CHILD_LINKS_PARENT_VISIBLE_TOP_OR_RIGHT
<< wimp_CHILD_TS_EDGE_SHIFT);
if (error) {
- LOG("xwimp_open_window_nested: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_open_window_nested: 0x%x: %s",
+ error->errnum, error->errmess);
return false;
}
@@ -176,7 +181,8 @@ void ro_gui_options_theme_finalise(wimp_w w)
ro_gui_wimp_event_finalise(theme_pane);
error = xwimp_delete_window(theme_pane);
if (error) {
- LOG("xwimp_delete_window: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_delete_window: 0x%x: %s",
+ error->errnum, error->errmess);
ro_warn_user("WimpError", error->errmess);
}
theme_pane = 0;
@@ -269,7 +275,7 @@ void ro_gui_options_theme_load(void)
ro_toolbar_rebuild(toolbar);
toolbar_display = calloc(sizeof(struct toolbar_display), 1);
if (!toolbar_display) {
- LOG("No memory for calloc()");
+ NSLOG(netsurf, INFO, "No memory for calloc()");
ro_warn_user("NoMemory", 0);
return;
}
@@ -291,7 +297,8 @@ void ro_gui_options_theme_load(void)
state.w = theme_pane;
error = xwimp_get_window_state(&state);
if (error) {
- LOG("xwimp_get_window_state: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_get_window_state: 0x%x: %s",
+ error->errnum, error->errmess);
ro_warn_user("WimpError", error->errmess);
return;
}
diff --git a/frontends/riscos/content-handlers/artworks.c b/frontends/riscos/content-handlers/artworks.c
index 7a7d79cb7..8ec4edcae 100644
--- a/frontends/riscos/content-handlers/artworks.c
+++ b/frontends/riscos/content-handlers/artworks.c
@@ -183,18 +183,19 @@ bool artworks_convert(struct content *c)
xos_read_var_val_size("Alias$LoadArtWorksModules", 0, os_VARTYPE_STRING,
&used, NULL, NULL);
if (used >= 0) {
- LOG("Alias$LoadArtWorksModules not defined");
+ NSLOG(netsurf, INFO, "Alias$LoadArtWorksModules not defined");
msg_data.error = messages_get("AWNotSeen");
- content_broadcast(c, CONTENT_MSG_ERROR, msg_data);
+ content_broadcast(c, CONTENT_MSG_ERROR, &msg_data);
return false;
}
/* load the modules, or do nothing if they're already loaded */
error = xos_cli("LoadArtWorksModules");
if (error) {
- LOG("xos_cli: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xos_cli: 0x%x: %s", error->errnum,
+ error->errmess);
msg_data.error = error->errmess;
- content_broadcast(c, CONTENT_MSG_ERROR, msg_data);
+ content_broadcast(c, CONTENT_MSG_ERROR, &msg_data);
return false;
}
@@ -202,9 +203,10 @@ bool artworks_convert(struct content *c)
error = (os_error*)_swix(AWRender_FileInitAddress, _OUT(0) | _OUT(1),
&init_routine, &init_workspace);
if (error) {
- LOG("AWRender_FileInitAddress: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "AWRender_FileInitAddress: 0x%x: %s",
+ error->errnum, error->errmess);
msg_data.error = error->errmess;
- content_broadcast(c, CONTENT_MSG_ERROR, msg_data);
+ content_broadcast(c, CONTENT_MSG_ERROR, &msg_data);
return false;
}
@@ -212,9 +214,10 @@ bool artworks_convert(struct content *c)
&aw->render_routine,
&aw->render_workspace);
if (error) {
- LOG("AWRender_RenderAddress: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "AWRender_RenderAddress: 0x%x: %s",
+ error->errnum, error->errmess);
msg_data.error = error->errmess;
- content_broadcast(c, CONTENT_MSG_ERROR, msg_data);
+ content_broadcast(c, CONTENT_MSG_ERROR, &msg_data);
return false;
}
@@ -224,9 +227,10 @@ bool artworks_convert(struct content *c)
error = awrender_init(&source_data, &source_size,
init_routine, init_workspace);
if (error) {
- LOG("awrender_init: 0x%x : %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "awrender_init: 0x%x : %s",
+ error->errnum, error->errmess);
msg_data.error = error->errmess;
- content_broadcast(c, CONTENT_MSG_ERROR, msg_data);
+ content_broadcast(c, CONTENT_MSG_ERROR, &msg_data);
return false;
}
@@ -239,13 +243,15 @@ bool artworks_convert(struct content *c)
&aw->y1);
if (error) {
- LOG("AWRender_DocBounds: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "AWRender_DocBounds: 0x%x: %s",
+ error->errnum, error->errmess);
msg_data.error = error->errmess;
- content_broadcast(c, CONTENT_MSG_ERROR, msg_data);
+ content_broadcast(c, CONTENT_MSG_ERROR, &msg_data);
return false;
}
- LOG("bounding box: %d,%d,%d,%d", aw->x0, aw->y0, aw->x1, aw->y1);
+ NSLOG(netsurf, INFO, "bounding box: %d,%d,%d,%d", aw->x0, aw->y0,
+ aw->x1, aw->y1);
/* create the resizable workspace required by the
ArtWorksRenderer rendering routine */
@@ -253,9 +259,10 @@ bool artworks_convert(struct content *c)
aw->size = INITIAL_BLOCK_SIZE;
aw->block = malloc(INITIAL_BLOCK_SIZE);
if (!aw->block) {
- LOG("failed to create block for ArtworksRenderer");
+ NSLOG(netsurf, INFO,
+ "failed to create block for ArtworksRenderer");
msg_data.error = messages_get("NoMemory");
- content_broadcast(c, CONTENT_MSG_ERROR, msg_data);
+ content_broadcast(c, CONTENT_MSG_ERROR, &msg_data);
return false;
}
@@ -368,13 +375,15 @@ bool artworks_redraw(struct content *c, struct content_redraw_data *data,
error = xos_read_vdu_variables(PTR_OS_VDU_VAR_LIST(&vars), vals);
if (error) {
- LOG("xos_read_vdu_variables: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xos_read_vdu_variables: 0x%x: %s",
+ error->errnum, error->errmess);
return false;
}
error = xwimp_read_palette((os_palette*)&vals[3]);
if (error) {
- LOG("xwimp_read_palette: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_read_palette: 0x%x: %s",
+ error->errnum, error->errmess);
return false;
}
@@ -393,7 +402,8 @@ bool artworks_redraw(struct content *c, struct content_redraw_data *data,
aw->render_workspace);
if (error) {
- LOG("awrender_render: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "awrender_render: 0x%x: %s",
+ error->errnum, error->errmess);
return false;
}
diff --git a/frontends/riscos/content-handlers/draw.c b/frontends/riscos/content-handlers/draw.c
index 0c84de866..bb66f9dbb 100644
--- a/frontends/riscos/content-handlers/draw.c
+++ b/frontends/riscos/content-handlers/draw.c
@@ -126,9 +126,10 @@ bool draw_convert(struct content *c)
error = xdrawfile_bbox(0, (drawfile_diagram *) data,
(int) source_size, 0, &bbox);
if (error) {
- LOG("xdrawfile_bbox: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xdrawfile_bbox: 0x%x: %s",
+ error->errnum, error->errmess);
msg_data.error = error->errmess;
- content_broadcast(c, CONTENT_MSG_ERROR, msg_data);
+ content_broadcast(c, CONTENT_MSG_ERROR, &msg_data);
return false;
}
@@ -208,7 +209,8 @@ bool draw_redraw(struct content *c, struct content_redraw_data *data,
error = xdrawfile_render(0, (drawfile_diagram *) src_data,
(int) source_size, &matrix, 0, 0);
if (error) {
- LOG("xdrawfile_render: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xdrawfile_render: 0x%x: %s",
+ error->errnum, error->errmess);
return false;
}
diff --git a/frontends/riscos/content-handlers/sprite.c b/frontends/riscos/content-handlers/sprite.c
index 02976e48e..3556aa555 100644
--- a/frontends/riscos/content-handlers/sprite.c
+++ b/frontends/riscos/content-handlers/sprite.c
@@ -126,7 +126,7 @@ bool sprite_convert(struct content *c)
/* check for bad data */
if ((int)source_size + 4 != area->used) {
msg_data.error = messages_get("BadSprite");
- content_broadcast(c, CONTENT_MSG_ERROR, msg_data);
+ content_broadcast(c, CONTENT_MSG_ERROR, &msg_data);
return false;
}
@@ -135,9 +135,12 @@ bool sprite_convert(struct content *c)
(osspriteop_id) ((char *) area + area->first),
&w, &h, NULL, NULL);
if (error) {
- LOG("xosspriteop_read_sprite_info: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO,
+ "xosspriteop_read_sprite_info: 0x%x: %s",
+ error->errnum,
+ error->errmess);
msg_data.error = error->errmess;
- content_broadcast(c, CONTENT_MSG_ERROR, msg_data);
+ content_broadcast(c, CONTENT_MSG_ERROR, &msg_data);
return false;
}
diff --git a/frontends/riscos/cookies.c b/frontends/riscos/cookies.c
index 614bc3d10..125d04356 100644
--- a/frontends/riscos/cookies.c
+++ b/frontends/riscos/cookies.c
@@ -445,12 +445,12 @@ nserror ro_gui_cookies_present(void)
res = ro_cookie_init();
if (res == NSERROR_OK) {
- LOG("Presenting");
+ NSLOG(netsurf, INFO, "Presenting");
ro_gui_dialog_open_top(cookie_window->core.wh,
cookie_window->core.toolbar,
600, 800);
} else {
- LOG("Failed presenting code %d", res);
+ NSLOG(netsurf, INFO, "Failed presenting code %d", res);
}
return res;
diff --git a/frontends/riscos/corewindow.c b/frontends/riscos/corewindow.c
index 77dd1c375..84177aa90 100644
--- a/frontends/riscos/corewindow.c
+++ b/frontends/riscos/corewindow.c
@@ -63,22 +63,22 @@ static void update_scrollbars(struct ro_corewindow *ro_cw, wimp_open *open)
int extent_height;
os_box extent;
- LOG("RO corewindow context %p", ro_cw);
+ NSLOG(netsurf, INFO, "RO corewindow context %p", ro_cw);
/* extent of content in not smaller than window so start there */
extent_width = open->visible.x1 - open->visible.x0;
extent_height = open->visible.y0 - open->visible.y1;
- LOG("extent w:%d h:%d content w:%d h:%d origin h:%d",
- extent_width, extent_height,
- ro_cw->content_width, ro_cw->content_height, ro_cw->origin_y);
+ NSLOG(netsurf, INFO,
+ "extent w:%d h:%d content w:%d h:%d origin h:%d", extent_width,
+ extent_height, ro_cw->content_width, ro_cw->content_height,
+ ro_cw->origin_y);
if (ro_cw->content_width > extent_width) {
extent_width = ro_cw->content_width;
}
if (extent_height > (ro_cw->origin_y + ro_cw->content_height)) {
extent_height = ro_cw->origin_y + ro_cw->content_height;
}
- LOG("extent w:%d h:%d",
- extent_width, extent_height);
+ NSLOG(netsurf, INFO, "extent w:%d h:%d", extent_width, extent_height);
extent.x0 = 0;
extent.y0 = extent_height;
extent.x1 = extent_width;
@@ -86,15 +86,15 @@ static void update_scrollbars(struct ro_corewindow *ro_cw, wimp_open *open)
error = xwimp_set_extent(ro_cw->wh, &extent);
if (error) {
- LOG("xwimp_set_extent: 0x%x: %s",
- error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_set_extent: 0x%x: %s",
+ error->errnum, error->errmess);
return;
}
error = xwimp_open_window(open);
if (error) {
- LOG("xwimp_open_window: 0x%x: %s",
- error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_open_window: 0x%x: %s",
+ error->errnum, error->errmess);
}
}
@@ -130,8 +130,8 @@ static void ro_cw_redraw(wimp_draw *redraw)
error = xwimp_get_rectangle(redraw, &more);
}
if (error != NULL) {
- LOG("xwimp_redraw_window: 0x%x: %s",
- error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_redraw_window: 0x%x: %s",
+ error->errnum, error->errmess);
}
}
@@ -145,7 +145,7 @@ static void ro_cw_scroll(wimp_scroll *scroll)
wimp_open open;
ro_cw = (struct ro_corewindow *)ro_gui_wimp_event_get_user_data(scroll->w);
- LOG("RO corewindow context %p", ro_cw);
+ NSLOG(netsurf, INFO, "RO corewindow context %p", ro_cw);
page_x = scroll->visible.x1 - scroll->visible.x0 - 32;
page_y = scroll->visible.y1 - scroll->visible.y0 - 32;
@@ -202,8 +202,8 @@ static void ro_cw_scroll(wimp_scroll *scroll)
error = xwimp_open_window(&open);
if (error) {
- LOG("xwimp_open_window: 0x%x: %s",
- error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_open_window: 0x%x: %s",
+ error->errnum, error->errmess);
}
}
@@ -231,18 +231,18 @@ static void ro_cw_mouse_at(wimp_pointer *pointer, void *data)
ro_cw = (struct ro_corewindow *)ro_gui_wimp_event_get_user_data(pointer->w);
if (ro_cw == NULL) {
- LOG("no corewindow conext for window: 0x%x",
- (unsigned int)pointer->w);
+ NSLOG(netsurf, INFO, "no corewindow conext for window: 0x%x",
+ (unsigned int)pointer->w);
return;
}
- LOG("RO corewindow context %p", ro_cw);
+ NSLOG(netsurf, INFO, "RO corewindow context %p", ro_cw);
/* Not a Menu click. */
state.w = pointer->w;
error = xwimp_get_window_state(&state);
if (error) {
- LOG("xwimp_get_window_state: 0x%x: %s",
- error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_get_window_state: 0x%x: %s",
+ error->errnum, error->errmess);
return;
}
@@ -285,14 +285,15 @@ static void ro_cw_drag_end(wimp_dragged *drag, void *data)
error = xwimp_drag_box((wimp_drag *) -1);
if (error) {
- LOG("xwimp_drag_box: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_drag_box: 0x%x: %s",
+ error->errnum, error->errmess);
ro_warn_user("WimpError", error->errmess);
}
error = xwimp_auto_scroll(0, NULL, NULL);
if (error) {
- LOG("xwimp_auto_scroll: 0x%x: %s",
- error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_auto_scroll: 0x%x: %s",
+ error->errnum, error->errmess);
ro_warn_user("WimpError", error->errmess);
}
}
@@ -345,12 +346,13 @@ ro_cw_drag_start(struct ro_corewindow *ro_cw,
break;
}
- LOG("Drag start...");
+ NSLOG(netsurf, INFO, "Drag start...");
error = xwimp_drag_box_with_flags(&drag,
wimp_DRAG_BOX_KEEP_IN_LINE | wimp_DRAG_BOX_CLIP);
if (error) {
- LOG("xwimp_drag_box: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_drag_box: 0x%x: %s",
+ error->errnum, error->errmess);
ro_warn_user("WimpError", error->errmess);
} else {
auto_scroll.w = ro_cw->wh;
@@ -364,7 +366,8 @@ ro_cw_drag_start(struct ro_corewindow *ro_cw,
error = xwimp_auto_scroll(wimp_AUTO_SCROLL_ENABLE_VERTICAL,
&auto_scroll, NULL);
if (error) {
- LOG("xwimp_auto_scroll: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_auto_scroll: 0x%x: %s",
+ error->errnum, error->errmess);
ro_warn_user("WimpError", error->errmess);
}
@@ -388,8 +391,8 @@ static void ro_cw_pointer_leaving(wimp_leaving *leaving, void *data)
ro_cw = (struct ro_corewindow *)ro_gui_wimp_event_get_user_data(leaving->w);
if (ro_cw == NULL) {
- LOG("no corewindow conext for window: 0x%x",
- (unsigned int)leaving->w);
+ NSLOG(netsurf, INFO, "no corewindow conext for window: 0x%x",
+ (unsigned int)leaving->w);
return;
}
@@ -439,14 +442,14 @@ static bool ro_cw_mouse_click(wimp_pointer *pointer)
struct ro_corewindow *ro_cw;
ro_cw = (struct ro_corewindow *)ro_gui_wimp_event_get_user_data(pointer->w);
- LOG("RO corewindow context %p", ro_cw);
+ NSLOG(netsurf, INFO, "RO corewindow context %p", ro_cw);
state.w = ro_cw->wh;
error = xwimp_get_window_state(&state);
if (error) {
- LOG("xwimp_get_window_state: 0x%x: %s",
- error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_get_window_state: 0x%x: %s",
+ error->errnum, error->errmess);
return false;
}
@@ -517,7 +520,7 @@ static bool ro_cw_keypress(wimp_key *key)
nserror res;
ro_cw = (struct ro_corewindow *)ro_gui_wimp_event_get_user_data(key->w);
- LOG("RO corewindow context %p", ro_cw);
+ NSLOG(netsurf, INFO, "RO corewindow context %p", ro_cw);
c = (uint32_t) key->c;
@@ -640,8 +643,8 @@ static void cw_tb_size(void *ctx)
state.w = ro_cw->wh;
error = xwimp_get_window_state(&state);
if (error) {
- LOG("xwimp_get_window_state: 0x%x: %s",
- error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_get_window_state: 0x%x: %s",
+ error->errnum, error->errmess);
return;
}
@@ -649,8 +652,8 @@ static void cw_tb_size(void *ctx)
0, state.visible.y0 - state.visible.y1,
state.visible.x1 - state.visible.x0, 0);
if (error) {
- LOG("xwimp_force_redraw: 0x%x: %s",
- error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_force_redraw: 0x%x: %s",
+ error->errnum, error->errmess);
return;
}
}
@@ -759,8 +762,10 @@ ro_cw_invalidate(struct core_window *cw, const struct rect *r)
info.w = ro_cw->wh;
error = xwimp_get_window_info_header_only(&info);
if (error) {
- LOG("xwimp_get_window_info_header_only: 0x%x: %s",
- error->errnum, error->errmess);
+ NSLOG(netsurf, INFO,
+ "xwimp_get_window_info_header_only: 0x%x: %s",
+ error->errnum,
+ error->errmess);
return NSERROR_INVALID;
}
} else {
@@ -775,8 +780,8 @@ ro_cw_invalidate(struct core_window *cw, const struct rect *r)
info.extent.x0, info.extent.y0,
info.extent.x1, info.extent.y1);
if (error) {
- LOG("xwimp_force_redraw: 0x%x: %s",
- error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_force_redraw: 0x%x: %s",
+ error->errnum, error->errmess);
return NSERROR_INVALID;
}
return NSERROR_OK;
@@ -794,8 +799,8 @@ ro_cw_update_size(struct core_window *cw, int width, int height)
wimp_window_state state;
os_error *error;
- LOG("content resize from w:%d h:%d to w:%d h:%d",
- ro_cw->content_width, ro_cw->content_height, width, height);
+ NSLOG(netsurf, INFO, "content resize from w:%d h:%d to w:%d h:%d",
+ ro_cw->content_width, ro_cw->content_height, width, height);
ro_cw->content_width = width * 2;
ro_cw->content_height = -(2 * height);
@@ -803,8 +808,8 @@ ro_cw_update_size(struct core_window *cw, int width, int height)
state.w = ro_cw->wh;
error = xwimp_get_window_state(&state);
if (error) {
- LOG("xwimp_get_window_state: 0x%x: %s",
- error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_get_window_state: 0x%x: %s",
+ error->errnum, error->errmess);
return;
}
@@ -848,8 +853,8 @@ ro_cw_get_window_dimensions(struct core_window *cw, int *width, int *height)
state.w = ro_cw->wh;
error = xwimp_get_window_state(&state);
if (error) {
- LOG("xwimp_get_window_state: 0x%x: %s",
- error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_get_window_state: 0x%x: %s",
+ error->errnum, error->errmess);
return;
}
diff --git a/frontends/riscos/dialog.c b/frontends/riscos/dialog.c
index 6414778db..a50d1289b 100644
--- a/frontends/riscos/dialog.c
+++ b/frontends/riscos/dialog.c
@@ -220,7 +220,8 @@ wimp_w ro_gui_dialog_create(const char *template_name)
window->sprite_area = gui_sprites;
error = xwimp_create_window(window, &w);
if (error) {
- LOG("xwimp_create_window: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_create_window: 0x%x: %s",
+ error->errnum, error->errmess);
xwimp_close_template();
die(error->errmess);
}
@@ -259,12 +260,13 @@ wimp_window * ro_gui_dialog_load_template(const char *template_name)
error = xwimp_load_template(wimp_GET_SIZE, 0, 0, wimp_NO_FONTS,
name, 0, &window_size, &data_size, &context);
if (error) {
- LOG("xwimp_load_template: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_load_template: 0x%x: %s",
+ error->errnum, error->errmess);
xwimp_close_template();
die(error->errmess);
}
if (!context) {
- LOG("template '%s' missing", template_name);
+ NSLOG(netsurf, INFO, "template '%s' missing", template_name);
xwimp_close_template();
die("Template");
}
@@ -281,7 +283,8 @@ wimp_window * ro_gui_dialog_load_template(const char *template_name)
error = xwimp_load_template(window, data, data + data_size,
wimp_NO_FONTS, name, 0, 0, 0, 0);
if (error) {
- LOG("xwimp_load_template: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_load_template: 0x%x: %s",
+ error->errnum, error->errmess);
xwimp_close_template();
die(error->errmess);
}
@@ -309,7 +312,8 @@ void ro_gui_dialog_open(wimp_w w)
state.w = w;
error = xwimp_get_window_state(&state);
if (error) {
- LOG("xwimp_get_window_state: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_get_window_state: 0x%x: %s",
+ error->errnum, error->errmess);
ro_warn_user("WimpError", error->errmess);
return;
}
@@ -356,7 +360,8 @@ void ro_gui_dialog_close(wimp_w close)
*/
error = xwimp_get_caret_position(&caret);
if (error) {
- LOG("xwimp_get_caret_position: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_get_caret_position: 0x%x: %s",
+ error->errnum, error->errmess);
ro_warn_user("WimpError", error->errmess);
} else if (caret.w == close) {
/* Check if we are a persistent window */
@@ -367,7 +372,10 @@ void ro_gui_dialog_close(wimp_w close)
32, -1);
/* parent may have been closed first */
if ((error) && (error->errnum != 0x287)) {
- LOG("xwimp_set_caret_position: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO,
+ "xwimp_set_caret_position: 0x%x: %s",
+ error->errnum,
+ error->errmess);
ro_warn_user("WimpError", error->errmess);
}
}
@@ -375,7 +383,8 @@ void ro_gui_dialog_close(wimp_w close)
error = xwimp_close_window(close);
if (error) {
- LOG("xwimp_close_window: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_close_window: 0x%x: %s",
+ error->errnum, error->errmess);
ro_warn_user("WimpError", error->errmess);
}
}
@@ -460,7 +469,8 @@ void ro_gui_dialog_open_at_pointer(wimp_w w)
/* get the pointer position */
error = xwimp_get_pointer_info(&ptr);
if (error) {
- LOG("xwimp_get_pointer_info: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_get_pointer_info: 0x%x: %s",
+ error->errnum, error->errmess);
ro_warn_user("WimpError", error->errmess);
return;
}
@@ -483,7 +493,8 @@ void ro_gui_dialog_open_xy(wimp_w w, int x, int y)
state.w = w;
error = xwimp_get_window_state(&state);
if (error) {
- LOG("xwimp_get_window_state: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_get_window_state: 0x%x: %s",
+ error->errnum, error->errmess);
ro_warn_user("WimpError", error->errmess);
return;
}
@@ -498,7 +509,8 @@ void ro_gui_dialog_open_xy(wimp_w w, int x, int y)
* on screen */
error = xwimp_close_window(w);
if (error) {
- LOG("xwimp_close_window: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_close_window: 0x%x: %s",
+ error->errnum, error->errmess);
ro_warn_user("WimpError", error->errmess);
return;
}
@@ -527,7 +539,10 @@ static void ro_gui_dialog_open_centre_parent(wimp_w parent, wimp_w child)
state.w = parent;
error = xwimp_get_window_state(&state);
if (error) {
- LOG("xwimp_get_window_state: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO,
+ "xwimp_get_window_state: 0x%x: %s",
+ error->errnum,
+ error->errmess);
ro_warn_user("WimpError", error->errmess);
return;
}
@@ -544,7 +559,8 @@ static void ro_gui_dialog_open_centre_parent(wimp_w parent, wimp_w child)
state.w = child;
error = xwimp_get_window_state(&state);
if (error) {
- LOG("xwimp_get_window_state: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_get_window_state: 0x%x: %s",
+ error->errnum, error->errmess);
ro_warn_user("WimpError", error->errmess);
return;
}
@@ -607,7 +623,7 @@ void ro_gui_dialog_add_persistent(wimp_w parent, wimp_w w) {
return;
}
}
- LOG("Unable to map persistent dialog to parent.");
+ NSLOG(netsurf, INFO, "Unable to map persistent dialog to parent.");
return;
}
@@ -636,7 +652,9 @@ void ro_gui_dialog_close_persistent(wimp_w parent) {
w = persistent_dialog[i].dialog;
ro_gui_dialog_close(w);
if (ro_gui_wimp_event_close_window(w))
- LOG("Persistent dialog close event: 0x%x", (unsigned)w);
+ NSLOG(netsurf, INFO,
+ "Persistent dialog close event: 0x%x",
+ (unsigned)w);
persistent_dialog[i].parent = NULL;
persistent_dialog[i].dialog = NULL;
}
@@ -713,7 +731,7 @@ static bool ro_gui_dialog_open_url_init(void)
if ((definition->icons[ICON_OPENURL_URL].flags & wimp_ICON_INDIRECTED)
== 0) {
- LOG("open_url URL icon not indirected");
+ NSLOG(netsurf, INFO, "open_url URL icon not indirected");
xwimp_close_template();
die("Template");
}
@@ -731,7 +749,8 @@ static bool ro_gui_dialog_open_url_init(void)
error = xwimp_create_window(definition, &dialog_openurl);
if (error != NULL) {
- LOG("xwimp_create_window: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_create_window: 0x%x: %s",
+ error->errnum, error->errmess);
xwimp_close_template();
die(error->errmess);
}
diff --git a/frontends/riscos/download.c b/frontends/riscos/download.c
index 561409ed1..bdc705426 100644
--- a/frontends/riscos/download.c
+++ b/frontends/riscos/download.c
@@ -261,7 +261,10 @@ static nserror download_ro_filetype(download_context *ctx, bits *ftype_out)
mime_type = download_context_get_mime_type(ctx);
error = xmimemaptranslate_mime_type_to_filetype(mime_type, &ftype);
if (error) {
- LOG("xmimemaptranslate_mime_type_to_filetype: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO,
+ "xmimemaptranslate_mime_type_to_filetype: 0x%x: %s",
+ error->errnum,
+ error->errmess);
ro_warn_user("MiscError", error->errmess);
ftype = 0xffd;
}
@@ -339,7 +342,8 @@ gui_download_window_create(download_context *ctx, struct gui_window *gui)
error = xosfind_openoutw(osfind_NO_PATH | osfind_ERROR_IF_DIR,
temp_name, 0, &dw->file);
if (error) {
- LOG("xosfind_openoutw: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xosfind_openoutw: 0x%x: %s",
+ error->errnum, error->errmess);
ro_warn_user("SaveError", error->errmess);
free(dw);
return 0;
@@ -372,7 +376,7 @@ gui_download_window_create(download_context *ctx, struct gui_window *gui)
filename = strdup(temp_name);
if (filename == NULL) {
- LOG("Failed to establish download filename.");
+ NSLOG(netsurf, INFO, "Failed to establish download filename.");
ro_warn_user("SaveError", error->errmess);
free(dw);
return 0;
@@ -404,7 +408,7 @@ gui_download_window_create(download_context *ctx, struct gui_window *gui)
if (err != NSERROR_OK) {
/* badenc should never happen */
assert(err !=NSERROR_BAD_ENCODING);
- LOG("utf8_to_local_encoding failed");
+ NSLOG(netsurf, INFO, "utf8_to_local_encoding failed");
ro_warn_user("NoMemory", 0);
free(dw);
return 0;
@@ -430,7 +434,8 @@ gui_download_window_create(download_context *ctx, struct gui_window *gui)
/* create and open the download window */
error = xwimp_create_window(download_template, &dw->window);
if (error) {
- LOG("xwimp_create_window: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_create_window: 0x%x: %s",
+ error->errnum, error->errmess);
ro_warn_user("WimpError", error->errmess);
free(dw);
return 0;
@@ -485,7 +490,8 @@ static void gui_download_window_error(struct gui_download_window *dw,
wimp_COLOUR_RED << wimp_ICON_FG_COLOUR_SHIFT,
wimp_ICON_FG_COLOUR);
if (error) {
- LOG("xwimp_set_icon_state: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_set_icon_state: 0x%x: %s",
+ error->errnum, error->errmess);
ro_warn_user("WimpError", error->errmess);
}
@@ -493,7 +499,8 @@ static void gui_download_window_error(struct gui_download_window *dw,
error = xwimp_set_icon_state(dw->window, ICON_DOWNLOAD_PATH,
wimp_ICON_SHADED, 0);
if (error) {
- LOG("xwimp_set_icon_state: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_set_icon_state: 0x%x: %s",
+ error->errnum, error->errmess);
ro_warn_user("WimpError", error->errmess);
}
@@ -501,7 +508,8 @@ static void gui_download_window_error(struct gui_download_window *dw,
error = xwimp_set_icon_state(dw->window, ICON_DOWNLOAD_ICON,
wimp_ICON_SHADED, wimp_ICON_SHADED);
if (error) {
- LOG("xwimp_set_icon_state: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_set_icon_state: 0x%x: %s",
+ error->errnum, error->errmess);
ro_warn_user("WimpError", error->errmess);
}
@@ -528,11 +536,13 @@ static nserror gui_download_window_data(struct gui_download_window *dw,
error = xosgbpb_writew(dw->file, (const byte *) data, size,
&unwritten);
if (error) {
- LOG("xosgbpb_writew: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xosgbpb_writew: 0x%x: %s",
+ error->errnum, error->errmess);
msg = error->errmess;
} else if (unwritten) {
- LOG("xosgbpb_writew: unwritten %i", unwritten);
+ NSLOG(netsurf, INFO, "xosgbpb_writew: unwritten %i",
+ unwritten);
msg = messages_get("Unwritten");
}
else {
@@ -555,20 +565,29 @@ static nserror gui_download_window_data(struct gui_download_window *dw,
error = xwimp_set_icon_state(dw->window, ICON_DOWNLOAD_ICON,
wimp_ICON_SHADED, 0);
if (error) {
- LOG("xwimp_set_icon_state: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO,
+ "xwimp_set_icon_state: 0x%x: %s",
+ error->errnum,
+ error->errmess);
ro_warn_user("WimpError", error->errmess);
}
error = xwimp_set_icon_state(dw->window, ICON_DOWNLOAD_DESTINATION,
wimp_ICON_DELETED, wimp_ICON_DELETED);
if (error) {
- LOG("xwimp_set_icon_state: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO,
+ "xwimp_set_icon_state: 0x%x: %s",
+ error->errnum,
+ error->errmess);
ro_warn_user("WimpError", error->errmess);
}
error = xwimp_set_icon_state(dw->window,
ICON_DOWNLOAD_PATH, wimp_ICON_DELETED, 0);
if (error) {
- LOG("xwimp_set_icon_state: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO,
+ "xwimp_set_icon_state: 0x%x: %s",
+ error->errnum,
+ error->errmess);
ro_warn_user("WimpError", error->errmess);
}
@@ -717,13 +736,15 @@ void ro_gui_download_update_status(struct gui_download_window *dw)
download_progress_x0 + width,
download_progress_y1);
if (error) {
- LOG("xwimp_resize_icon: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_resize_icon: 0x%x: %s",
+ error->errnum, error->errmess);
ro_warn_user("WimpError", error->errmess);
}
error = xwimp_set_icon_state(dw->window, ICON_DOWNLOAD_STATUS, 0, 0);
if (error) {
- LOG("xwimp_set_icon_state: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_set_icon_state: 0x%x: %s",
+ error->errnum, error->errmess);
ro_warn_user("WimpError", error->errmess);
}
@@ -759,13 +780,17 @@ void ro_gui_download_window_hide_caret(struct gui_download_window *dw)
error = xwimp_get_caret_position(&caret);
if (error) {
- LOG("xwimp_get_caret_position: 0x%x : %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_get_caret_position: 0x%x : %s",
+ error->errnum, error->errmess);
ro_warn_user("WimpError", error->errmess);
}
else if (caret.w == dw->window) {
error = xwimp_set_caret_position(dw->window, (wimp_i)-1, 0, 0, 1 << 25, -1);
if (error) {
- LOG("xwimp_get_caret_position: 0x%x : %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO,
+ "xwimp_get_caret_position: 0x%x : %s",
+ error->errnum,
+ error->errmess);
ro_warn_user("WimpError", error->errmess);
}
}
@@ -791,7 +816,8 @@ static void gui_download_window_done(struct gui_download_window *dw)
error = xosfind_closew(dw->file);
if (error) {
- LOG("xosfind_closew: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xosfind_closew: 0x%x: %s",
+ error->errnum, error->errmess);
ro_warn_user("SaveError", error->errmess);
}
dw->file = 0;
@@ -800,7 +826,8 @@ static void gui_download_window_done(struct gui_download_window *dw)
error = xosfile_set_type(dw->path,
dw->file_type);
if (error) {
- LOG("xosfile_set_type: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xosfile_set_type: 0x%x: %s",
+ error->errnum, error->errmess);
ro_warn_user("SaveError", error->errmess);
}
@@ -856,7 +883,8 @@ bool ro_gui_download_click(wimp_pointer *pointer)
*dot = 0;
error = xos_cli(command);
if (error) {
- LOG("xos_cli: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xos_cli: 0x%x: %s",
+ error->errnum, error->errmess);
ro_warn_user("MiscError", error->errmess);
}
}
@@ -929,7 +957,8 @@ static void ro_gui_download_drag_end(wimp_dragged *drag, void *data)
error = xwimp_get_pointer_info(&pointer);
if (error) {
- LOG("xwimp_get_pointer_info: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_get_pointer_info: 0x%x: %s",
+ error->errnum, error->errmess);
ro_warn_user("WimpError", error->errmess);
return;
}
@@ -959,7 +988,10 @@ static void ro_gui_download_drag_end(wimp_dragged *drag, void *data)
error = xwimp_send_message_to_window(wimp_USER_MESSAGE, &message,
pointer.w, pointer.i, 0);
if (error) {
- LOG("xwimp_send_message_to_window: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO,
+ "xwimp_send_message_to_window: 0x%x: %s",
+ error->errnum,
+ error->errmess);
ro_warn_user("WimpError", error->errmess);
}
@@ -1011,7 +1043,10 @@ char *ro_gui_download_canonicalise(const char *path)
error = xosfscontrol_canonicalise_path(path, NULL, NULL, NULL, 0, &spare);
if (error) {
- LOG("xosfscontrol_canonicalise_path: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO,
+ "xosfscontrol_canonicalise_path: 0x%x: %s",
+ error->errnum,
+ error->errmess);
return NULL;
}
@@ -1020,7 +1055,10 @@ char *ro_gui_download_canonicalise(const char *path)
error = xosfscontrol_canonicalise_path(path, buf, NULL, NULL,
1 - spare, NULL);
if (error) {
- LOG("xosfscontrol_canonicalise_path: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO,
+ "xosfscontrol_canonicalise_path: 0x%x: %s",
+ error->errnum,
+ error->errmess);
free(buf);
return NULL;
@@ -1065,13 +1103,17 @@ bool ro_gui_download_check_space(struct gui_download_window *dw,
error = xosfscontrol_free_space64(dir, &free_lo, &free_hi,
&max_file, NULL, NULL);
if (error) {
- LOG("xosfscontrol_free_space64: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xosfscontrol_free_space64: 0x%x: %s",
+ error->errnum, error->errmess);
free_hi = 0;
error = xosfscontrol_free_space(dir, (int*)&free_lo,
&max_file, NULL);
if (error) {
- LOG("xosfscontrol_free_space: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO,
+ "xosfscontrol_free_space: 0x%x: %s",
+ error->errnum,
+ error->errmess);
/* close our eyes and hope */
free(dir);
return true;
@@ -1108,7 +1150,10 @@ bool ro_gui_download_check_space(struct gui_download_window *dw,
error = xosargs_read_allocation(dw->file,
&allocation);
if (error) {
- LOG("xosargs_read_allocation: 0x%x : %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO,
+ "xosargs_read_allocation: 0x%x : %s",
+ error->errnum,
+ error->errmess);
}
else {
space += allocation;
@@ -1147,7 +1192,8 @@ os_error *ro_gui_download_move(struct gui_download_window *dw,
error = xosfind_closew(dw->file);
dw->file = 0;
if (error) {
- LOG("xosfind_closew: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xosfind_closew: 0x%x: %s",
+ error->errnum, error->errmess);
return error;
}
}
@@ -1165,11 +1211,13 @@ os_error *ro_gui_download_move(struct gui_download_window *dw,
osfscontrol_COPY_LOOK,
0, 0, 0, 0, 0);
if (error) {
- LOG("xosfscontrol_copy: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xosfscontrol_copy: 0x%x: %s",
+ error->errnum, error->errmess);
return error;
}
} else if (error) {
- LOG("xosfscontrol_rename: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xosfscontrol_rename: 0x%x: %s",
+ error->errnum, error->errmess);
return error;
}
@@ -1179,20 +1227,23 @@ os_error *ro_gui_download_move(struct gui_download_window *dw,
fileswitch_ATTR_OWNER_READ |
fileswitch_ATTR_OWNER_WRITE);
if (error) {
- LOG("xosfile_write: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xosfile_write: 0x%x: %s",
+ error->errnum, error->errmess);
ro_warn_user("SaveError", error->errmess);
}
error = xosfind_openupw(osfind_NO_PATH | osfind_ERROR_IF_DIR,
dest_file, 0, &dw->file);
if (error) {
- LOG("xosfind_openupw: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xosfind_openupw: 0x%x: %s",
+ error->errnum, error->errmess);
return error;
}
error = xosargs_set_ptrw(dw->file, dw->received);
if (error) {
- LOG("xosargs_set_ptrw: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xosargs_set_ptrw: 0x%x: %s",
+ error->errnum, error->errmess);
return error;
}
@@ -1201,7 +1252,8 @@ os_error *ro_gui_download_move(struct gui_download_window *dw,
error = xosfile_set_type(dest_file,
dw->file_type);
if (error) {
- LOG("xosfile_set_type: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xosfile_set_type: 0x%x: %s",
+ error->errnum, error->errmess);
ro_warn_user("SaveError", error->errmess);
}
}
@@ -1273,7 +1325,8 @@ bool ro_gui_download_save(struct gui_download_window *dw,
error = xosfile_read_stamped(file_name, &obj_type,
NULL, NULL, NULL, NULL, NULL);
if (error) {
- LOG("xosfile_read_stamped: 0x%x:%s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xosfile_read_stamped: 0x%x:%s",
+ error->errnum, error->errmess);
return false;
}
@@ -1309,12 +1362,16 @@ bool ro_gui_download_save(struct gui_download_window *dw,
error = xosfind_openupw(osfind_NO_PATH | osfind_ERROR_IF_DIR,
temp_name, 0, &dw->file);
if (error) {
- LOG("xosfind_openupw: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xosfind_openupw: 0x%x: %s",
+ error->errnum, error->errmess);
} else {
error = xosargs_set_ptrw(dw->file, dw->received);
if (error) {
- LOG("xosargs_set_ptrw: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO,
+ "xosargs_set_ptrw: 0x%x: %s",
+ error->errnum,
+ error->errmess);
}
}
@@ -1336,7 +1393,8 @@ bool ro_gui_download_save(struct gui_download_window *dw,
error = xwimp_set_icon_state(dw->window, ICON_DOWNLOAD_ICON,
wimp_ICON_SHADED, wimp_ICON_SHADED);
if (error) {
- LOG("xwimp_set_icon_state: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_set_icon_state: 0x%x: %s",
+ error->errnum, error->errmess);
ro_warn_user("WimpError", error->errmess);
}
@@ -1349,13 +1407,15 @@ bool ro_gui_download_save(struct gui_download_window *dw,
error = xwimp_set_icon_state(dw->window, ICON_DOWNLOAD_PATH,
wimp_ICON_DELETED, wimp_ICON_DELETED);
if (error) {
- LOG("xwimp_set_icon_state: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_set_icon_state: 0x%x: %s",
+ error->errnum, error->errmess);
ro_warn_user("WimpError", error->errmess);
}
error = xwimp_set_icon_state(dw->window,
ICON_DOWNLOAD_DESTINATION, wimp_ICON_DELETED, 0);
if (error) {
- LOG("xwimp_set_icon_state: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_set_icon_state: 0x%x: %s",
+ error->errnum, error->errmess);
ro_warn_user("WimpError", error->errmess);
}
@@ -1401,7 +1461,8 @@ void ro_gui_download_send_dataload(struct gui_download_window *dw)
* for the rather depressing details.
*/
if (error && error->errnum != error_WIMP_BAD_HANDLE) {
- LOG("xwimp_set_icon_state: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_set_icon_state: 0x%x: %s",
+ error->errnum, error->errmess);
ro_warn_user("WimpError", error->errmess);
}
@@ -1482,7 +1543,8 @@ bool ro_gui_download_window_destroy(struct gui_download_window *dw, bool quit)
/* delete window */
error = xwimp_delete_window(dw->window);
if (error) {
- LOG("xwimp_delete_window: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_delete_window: 0x%x: %s",
+ error->errnum, error->errmess);
ro_warn_user("WimpError", error->errmess);
}
ro_gui_wimp_event_finalise(dw->window);
@@ -1491,7 +1553,8 @@ bool ro_gui_download_window_destroy(struct gui_download_window *dw, bool quit)
if (dw->file) {
error = xosfind_closew(dw->file);
if (error) {
- LOG("xosfind_closew: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xosfind_closew: 0x%x: %s",
+ error->errnum, error->errmess);
ro_warn_user("SaveError", error->errmess);
}
}
@@ -1502,7 +1565,8 @@ bool ro_gui_download_window_destroy(struct gui_download_window *dw, bool quit)
error = xosfile_delete(temp_name, 0, 0, 0, 0, 0);
if (error) {
- LOG("xosfile_delete: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xosfile_delete: 0x%x: %s",
+ error->errnum, error->errmess);
ro_warn_user("SaveError", error->errmess);
}
}
diff --git a/frontends/riscos/filetype.c b/frontends/riscos/filetype.c
index 75ff41414..73651cd63 100644
--- a/frontends/riscos/filetype.c
+++ b/frontends/riscos/filetype.c
@@ -72,7 +72,7 @@ const char *fetch_filetype(const char *unix_path)
int objtype;
if (!path) {
- LOG("Insufficient memory for calloc");
+ NSLOG(netsurf, INFO, "Insufficient memory for calloc");
ro_warn_user("NoMemory", 0);
return "application/riscos";
}
@@ -80,7 +80,7 @@ const char *fetch_filetype(const char *unix_path)
/* convert path to RISC OS format and read file type */
r = __riscosify(unix_path, 0, __RISCOSIFY_NO_SUFFIX, path, len, 0);
if (r == 0) {
- LOG("__riscosify failed");
+ NSLOG(netsurf, INFO, "__riscosify failed");
free(path);
return "application/riscos";
}
@@ -88,7 +88,9 @@ const char *fetch_filetype(const char *unix_path)
error = xosfile_read_stamped_no_path(path, &objtype, 0, 0, 0, 0,
&file_type);
if (error) {
- LOG("xosfile_read_stamped_no_path failed: %s", error->errmess);
+ NSLOG(netsurf, INFO,
+ "xosfile_read_stamped_no_path failed: %s",
+ error->errmess);
free(path);
return "application/riscos";
}
@@ -108,7 +110,10 @@ const char *fetch_filetype(const char *unix_path)
slash+1, &temp);
if (error)
/* ignore error and leave file_type alone */
- LOG("xmimemaptranslate_extension_to_filetype: ""0x%x %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO,
+ "xmimemaptranslate_extension_to_filetype: ""0x%x %s",
+ error->errnum,
+ error->errmess);
else
file_type = temp;
}
@@ -126,7 +131,7 @@ const char *fetch_filetype(const char *unix_path)
/* not in internal table, so ask MimeMap */
error = xmimemaptranslate_filetype_to_mime_type(file_type, type_buf);
if (error) {
- LOG("0x%x %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "0x%x %s", error->errnum, error->errmess);
free(path);
return "application/riscos";
}
@@ -139,7 +144,7 @@ const char *fetch_filetype(const char *unix_path)
free(path);
- LOG("mime type '%s'", type_buf);
+ NSLOG(netsurf, INFO, "mime type '%s'", type_buf);
return (const char *)type_buf;
}
@@ -155,14 +160,15 @@ char *fetch_mimetype(const char *ro_path)
struct type_entry *t;
if (!mime) {
- LOG("Insufficient memory for calloc");
+ NSLOG(netsurf, INFO, "Insufficient memory for calloc");
ro_warn_user("NoMemory", 0);
return 0;
}
e = xosfile_read_no_path(ro_path, &objtype, &load, 0, 0, 0);
if (e) {
- LOG("xosfile_read_no_path: 0x%x: %s", e->errnum, e->errmess);
+ NSLOG(netsurf, INFO, "xosfile_read_no_path: 0x%x: %s",
+ e->errnum, e->errmess);
free(mime);
return 0;
}
@@ -188,7 +194,7 @@ char *fetch_mimetype(const char *ro_path)
if (e)
/* if we get an error here, simply ignore it and
* leave filetype unchanged */
- LOG("0x%x %s", e->errnum, e->errmess);
+ NSLOG(netsurf, INFO, "0x%x %s", e->errnum, e->errmess);
else
filetype = load;
}
@@ -205,7 +211,10 @@ char *fetch_mimetype(const char *ro_path)
/* not in internal table, so ask MimeMap */
e = xmimemaptranslate_filetype_to_mime_type(filetype, mime);
if (e) {
- LOG("xmimemaptranslate_filetype_to_mime_type: 0x%x: %s", e->errnum, e->errmess);
+ NSLOG(netsurf, INFO,
+ "xmimemaptranslate_filetype_to_mime_type: 0x%x: %s",
+ e->errnum,
+ e->errmess);
free(mime);
return 0;
}
@@ -322,7 +331,7 @@ bits ro_filetype_from_unix_path(const char *unix_path)
bits file_type;
if (!path) {
- LOG("Insufficient memory for calloc");
+ NSLOG(netsurf, INFO, "Insufficient memory for calloc");
ro_warn_user("NoMemory", 0);
return osfile_TYPE_DATA;
}
@@ -330,7 +339,7 @@ bits ro_filetype_from_unix_path(const char *unix_path)
/* convert path to RISC OS format and read file type */
r = __riscosify(unix_path, 0, __RISCOSIFY_NO_SUFFIX, path, len, 0);
if (r == 0) {
- LOG("__riscosify failed");
+ NSLOG(netsurf, INFO, "__riscosify failed");
free(path);
return osfile_TYPE_DATA;
}
@@ -338,7 +347,9 @@ bits ro_filetype_from_unix_path(const char *unix_path)
error = xosfile_read_stamped_no_path(path, 0, 0, 0, 0, 0,
&file_type);
if (error) {
- LOG("xosfile_read_stamped_no_path failed: %s", error->errmess);
+ NSLOG(netsurf, INFO,
+ "xosfile_read_stamped_no_path failed: %s",
+ error->errmess);
free(path);
return osfile_TYPE_DATA;
}
diff --git a/frontends/riscos/font.c b/frontends/riscos/font.c
index 560afc785..8913efeeb 100644
--- a/frontends/riscos/font.c
+++ b/frontends/riscos/font.c
@@ -65,7 +65,8 @@ static void nsfont_check_fonts(void)
"<NetSurf$Dir>.FixFonts", 0);
die("FontBadInst");
} else {
- LOG("xfont_find_font: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xfont_find_font: 0x%x: %s",
+ error->errnum, error->errmess);
snprintf(s, sizeof s, messages_get("FontError"),
error->errmess);
die(s);
@@ -74,7 +75,8 @@ static void nsfont_check_fonts(void)
error = xfont_lose_font(font);
if (error) {
- LOG("xfont_lose_font: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xfont_lose_font: 0x%x: %s",
+ error->errnum, error->errmess);
snprintf(s, sizeof s, messages_get("FontError"),
error->errmess);
die(s);
@@ -118,17 +120,20 @@ void nsfont_init(void)
nsfont_check_fonts();
- LOG("Initialise RUfl");
+ NSLOG(netsurf, INFO, "Initialise RUfl");
code = rufl_init();
if (code != rufl_OK) {
if (code == rufl_FONT_MANAGER_ERROR)
- LOG("rufl_init: rufl_FONT_MANAGER_ERROR: 0x%x: %s", rufl_fm_error->errnum, rufl_fm_error->errmess);
+ NSLOG(netsurf, INFO,
+ "rufl_init: rufl_FONT_MANAGER_ERROR: 0x%x: %s",
+ rufl_fm_error->errnum,
+ rufl_fm_error->errmess);
else
- LOG("rufl_init: 0x%x", code);
+ NSLOG(netsurf, INFO, "rufl_init: 0x%x", code);
die("The Unicode font library could not be initialized. "
"Please report this to the developers.");
}
- LOG("RUfl initialised");
+ NSLOG(netsurf, INFO, "RUfl initialised");
if (rufl_family_list_entries == 0)
die("No fonts could be found. At least one font must be "
@@ -162,9 +167,10 @@ const char *nsfont_fallback_font(void)
const char *fallback = "Homerton";
if (!nsfont_exists(fallback)) {
- LOG("Homerton not found, dumping RUfl family list");
+ NSLOG(netsurf, INFO,
+ "Homerton not found, dumping RUfl family list");
for (unsigned int i = 0; i < rufl_family_list_entries; i++) {
- LOG("'%s'", rufl_family_list[i]);
+ NSLOG(netsurf, INFO, "'%s'", rufl_family_list[i]);
}
fallback = rufl_family_list[0];
}
@@ -230,9 +236,12 @@ ro_font_width(const plot_font_style_t *fstyle,
width);
if (code != rufl_OK) {
if (code == rufl_FONT_MANAGER_ERROR)
- LOG("rufl_width: rufl_FONT_MANAGER_ERROR: 0x%x: %s", rufl_fm_error->errnum, rufl_fm_error->errmess);
+ NSLOG(netsurf, INFO,
+ "rufl_width: rufl_FONT_MANAGER_ERROR: 0x%x: %s",
+ rufl_fm_error->errnum,
+ rufl_fm_error->errmess);
else
- LOG("rufl_width: 0x%x", code);
+ NSLOG(netsurf, INFO, "rufl_width: 0x%x", code);
/* ro_warn_user("MiscError", "font error"); */
*width = 0;
return NSERROR_INVALID;
@@ -276,9 +285,12 @@ ro_font_position(const plot_font_style_t *fstyle,
x * 2, char_offset, actual_x);
if (code != rufl_OK) {
if (code == rufl_FONT_MANAGER_ERROR)
- LOG("rufl_x_to_offset: rufl_FONT_MANAGER_ERROR: ""0x%x: %s", rufl_fm_error->errnum, rufl_fm_error->errmess);
+ NSLOG(netsurf, INFO,
+ "rufl_x_to_offset: rufl_FONT_MANAGER_ERROR: ""0x%x: %s",
+ rufl_fm_error->errnum,
+ rufl_fm_error->errmess);
else
- LOG("rufl_x_to_offset: 0x%x", code);
+ NSLOG(netsurf, INFO, "rufl_x_to_offset: 0x%x", code);
/* ro_warn_user("MiscError", "font error"); */
*char_offset = 0;
*actual_x = 0;
@@ -335,10 +347,12 @@ ro_font_split(const plot_font_style_t *fstyle,
x * 2, char_offset, actual_x);
if (code != rufl_OK) {
if (code == rufl_FONT_MANAGER_ERROR) {
- LOG("rufl_split: rufl_FONT_MANAGER_ERROR: ""0x%x: %s",
- rufl_fm_error->errnum, rufl_fm_error->errmess);
+ NSLOG(netsurf, INFO,
+ "rufl_split: rufl_FONT_MANAGER_ERROR: ""0x%x: %s",
+ rufl_fm_error->errnum,
+ rufl_fm_error->errmess);
} else {
- LOG("rufl_split: 0x%x", code);
+ NSLOG(netsurf, INFO, "rufl_split: 0x%x", code);
}
/* ro_warn_user("MiscError", "font error"); */
*char_offset = 0;
@@ -370,10 +384,12 @@ ro_font_split(const plot_font_style_t *fstyle,
actual_x);
if (code != rufl_OK) {
if (code == rufl_FONT_MANAGER_ERROR) {
- LOG("rufl_width: rufl_FONT_MANAGER_ERROR: 0x%x: %s",
- rufl_fm_error->errnum, rufl_fm_error->errmess);
+ NSLOG(netsurf, INFO,
+ "rufl_width: rufl_FONT_MANAGER_ERROR: 0x%x: %s",
+ rufl_fm_error->errnum,
+ rufl_fm_error->errmess);
} else {
- LOG("rufl_width: 0x%x", code);
+ NSLOG(netsurf, INFO, "rufl_width: 0x%x", code);
}
/* ro_warn_user("MiscError", "font error"); */
*char_offset = 0;
@@ -416,9 +432,12 @@ bool nsfont_paint(const plot_font_style_t *fstyle, const char *string,
string, length, x, y, flags);
if (code != rufl_OK) {
if (code == rufl_FONT_MANAGER_ERROR) {
- LOG("rufl_paint: rufl_FONT_MANAGER_ERROR: 0x%x: %s", rufl_fm_error->errnum, rufl_fm_error->errmess);
+ NSLOG(netsurf, INFO,
+ "rufl_paint: rufl_FONT_MANAGER_ERROR: 0x%x: %s",
+ rufl_fm_error->errnum,
+ rufl_fm_error->errmess);
} else {
- LOG("rufl_paint: 0x%x", code);
+ NSLOG(netsurf, INFO, "rufl_paint: 0x%x", code);
}
}
@@ -513,7 +532,8 @@ ro_gui_wimp_desktop_font(char *family,
error = xwimpreadsysinfo_font(&font_handle, NULL);
if (error) {
- LOG("xwimpreadsysinfo_font: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimpreadsysinfo_font: 0x%x: %s",
+ error->errnum, error->errmess);
ro_warn_user("WimpError", error->errmess);
goto failsafe;
}
@@ -525,20 +545,22 @@ ro_gui_wimp_desktop_font(char *family,
error = xfont_read_identifier(font_handle, NULL, &used);
if (error) {
- LOG("xfont_read_identifier: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xfont_read_identifier: 0x%x: %s",
+ error->errnum, error->errmess);
ro_warn_user("MiscError", error->errmess);
goto failsafe;
}
if (family_size < (size_t) used + 1) {
- LOG("desktop font name too long");
+ NSLOG(netsurf, INFO, "desktop font name too long");
goto failsafe;
}
error = xfont_read_defn(font_handle, (byte *) family,
&ptx, &pty, NULL, NULL, NULL, NULL);
if (error) {
- LOG("xfont_read_defn: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xfont_read_defn: 0x%x: %s",
+ error->errnum, error->errmess);
ro_warn_user("MiscError", error->errmess);
goto failsafe;
}
@@ -550,7 +572,7 @@ ro_gui_wimp_desktop_font(char *family,
}
}
- LOG("desktop font \"%s\"", family);
+ NSLOG(netsurf, INFO, "desktop font \"%s\"", family);
if (strcasestr(family, ".Medium"))
style = rufl_WEIGHT_500;
@@ -566,7 +588,8 @@ ro_gui_wimp_desktop_font(char *family,
*psize = max(ptx, pty);
*pstyle = style;
- LOG("family \"%s\", size %i, style %i", family, *psize, style);
+ NSLOG(netsurf, INFO, "family \"%s\", size %i, style %i", family,
+ *psize, style);
return;
diff --git a/frontends/riscos/global_history.c b/frontends/riscos/global_history.c
index d122a4d7f..7dfc58317 100644
--- a/frontends/riscos/global_history.c
+++ b/frontends/riscos/global_history.c
@@ -474,12 +474,12 @@ nserror ro_gui_global_history_present(void)
res = ro_global_history_init();
if (res == NSERROR_OK) {
- LOG("Presenting");
+ NSLOG(netsurf, INFO, "Presenting");
ro_gui_dialog_open_top(global_history_window->core.wh,
global_history_window->core.toolbar,
600, 800);
} else {
- LOG("Failed presenting code %d", res);
+ NSLOG(netsurf, INFO, "Failed presenting code %d", res);
}
return res;
diff --git a/frontends/riscos/gui.c b/frontends/riscos/gui.c
index 576e1ff12..cfc513f72 100644
--- a/frontends/riscos/gui.c
+++ b/frontends/riscos/gui.c
@@ -274,8 +274,10 @@ set_colour_from_wimp(struct nsoption_s *opts,
error = xwimp_read_true_palette((os_palette *) &palette);
if (error != NULL) {
- LOG("xwimp_read_palette: 0x%x: %s",
- error->errnum, error->errmess);
+ NSLOG(netsurf, INFO,
+ "xwimp_read_palette: 0x%x: %s",
+ error->errnum,
+ error->errmess);
} else {
/* entries are in B0G0R0LL */
def_colour = palette.entries[wimp] >> 8;
@@ -307,7 +309,7 @@ static nserror set_defaults(struct nsoption_s *defaults)
if (nsoption_charp(ca_bundle) == NULL ||
nsoption_charp(cookie_file) == NULL ||
nsoption_charp(cookie_jar) == NULL) {
- LOG("Failed initialising default options");
+ NSLOG(netsurf, INFO, "Failed initialising default options");
return NSERROR_BAD_PARAMETER;
}
@@ -430,7 +432,7 @@ static void ro_gui_signal(int sig)
if (used) {
int curr_slot;
xwimp_slot_size(-1, -1, &curr_slot, 0, 0);
- LOG("saving WimpSlot, size 0x%x", curr_slot);
+ NSLOG(netsurf, INFO, "saving WimpSlot, size 0x%x", curr_slot);
xosfile_save("$.NetSurf_Slot", 0x8000, 0,
(byte *) 0x8000,
(byte *) 0x8000 + curr_slot);
@@ -440,7 +442,11 @@ static void ro_gui_signal(int sig)
byte *base_address;
xosdynamicarea_read(__dynamic_num, &size,
&base_address, 0, 0, 0, 0, 0);
- LOG("saving DA %i, base %p, size 0x%x", __dynamic_num, base_address, size);
+ NSLOG(netsurf, INFO,
+ "saving DA %i, base %p, size 0x%x",
+ __dynamic_num,
+ base_address,
+ size);
xosfile_save("$.NetSurf_DA",
(bits) base_address, 0,
base_address,
@@ -452,7 +458,7 @@ static void ro_gui_signal(int sig)
* defines a coredump directory. */
const _kernel_oserror *err = __unixlib_write_coredump (NULL);
if (err != NULL)
- LOG("Coredump failed: %s", err->errmess);
+ NSLOG(netsurf, INFO, "Coredump failed: %s", err->errmess);
#endif
xhourglass_colours(old_sand, old_glass, 0, 0);
@@ -536,7 +542,8 @@ static char *ro_gui_uri_file_parse(const char *file_name, char **uri_title)
*uri_title = NULL;
fp = fopen(file_name, "rb");
if (!fp) {
- LOG("fopen(\"%s\", \"rb\"): %i: %s", file_name, errno, strerror(errno));
+ NSLOG(netsurf, INFO, "fopen(\"%s\", \"rb\"): %i: %s",
+ file_name, errno, strerror(errno));
ro_warn_user("LoadError", strerror(errno));
return 0;
}
@@ -597,14 +604,16 @@ static char *ro_gui_url_file_parse(const char *file_name)
fp = fopen(file_name, "r");
if (!fp) {
- LOG("fopen(\"%s\", \"r\"): %i: %s", file_name, errno, strerror(errno));
+ NSLOG(netsurf, INFO, "fopen(\"%s\", \"r\"): %i: %s",
+ file_name, errno, strerror(errno));
ro_warn_user("LoadError", strerror(errno));
return 0;
}
if (!fgets(line, sizeof line, fp)) {
if (ferror(fp)) {
- LOG("fgets: %i: %s", errno, strerror(errno));
+ NSLOG(netsurf, INFO, "fgets: %i: %s", errno,
+ strerror(errno));
ro_warn_user("LoadError", strerror(errno));
} else
ro_warn_user("LoadError", messages_get("EmptyError"));
@@ -641,7 +650,8 @@ static char *ro_gui_ieurl_file_parse(const char *file_name)
fp = fopen(file_name, "r");
if (!fp) {
- LOG("fopen(\"%s\", \"r\"): %i: %s", file_name, errno, strerror(errno));
+ NSLOG(netsurf, INFO, "fopen(\"%s\", \"r\"): %i: %s",
+ file_name, errno, strerror(errno));
ro_warn_user("LoadError", strerror(errno));
return 0;
}
@@ -660,7 +670,7 @@ static char *ro_gui_ieurl_file_parse(const char *file_name)
}
}
if (ferror(fp)) {
- LOG("fgets: %i: %s", errno, strerror(errno));
+ NSLOG(netsurf, INFO, "fgets: %i: %s", errno, strerror(errno));
ro_warn_user("LoadError", strerror(errno));
fclose(fp);
return 0;
@@ -732,7 +742,8 @@ static void ro_msg_dataopen(wimp_message *message)
message->your_ref = message->my_ref;
oserror = xwimp_send_message(wimp_USER_MESSAGE, message, message->sender);
if (oserror) {
- LOG("xwimp_send_message: 0x%x: %s", oserror->errnum, oserror->errmess);
+ NSLOG(netsurf, INFO, "xwimp_send_message: 0x%x: %s",
+ oserror->errnum, oserror->errmess);
ro_warn_user("WimpError", oserror->errmess);
return;
}
@@ -855,7 +866,8 @@ static void ro_msg_dataload(wimp_message *message)
oserror = xwimp_send_message(wimp_USER_MESSAGE, message,
message->sender);
if (oserror) {
- LOG("xwimp_send_message: 0x%x: %s", oserror->errnum, oserror->errmess);
+ NSLOG(netsurf, INFO, "xwimp_send_message: 0x%x: %s",
+ oserror->errnum, oserror->errmess);
ro_warn_user("WimpError", oserror->errmess);
return;
}
@@ -925,7 +937,10 @@ static void ro_msg_datasave(wimp_message *message)
error = xwimp_send_message(wimp_USER_MESSAGE, (wimp_message*)dataxfer, message->sender);
if (error) {
- LOG("xwimp_send_message: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO,
+ "xwimp_send_message: 0x%x: %s",
+ error->errnum,
+ error->errmess);
ro_warn_user("WimpError", error->errmess);
}
}
@@ -977,7 +992,8 @@ static void ro_msg_prequit(wimp_message *message)
error = xwimp_send_message(wimp_USER_MESSAGE_ACKNOWLEDGE,
message, message->sender);
if (error) {
- LOG("xwimp_send_message: 0x%x:%s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_send_message: 0x%x:%s",
+ error->errnum, error->errmess);
ro_warn_user("WimpError", error->errmess);
}
}
@@ -1003,7 +1019,8 @@ static void ro_msg_save_desktop(wimp_message *message)
}
if (error) {
- LOG("xosgbpb_writew/xos_bputw: 0x%x:%s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xosgbpb_writew/xos_bputw: 0x%x:%s",
+ error->errnum, error->errmess);
ro_warn_user("SaveError", error->errmess);
/* we must cancel the save by acknowledging the message */
@@ -1011,7 +1028,8 @@ static void ro_msg_save_desktop(wimp_message *message)
error = xwimp_send_message(wimp_USER_MESSAGE_ACKNOWLEDGE,
message, message->sender);
if (error) {
- LOG("xwimp_send_message: 0x%x:%s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_send_message: 0x%x:%s",
+ error->errnum, error->errmess);
ro_warn_user("WimpError", error->errmess);
}
}
@@ -1062,7 +1080,8 @@ static void ro_gui_get_screen_properties(void)
error = xos_read_vdu_variables(PTR_OS_VDU_VAR_LIST(&vars), vals);
if (error) {
- LOG("xos_read_vdu_variables: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xos_read_vdu_variables: 0x%x: %s",
+ error->errnum, error->errmess);
ro_warn_user("MiscError", error->errmess);
return;
}
@@ -1079,9 +1098,9 @@ static void ro_gui_check_resolvers(void)
char *resolvers;
resolvers = getenv("Inet$Resolvers");
if (resolvers && resolvers[0]) {
- LOG("Inet$Resolvers '%s'", resolvers);
+ NSLOG(netsurf, INFO, "Inet$Resolvers '%s'", resolvers);
} else {
- LOG("Inet$Resolvers not set or empty");
+ NSLOG(netsurf, INFO, "Inet$Resolvers not set or empty");
ro_warn_user("Resolvers", 0);
}
}
@@ -1196,7 +1215,8 @@ static nserror gui_init(int argc, char** argv)
PTR_WIMP_MESSAGE_LIST(&task_messages), 0,
&task_handle);
if (error) {
- LOG("xwimp_initialise: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_initialise: 0x%x: %s",
+ error->errnum, error->errmess);
die(error->errmess);
}
/* Register message handlers */
@@ -1234,7 +1254,8 @@ static nserror gui_init(int argc, char** argv)
die("Failed to locate Templates resource.");
error = xwimp_open_template(path);
if (error) {
- LOG("xwimp_open_template failed: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_open_template failed: 0x%x: %s",
+ error->errnum, error->errmess);
die(error->errmess);
}
@@ -1275,7 +1296,7 @@ static nserror gui_init(int argc, char** argv)
/* parse command-line arguments */
if (argc == 2) {
- LOG("parameters: '%s'", argv[1]);
+ NSLOG(netsurf, INFO, "parameters: '%s'", argv[1]);
/* this is needed for launching URI files */
if (strcasecmp(argv[1], "-nowin") == 0) {
return NSERROR_OK;
@@ -1283,7 +1304,8 @@ static nserror gui_init(int argc, char** argv)
ret = nsurl_create(NETSURF_HOMEPAGE, &url);
}
else if (argc == 3) {
- LOG("parameters: '%s' '%s'", argv[1], argv[2]);
+ NSLOG(netsurf, INFO, "parameters: '%s' '%s'", argv[1],
+ argv[2]);
open_window = true;
/* HTML files */
@@ -1294,7 +1316,7 @@ static nserror gui_init(int argc, char** argv)
else if (strcasecmp(argv[1], "-urlf") == 0) {
char *urlf = ro_gui_url_file_parse(argv[2]);
if (!urlf) {
- LOG("allocation failed");
+ NSLOG(netsurf, INFO, "allocation failed");
die("Insufficient memory for URL");
}
ret = nsurl_create(urlf, &url);
@@ -1306,7 +1328,8 @@ static nserror gui_init(int argc, char** argv)
}
/* Unknown => exit here. */
else {
- LOG("Unknown parameters: '%s' '%s'", argv[1], argv[2]);
+ NSLOG(netsurf, INFO, "Unknown parameters: '%s' '%s'",
+ argv[1], argv[2]);
return NSERROR_BAD_PARAMETER;
}
}
@@ -1354,7 +1377,8 @@ const char *ro_gui_default_language(void)
/* choose a language from the configured country number */
error = xosbyte_read(osbyte_VAR_COUNTRY_NUMBER, &country);
if (error) {
- LOG("xosbyte_read failed: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xosbyte_read failed: 0x%x: %s",
+ error->errnum, error->errmess);
country = 1;
}
switch (country) {
@@ -1405,7 +1429,10 @@ static nserror ro_path_to_nsurl(const char *path, struct nsurl **url_out)
/* calculate the canonical risc os path */
error = xosfscontrol_canonicalise_path(path, 0, 0, 0, 0, &spare);
if (error) {
- LOG("xosfscontrol_canonicalise_path failed: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO,
+ "xosfscontrol_canonicalise_path failed: 0x%x: %s",
+ error->errnum,
+ error->errmess);
ro_warn_user("PathToURL", error->errmess);
return NSERROR_NOT_FOUND;
}
@@ -1418,7 +1445,10 @@ static nserror ro_path_to_nsurl(const char *path, struct nsurl **url_out)
error = xosfscontrol_canonicalise_path(path, canonical_path, 0, 0, 1 - spare, 0);
if (error) {
- LOG("xosfscontrol_canonicalise_path failed: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO,
+ "xosfscontrol_canonicalise_path failed: 0x%x: %s",
+ error->errnum,
+ error->errmess);
ro_warn_user("PathToURL", error->errmess);
free(canonical_path);
return NSERROR_NOT_FOUND;
@@ -1428,7 +1458,7 @@ static nserror ro_path_to_nsurl(const char *path, struct nsurl **url_out)
unix_path = __unixify(canonical_path, __RISCOSIFY_NO_REVERSE_SUFFIX, NULL, 0, 0);
if (unix_path == NULL) {
- LOG("__unixify failed: %s", canonical_path);
+ NSLOG(netsurf, INFO, "__unixify failed: %s", canonical_path);
free(canonical_path);
return NSERROR_BAD_PARAMETER;
}
@@ -1446,7 +1476,7 @@ static nserror ro_path_to_nsurl(const char *path, struct nsurl **url_out)
urllen = strlen(escaped_path) + FILE_SCHEME_PREFIX_LEN + 1;
url = malloc(urllen);
if (url == NULL) {
- LOG("Unable to allocate url");
+ NSLOG(netsurf, INFO, "Unable to allocate url");
free(escaped_path);
return NSERROR_NOMEM;
}
@@ -1596,7 +1626,8 @@ static void ro_gui_keypress_cb(void *pw)
if (ro_gui_wimp_event_keypress(key) == false) {
os_error *error = xwimp_process_key(key->c);
if (error) {
- LOG("xwimp_process_key: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_process_key: 0x%x: %s",
+ error->errnum, error->errmess);
ro_warn_user("WimpError", error->errmess);
}
}
@@ -1633,7 +1664,8 @@ static void ro_gui_keypress(wimp_key *key)
} else if (ro_gui_wimp_event_keypress(key) == false) {
os_error *error = xwimp_process_key(key->c);
if (error) {
- LOG("xwimp_process_key: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_process_key: 0x%x: %s",
+ error->errnum, error->errmess);
ro_warn_user("WimpError", error->errmess);
}
}
@@ -1905,7 +1937,8 @@ void ro_gui_open_window_request(wimp_open *open)
error = xwimp_open_window(open);
if (error) {
- LOG("xwimp_open_window: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_open_window: 0x%x: %s",
+ error->errnum, error->errmess);
ro_warn_user("WimpError", error->errmess);
return;
}
@@ -1926,7 +1959,8 @@ static void ro_gui_view_source_bounce(wimp_message *message)
sprintf(command, "@RunType_FFF %s", filename);
error = xwimp_start_task(command, 0);
if (error) {
- LOG("xwimp_start_task failed: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_start_task failed: 0x%x: %s",
+ error->errnum, error->errmess);
ro_warn_user("WimpError", error->errmess);
}
}
@@ -1989,7 +2023,7 @@ void ro_gui_view_source(struct hlcache_handle *c)
r = __riscosify(full_name, 0, __RISCOSIFY_NO_SUFFIX,
message.file_name, 212, 0);
if (r == 0) {
- LOG("__riscosify failed");
+ NSLOG(netsurf, INFO, "__riscosify failed");
return;
}
message.file_name[211] = '\0';
@@ -1999,7 +2033,10 @@ void ro_gui_view_source(struct hlcache_handle *c)
(byte *) source_data,
(byte *) source_data + source_size);
if (error) {
- LOG("xosfile_save_stamped failed: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO,
+ "xosfile_save_stamped failed: 0x%x: %s",
+ error->errnum,
+ error->errmess);
ro_warn_user("MiscError", error->errmess);
return;
}
@@ -2069,7 +2106,7 @@ static void ro_gui_choose_language(void)
*/
nserror ro_warn_user(const char *warning, const char *detail)
{
- LOG("%s %s", warning, detail);
+ NSLOG(netsurf, INFO, "%s %s", warning, detail);
if (dialog_warning) {
char warn_buffer[300];
@@ -2113,7 +2150,7 @@ void die(const char * const error)
{
os_error warn_error;
- LOG("%s", error);
+ NSLOG(netsurf, INFO, "%s", error);
warn_error.errnum = 1; /* \todo: reasonable ? */
strncpy(warn_error.errmess, messages_get(error),
@@ -2350,7 +2387,7 @@ void ro_gui_dump_browser_window(struct browser_window *bw)
/* open file for dump */
FILE *stream = fopen("<Wimp$ScrapDir>.WWW.NetSurf.dump", "w");
if (!stream) {
- LOG("fopen: errno %i", errno);
+ NSLOG(netsurf, INFO, "fopen: errno %i", errno);
ro_warn_user("SaveError", strerror(errno));
return;
}
@@ -2363,7 +2400,8 @@ void ro_gui_dump_browser_window(struct browser_window *bw)
error = xwimp_start_task("Filer_Run <Wimp$ScrapDir>.WWW.NetSurf.dump",
0);
if (error) {
- LOG("xwimp_start_task failed: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_start_task failed: 0x%x: %s",
+ error->errnum, error->errmess);
ro_warn_user("WimpError", error->errmess);
}
}
@@ -2403,7 +2441,7 @@ static char *get_cachepath(void)
cachedir = getenv("Cache$Dir");
if ((cachedir == NULL) || (cachedir[0] == 0)) {
- LOG("cachedir was null");
+ NSLOG(netsurf, INFO, "cachedir was null");
return NULL;
}
ret = netsurf_mkpath(&cachepath, NULL, 2, cachedir, "NetSurf");
@@ -2519,5 +2557,8 @@ int main(int argc, char** argv)
netsurf_exit();
nsoption_finalise(nsoptions, nsoptions_default);
+ /* finalise logging */
+ nslog_finalise();
+
return 0;
}
diff --git a/frontends/riscos/gui/button_bar.c b/frontends/riscos/gui/button_bar.c
index 6ecd7cffa..34ae39ae5 100644
--- a/frontends/riscos/gui/button_bar.c
+++ b/frontends/riscos/gui/button_bar.c
@@ -138,7 +138,7 @@ struct button_bar *ro_gui_button_bar_create(struct theme_descriptor *theme,
button_bar = malloc(sizeof(struct button_bar));
if (button_bar == NULL) {
- LOG("No memory for malloc()");
+ NSLOG(netsurf, INFO, "No memory for malloc()");
return NULL;
}
@@ -538,7 +538,10 @@ bool ro_gui_button_bar_icon_update(struct button_bar *button_bar)
error = xwimp_create_icon(&icon, &button->icon);
if (error) {
- LOG("xwimp_create_icon: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO,
+ "xwimp_create_icon: 0x%x: %s",
+ error->errnum,
+ error->errmess);
ro_warn_user("WimpError", error->errmess);
button->icon = -1;
return false;
@@ -548,7 +551,10 @@ bool ro_gui_button_bar_icon_update(struct button_bar *button_bar)
error = xwimp_delete_icon(button_bar->window,
button->icon);
if (error != NULL) {
- LOG("xwimp_delete_icon: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO,
+ "xwimp_delete_icon: 0x%x: %s",
+ error->errnum,
+ error->errmess);
ro_warn_user("WimpError", error->errmess);
return false;
}
@@ -598,7 +604,10 @@ bool ro_gui_button_bar_icon_resize(struct button_bar *button_bar)
button->y_pos +
button->y_size);
if (error != NULL) {
- LOG("xwimp_resize_icon: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO,
+ "xwimp_resize_icon: 0x%x: %s",
+ error->errnum,
+ error->errmess);
ro_warn_user("WimpError", error->errmess);
button->icon = -1;
return false;
@@ -769,7 +778,10 @@ bool ro_gui_button_bar_click(struct button_bar *button_bar,
button_bar->sprites,
sprite, &box, NULL);
if (error)
- LOG("xdragasprite_start: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO,
+ "xdragasprite_start: 0x%x: %s",
+ error->errnum,
+ error->errmess);
ro_mouse_drag_start(ro_gui_button_bar_drag_end,
NULL, NULL, NULL);
@@ -870,7 +882,8 @@ void ro_gui_button_bar_drag_end(wimp_dragged *drag, void *data)
error = xwimp_get_pointer_info(&pointer);
if (error) {
- LOG("xwimp_get_pointer_info: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_get_pointer_info: 0x%x: %s",
+ error->errnum, error->errmess);
ro_warn_user("WimpError", error->errmess);
return;
}
@@ -880,7 +893,8 @@ void ro_gui_button_bar_drag_end(wimp_dragged *drag, void *data)
state.w = drag_start->window;
error = xwimp_get_window_state(&state);
if (error) {
- LOG("xwimp_get_window_state: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_get_window_state: 0x%x: %s",
+ error->errnum, error->errmess);
ro_warn_user("WimpError", error->errmess);
return;
}
@@ -1068,7 +1082,7 @@ char *ro_gui_button_bar_get_config(struct button_bar *button_bar)
config = malloc(size);
if (config == NULL) {
- LOG("No memory for malloc()");
+ NSLOG(netsurf, INFO, "No memory for malloc()");
ro_warn_user("NoMemory", 0);
return NULL;
}
diff --git a/frontends/riscos/gui/progress_bar.c b/frontends/riscos/gui/progress_bar.c
index c47c2af7d..06d89dbf4 100644
--- a/frontends/riscos/gui/progress_bar.c
+++ b/frontends/riscos/gui/progress_bar.c
@@ -137,7 +137,8 @@ struct progress_bar *ro_gui_progress_bar_create(void)
error = xwimp_create_window((wimp_window *)&progress_bar_definition,
&pb->w);
if (error) {
- LOG("xwimp_create_window: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_create_window: 0x%x: %s",
+ error->errnum, error->errmess);
free(pb);
return NULL;
}
@@ -165,7 +166,8 @@ void ro_gui_progress_bar_destroy(struct progress_bar *pb)
ro_gui_wimp_event_finalise(pb->w);
error = xwimp_delete_window(pb->w);
if (error) {
- LOG("xwimp_delete_window: 0x%x:%s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_delete_window: 0x%x:%s",
+ error->errnum, error->errmess);
}
free(pb);
@@ -327,7 +329,8 @@ void ro_gui_progress_bar_update(struct progress_bar *pb, int width, int height)
redraw.box.x0 = cur.x1;
error = xwimp_update_window(&redraw, &more);
if (error) {
- LOG("Error getting update window: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "Error getting update window: 0x%x: %s",
+ error->errnum, error->errmess);
return;
}
if (more)
@@ -351,7 +354,8 @@ void ro_gui_progress_bar_redraw(wimp_draw *redraw)
error = xwimp_redraw_window(redraw, &more);
if (error) {
- LOG("xwimp_redraw_window: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_redraw_window: 0x%x: %s",
+ error->errnum, error->errmess);
return;
}
if (more)
@@ -385,7 +389,8 @@ void ro_gui_progress_bar_animate(void *p)
redraw.box = pb->visible;
error = xwimp_update_window(&redraw, &more);
if (error != NULL) {
- LOG("Error getting update window: '%s'", error->errmess);
+ NSLOG(netsurf, INFO, "Error getting update window: '%s'",
+ error->errmess);
return;
}
if (more)
@@ -533,7 +538,8 @@ void ro_gui_progress_bar_redraw_window(wimp_draw *redraw,
}
error = xwimp_get_rectangle(redraw, &more);
if (error) {
- LOG("xwimp_get_rectangle: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_get_rectangle: 0x%x: %s",
+ error->errnum, error->errmess);
return;
}
}
diff --git a/frontends/riscos/gui/status_bar.c b/frontends/riscos/gui/status_bar.c
index bcaf3baf9..dd1aab639 100644
--- a/frontends/riscos/gui/status_bar.c
+++ b/frontends/riscos/gui/status_bar.c
@@ -131,7 +131,8 @@ struct status_bar *ro_gui_status_bar_create(wimp_w parent, unsigned int width)
error = xwimp_create_window((wimp_window *)&status_bar_definition,
&sb->w);
if (error) {
- LOG("xwimp_create_window: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_create_window: 0x%x: %s",
+ error->errnum, error->errmess);
free(sb);
return NULL;
}
@@ -165,7 +166,8 @@ void ro_gui_status_bar_destroy(struct status_bar *sb)
ro_gui_wimp_event_finalise(sb->w);
error = xwimp_delete_window(sb->w);
if (error) {
- LOG("xwimp_delete_window: 0x%x:%s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_delete_window: 0x%x:%s",
+ error->errnum, error->errmess);
}
ro_gui_progress_bar_destroy(sb->pb);
@@ -222,7 +224,8 @@ void ro_gui_status_bar_set_visible(struct status_bar *sb, bool visible)
} else {
os_error *error = xwimp_close_window(sb->w);
if (error) {
- LOG("xwimp_close_window: 0x%x:%s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_close_window: 0x%x:%s",
+ error->errnum, error->errmess);
}
}
}
@@ -275,14 +278,15 @@ void ro_gui_status_bar_set_progress_range(struct status_bar *sb,
old_range = ro_gui_progress_bar_get_range(sb->pb);
ro_gui_progress_bar_set_range(sb->pb, range);
- LOG("Ranges are %i vs %i", old_range, range);
+ NSLOG(netsurf, INFO, "Ranges are %i vs %i", old_range, range);
if ((old_range == 0) && (range != 0)) {
ro_gui_status_position_progress_bar(sb);
} else if ((old_range != 0) && (range == 0)) {
os_error *error = xwimp_close_window(
ro_gui_progress_bar_get_window(sb->pb));
if (error) {
- LOG("xwimp_close_window: 0x%x:%s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_close_window: 0x%x:%s",
+ error->errnum, error->errmess);
}
}
}
@@ -354,7 +358,8 @@ void ro_gui_status_bar_resize(struct status_bar *sb)
state.w = sb->parent;
error = xwimp_get_window_state(&state);
if (error) {
- LOG("xwimp_get_window_state: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_get_window_state: 0x%x: %s",
+ error->errnum, error->errmess);
return;
}
window_width = state.visible.x1 - state.visible.x0;
@@ -377,7 +382,8 @@ void ro_gui_status_bar_resize(struct status_bar *sb)
extent.y1 = status_height - 4;
error = xwimp_set_extent(sb->w, &extent);
if (error) {
- LOG("xwimp_set_extent: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_set_extent: 0x%x: %s",
+ error->errnum, error->errmess);
return;
}
@@ -405,7 +411,10 @@ void ro_gui_status_bar_resize(struct status_bar *sb)
wimp_CHILD_LINKS_PARENT_VISIBLE_BOTTOM_OR_LEFT
<< wimp_CHILD_TS_EDGE_SHIFT);
if (error) {
- LOG("xwimp_open_window_nested: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO,
+ "xwimp_open_window_nested: 0x%x: %s",
+ error->errnum,
+ error->errmess);
return;
}
ro_gui_status_position_progress_bar(sb);
@@ -413,7 +422,8 @@ void ro_gui_status_bar_resize(struct status_bar *sb)
status_width - WIDGET_WIDTH, 0,
status_width, status_height - 4);
if (error) {
- LOG("xwimp_resize_icon: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_resize_icon: 0x%x: %s",
+ error->errnum, error->errmess);
return;
}
@@ -454,7 +464,8 @@ void ro_gui_status_bar_redraw(wimp_draw *redraw)
/* redraw the window */
error = xwimp_redraw_window(redraw, &more);
if (error) {
- LOG("xwimp_redraw_window: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_redraw_window: 0x%x: %s",
+ error->errnum, error->errmess);
return;
}
while (more) {
@@ -463,7 +474,10 @@ void ro_gui_status_bar_redraw(wimp_draw *redraw)
error = xcolourtrans_set_font_colours(font_CURRENT,
0xeeeeee00, 0x00000000, 14, 0, 0, 0);
if (error) {
- LOG("xcolourtrans_set_font_colours: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO,
+ "xcolourtrans_set_font_colours: 0x%x: %s",
+ error->errnum,
+ error->errmess);
return;
}
code = rufl_paint(ro_gui_desktop_font_family,
@@ -474,10 +488,13 @@ void ro_gui_status_bar_redraw(wimp_draw *redraw)
rufl_BLEND_FONT);
if (code != rufl_OK) {
if (code == rufl_FONT_MANAGER_ERROR)
- LOG("rufl_FONT_MANAGER_ERROR: 0x%x: %s",
- rufl_fm_error->errnum, rufl_fm_error->errmess);
+ NSLOG(netsurf, INFO,
+ "rufl_FONT_MANAGER_ERROR: 0x%x: %s",
+ rufl_fm_error->errnum,
+ rufl_fm_error->errmess);
else
- LOG("rufl_paint: 0x%x", code);
+ NSLOG(netsurf, INFO,
+ "rufl_paint: 0x%x", code);
}
}
@@ -493,7 +510,8 @@ void ro_gui_status_bar_redraw(wimp_draw *redraw)
error = xwimp_get_rectangle(redraw, &more);
if (error) {
- LOG("xwimp_get_rectangle: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_get_rectangle: 0x%x: %s",
+ error->errnum, error->errmess);
return;
}
}
@@ -532,7 +550,10 @@ bool ro_gui_status_bar_click(wimp_pointer *pointer)
drag.initial.y1 = pointer->pos.y;
error = xwimp_drag_box(&drag);
if (error) {
- LOG("xwimp_drag_box: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO,
+ "xwimp_drag_box: 0x%x: %s",
+ error->errnum,
+ error->errmess);
}
break;
}
@@ -557,7 +578,8 @@ void ro_gui_status_bar_open(wimp_open *open)
state.w = sb->parent;
error = xwimp_get_window_state(&state);
if (error) {
- LOG("xwimp_get_window_state: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_get_window_state: 0x%x: %s",
+ error->errnum, error->errmess);
return;
}
window_width = state.visible.x1 - state.visible.x0;
@@ -596,7 +618,8 @@ void ro_gui_status_position_progress_bar(struct status_bar *sb)
state.w = sb->w;
error = xwimp_get_window_state(&state);
if (error) {
- LOG("xwimp_get_window_state: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_get_window_state: 0x%x: %s",
+ error->errnum, error->errmess);
return;
}
@@ -626,7 +649,8 @@ void ro_gui_status_position_progress_bar(struct status_bar *sb)
wimp_CHILD_LINKS_PARENT_VISIBLE_BOTTOM_OR_LEFT
<< wimp_CHILD_TS_EDGE_SHIFT);
if (error) {
- LOG("xwimp_open_window: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_open_window: 0x%x: %s",
+ error->errnum, error->errmess);
}
/* update the progress bar display on non-standard width */
diff --git a/frontends/riscos/gui/throbber.c b/frontends/riscos/gui/throbber.c
index a326f806c..f3b79a68e 100644
--- a/frontends/riscos/gui/throbber.c
+++ b/frontends/riscos/gui/throbber.c
@@ -81,7 +81,7 @@ struct throbber *ro_gui_throbber_create(struct theme_descriptor *theme)
throbber = malloc(sizeof(struct throbber));
if (throbber == NULL) {
- LOG("No memory for malloc()");
+ NSLOG(netsurf, INFO, "No memory for malloc()");
return NULL;
}
@@ -248,7 +248,8 @@ bool ro_gui_throbber_icon_update(struct throbber *throbber)
error = xwimp_create_icon(&icon, &throbber->icon);
if (error != NULL) {
- LOG("xwimp_create_icon: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_create_icon: 0x%x: %s",
+ error->errnum, error->errmess);
ro_warn_user("WimpError", error->errmess);
throbber->icon = -1;
return false;
@@ -259,7 +260,8 @@ bool ro_gui_throbber_icon_update(struct throbber *throbber)
} else if (throbber->hidden && throbber->icon != -1) {
error = xwimp_delete_icon(throbber->window, throbber->icon);
if (error != NULL) {
- LOG("xwimp_delete_icon: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_delete_icon: 0x%x: %s",
+ error->errnum, error->errmess);
ro_warn_user("WimpError", error->errmess);
return false;
}
@@ -295,7 +297,8 @@ bool ro_gui_throbber_icon_resize(struct throbber *throbber)
throbber->extent.x0, throbber->extent.y0,
throbber->extent.x1, throbber->extent.y1);
if (error != NULL) {
- LOG("xwimp_resize_icon: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_resize_icon: 0x%x: %s",
+ error->errnum, error->errmess);
ro_warn_user("WimpError", error->errmess);
throbber->icon = -1;
return false;
diff --git a/frontends/riscos/gui/url_bar.c b/frontends/riscos/gui/url_bar.c
index a5ec3f8c6..ee5c689df 100644
--- a/frontends/riscos/gui/url_bar.c
+++ b/frontends/riscos/gui/url_bar.c
@@ -140,7 +140,7 @@ struct url_bar *ro_gui_url_bar_create(struct theme_descriptor *theme)
url_bar = malloc(sizeof(struct url_bar));
if (url_bar == NULL) {
- LOG("No memory for malloc()");
+ NSLOG(netsurf, INFO, "No memory for malloc()");
return NULL;
}
@@ -240,7 +240,8 @@ static bool ro_gui_url_bar_icon_resize(struct url_bar *url_bar, bool full)
url_bar->container_icon,
x0, y0, x1, y1);
if (error != NULL) {
- LOG("xwimp_resize_icon: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_resize_icon: 0x%x: %s",
+ error->errnum, error->errmess);
ro_warn_user("WimpError", error->errmess);
url_bar->container_icon = -1;
return false;
@@ -260,7 +261,8 @@ static bool ro_gui_url_bar_icon_resize(struct url_bar *url_bar, bool full)
url_bar->suggest_icon,
x0, y0, x1, y1);
if (error != NULL) {
- LOG("xwimp_resize_icon: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_resize_icon: 0x%x: %s",
+ error->errnum, error->errmess);
ro_warn_user("WimpError", error->errmess);
url_bar->suggest_icon = -1;
return false;
@@ -281,7 +283,8 @@ static bool ro_gui_url_bar_icon_resize(struct url_bar *url_bar, bool full)
url_bar->text_icon,
x0, y0, x1, y1);
if (error != NULL) {
- LOG("xwimp_resize_icon: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_resize_icon: 0x%x: %s",
+ error->errnum, error->errmess);
ro_warn_user("WimpError", error->errmess);
url_bar->text_icon = -1;
return false;
@@ -362,7 +365,8 @@ static bool ro_gui_url_bar_icon_update(struct url_bar *url_bar)
wimp_ICON_BUTTON_TYPE_SHIFT);
error = xwimp_create_icon(&icon, &url_bar->container_icon);
if (error != NULL) {
- LOG("xwimp_create_icon: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_create_icon: 0x%x: %s",
+ error->errnum, error->errmess);
ro_warn_user("WimpError", error->errmess);
url_bar->container_icon = -1;
return false;
@@ -373,7 +377,8 @@ static bool ro_gui_url_bar_icon_update(struct url_bar *url_bar)
error = xwimp_delete_icon(url_bar->window,
url_bar->container_icon);
if (error != NULL) {
- LOG("xwimp_delete_icon: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_delete_icon: 0x%x: %s",
+ error->errnum, error->errmess);
ro_warn_user("WimpError", error->errmess);
return false;
}
@@ -399,7 +404,8 @@ static bool ro_gui_url_bar_icon_update(struct url_bar *url_bar)
wimp_ICON_BUTTON_TYPE_SHIFT);
error = xwimp_create_icon(&icon, &url_bar->text_icon);
if (error) {
- LOG("xwimp_create_icon: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_create_icon: 0x%x: %s",
+ error->errnum, error->errmess);
ro_warn_user("WimpError", error->errmess);
url_bar->text_icon = -1;
return false;
@@ -410,7 +416,8 @@ static bool ro_gui_url_bar_icon_update(struct url_bar *url_bar)
error = xwimp_delete_icon(url_bar->window,
url_bar->text_icon);
if (error != NULL) {
- LOG("xwimp_delete_icon: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_delete_icon: 0x%x: %s",
+ error->errnum, error->errmess);
ro_warn_user("WimpError", error->errmess);
return false;
}
@@ -430,7 +437,8 @@ static bool ro_gui_url_bar_icon_update(struct url_bar *url_bar)
wimp_ICON_BUTTON_TYPE_SHIFT);
error = xwimp_create_icon(&icon, &url_bar->suggest_icon);
if (error) {
- LOG("xwimp_create_icon: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_create_icon: 0x%x: %s",
+ error->errnum, error->errmess);
ro_warn_user("WimpError", error->errmess);
return false;
}
@@ -450,7 +458,8 @@ static bool ro_gui_url_bar_icon_update(struct url_bar *url_bar)
error = xwimp_delete_icon(url_bar->window,
url_bar->suggest_icon);
if (error != NULL) {
- LOG("xwimp_delete_icon: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_delete_icon: 0x%x: %s",
+ error->errnum, error->errmess);
ro_warn_user("WimpError", error->errmess);
return false;
}
@@ -940,7 +949,8 @@ bool ro_gui_url_bar_take_caret(struct url_bar *url_bar)
error = xwimp_set_caret_position(url_bar->window, url_bar->text_icon,
-1, -1, -1, 0);
if (error) {
- LOG("xwimp_set_caret_position: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_set_caret_position: 0x%x: %s",
+ error->errnum, error->errmess);
ro_warn_user("WimpError", error->errmess);
return false;
@@ -977,7 +987,7 @@ void ro_gui_url_bar_set_url(struct url_bar *url_bar, const char *url,
if (err != NSERROR_OK) {
/* A bad encoding should never happen, so assert this */
assert(err != NSERROR_BAD_ENCODING);
- LOG("utf8_to_enc failed");
+ NSLOG(netsurf, INFO, "utf8_to_enc failed");
/* Paranoia */
local_text = NULL;
}
@@ -993,7 +1003,8 @@ void ro_gui_url_bar_set_url(struct url_bar *url_bar, const char *url,
if (strlen(local_url) >= url_bar->text_size) {
url_bar->text_buffer[0] = '\0';
ro_warn_user("LongURL", NULL);
- LOG("Long URL (%zu chars): %s", strlen(url), url);
+ NSLOG(netsurf, INFO, "Long URL (%zu chars): %s", strlen(url),
+ url);
} else {
strncpy(url_bar->text_buffer, local_url,
url_bar->text_size - 1);
@@ -1021,7 +1032,8 @@ void ro_gui_url_bar_set_url(struct url_bar *url_bar, const char *url,
error = xwimp_get_caret_position(&caret);
if (error) {
- LOG("xwimp_get_caret_position: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_get_caret_position: 0x%x: %s",
+ error->errnum, error->errmess);
ro_warn_user("WimpError", error->errmess);
return;
}
@@ -1034,7 +1046,10 @@ void ro_gui_url_bar_set_url(struct url_bar *url_bar, const char *url,
error = xwimp_set_caret_position(url_bar->window,
url_bar->text_icon, 0, 0, -1, strlen(set_url));
if (error) {
- LOG("xwimp_set_caret_position: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO,
+ "xwimp_set_caret_position: 0x%x: %s",
+ error->errnum,
+ error->errmess);
ro_warn_user("WimpError", error->errmess);
}
}
@@ -1123,7 +1138,8 @@ bool ro_gui_url_bar_get_url_extent(struct url_bar *url_bar, os_box *extent)
state.i = url_bar->container_icon;
error = xwimp_get_icon_state(&state);
if (error) {
- LOG("xwimp_get_icon_state: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_get_icon_state: 0x%x: %s",
+ error->errnum, error->errmess);
ro_warn_user("WimpError", error->errmess);
return false;
}
diff --git a/frontends/riscos/help.c b/frontends/riscos/help.c
index b6871c5eb..952b3f2d1 100644
--- a/frontends/riscos/help.c
+++ b/frontends/riscos/help.c
@@ -166,7 +166,8 @@ void ro_gui_interactive_help_request(wimp_message *message)
error = xwimp_get_menu_state(wimp_GIVEN_WINDOW_AND_ICON,
&menu_tree, window, icon);
if (error) {
- LOG("xwimp_get_menu_state: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_get_menu_state: 0x%x: %s",
+ error->errnum, error->errmess);
ro_warn_user("WimpError", error->errmess);
return;
}
@@ -269,7 +270,8 @@ static void ro_gui_interactive_help_broadcast(wimp_message *message,
error = xwimp_send_message(wimp_USER_MESSAGE, (wimp_message *)reply,
reply->sender);
if (error) {
- LOG("xwimp_send_message: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_send_message: 0x%x: %s",
+ error->errnum, error->errmess);
ro_warn_user("WimpError", error->errmess);
}
}
@@ -297,7 +299,10 @@ bool ro_gui_interactive_help_available(void)
error = xtaskmanager_enumerate_tasks(context, &task,
sizeof(taskmanager_task), &context, 0);
if (error) {
- LOG("xtaskmanager_enumerate_tasks: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO,
+ "xtaskmanager_enumerate_tasks: 0x%x: %s",
+ error->errnum,
+ error->errmess);
ro_warn_user("MiscError", error->errmess);
}
@@ -334,7 +339,8 @@ void ro_gui_interactive_help_start(void)
if ((help_start) && (help_start[0])) {
error = xwimp_start_task("<Help$Start>", &task);
if (error) {
- LOG("xwimp_start_tast: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_start_tast: 0x%x: %s",
+ error->errnum, error->errmess);
ro_warn_user("WimpError", error->errmess);
return;
}
@@ -344,7 +350,8 @@ void ro_gui_interactive_help_start(void)
if (!task) {
error = xwimp_start_task("Resources:$.Apps.!Help", &task);
if (error) {
- LOG("xwimp_start_tast: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_start_tast: 0x%x: %s",
+ error->errnum, error->errmess);
ro_warn_user("WimpError", error->errmess);
return;
}
@@ -354,7 +361,10 @@ void ro_gui_interactive_help_start(void)
if (task) {
error = xos_read_monotonic_time(&help_time);
if (error) {
- LOG("xwimp_read_monotonic_time: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO,
+ "xwimp_read_monotonic_time: 0x%x: %s",
+ error->errnum,
+ error->errmess);
ro_warn_user("WimpError", error->errmess);
}
}
diff --git a/frontends/riscos/hotlist.c b/frontends/riscos/hotlist.c
index b055d1bec..b0ed1e2f4 100644
--- a/frontends/riscos/hotlist.c
+++ b/frontends/riscos/hotlist.c
@@ -548,19 +548,20 @@ nserror ro_gui_hotlist_present(void)
return NSERROR_OK;
}
- LOG("xos_cli: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xos_cli: 0x%x: %s", error->errnum,
+ error->errmess);
ro_warn_user("Failed to launch external hotlist: %s",
error->errmess);
}
res = ro_hotlist_init();
if (res == NSERROR_OK) {
- LOG("Presenting");
+ NSLOG(netsurf, INFO, "Presenting");
ro_gui_dialog_open_top(hotlist_window->core.wh,
hotlist_window->core.toolbar,
600, 800);
} else {
- LOG("Failed presenting code %d", res);
+ NSLOG(netsurf, INFO, "Failed presenting code %d", res);
}
return res;
diff --git a/frontends/riscos/iconbar.c b/frontends/riscos/iconbar.c
index 3430ed2f0..23f97258b 100644
--- a/frontends/riscos/iconbar.c
+++ b/frontends/riscos/iconbar.c
@@ -95,7 +95,8 @@ void ro_gui_iconbar_initialise(void)
{ "!netsurf" } } };
error = xwimp_create_icon(&icon, 0);
if (error) {
- LOG("xwimp_create_icon: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_create_icon: 0x%x: %s",
+ error->errnum, error->errmess);
die(error->errmess);
}
@@ -238,7 +239,8 @@ bool ro_gui_iconbar_menu_select(wimp_w w, wimp_i i, wimp_menu *menu,
return true;
case APPLICATION_QUIT:
if (ro_gui_prequit()) {
- LOG("QUIT in response to user request");
+ NSLOG(netsurf, INFO,
+ "QUIT in response to user request");
riscos_done = true;
}
return true;
diff --git a/frontends/riscos/image.c b/frontends/riscos/image.c
index acbe62d98..30cb30096 100644
--- a/frontends/riscos/image.c
+++ b/frontends/riscos/image.c
@@ -142,7 +142,8 @@ bool image_redraw_tinct(osspriteop_id header, int x, int y,
}
if (error) {
- LOG("xtinct_plotscaled%s: 0x%x: %s", (alpha ? "alpha" : ""), error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xtinct_plotscaled%s: 0x%x: %s",
+ (alpha ? "alpha" : ""), error->errnum, error->errmess);
return false;
}
@@ -176,13 +177,16 @@ bool image_redraw_os(osspriteop_id header, int x, int y, int req_width,
colourtrans_CURRENT_PALETTE,
0, colourtrans_GIVEN_SPRITE, 0, 0, &size);
if (error) {
- LOG("xcolourtrans_generate_table_for_sprite: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO,
+ "xcolourtrans_generate_table_for_sprite: 0x%x: %s",
+ error->errnum,
+ error->errmess);
return false;
}
table = calloc(size, sizeof(char));
if (!table) {
- LOG("malloc failed");
+ NSLOG(netsurf, INFO, "malloc failed");
ro_warn_user("NoMemory", 0);
return false;
}
@@ -193,7 +197,10 @@ bool image_redraw_os(osspriteop_id header, int x, int y, int req_width,
colourtrans_CURRENT_PALETTE,
table, colourtrans_GIVEN_SPRITE, 0, 0, 0);
if (error) {
- LOG("xcolourtrans_generate_table_for_sprite: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO,
+ "xcolourtrans_generate_table_for_sprite: 0x%x: %s",
+ error->errnum,
+ error->errmess);
free(table);
return false;
}
@@ -208,7 +215,10 @@ bool image_redraw_os(osspriteop_id header, int x, int y, int req_width,
x, (int)(y - req_height),
8, &f, table);
if (error) {
- LOG("xosspriteop_put_sprite_scaled: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO,
+ "xosspriteop_put_sprite_scaled: 0x%x: %s",
+ error->errnum,
+ error->errmess);
free(table);
return false;
}
diff --git a/frontends/riscos/local_history.c b/frontends/riscos/local_history.c
index f9f1f2e01..bbe6a1d12 100644
--- a/frontends/riscos/local_history.c
+++ b/frontends/riscos/local_history.c
@@ -154,8 +154,8 @@ ro_local_history_tooltip(struct ro_local_history_window *lhw, int x, int y)
/* not over a tree entry => close tooltip window. */
error = xwimp_close_window(dialog_tooltip);
if (error) {
- LOG("xwimp_close_window: 0x%x: %s",
- error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_close_window: 0x%x: %s",
+ error->errnum, error->errmess);
ro_warn_user("WimpError", error->errmess);
return NSERROR_NOMEM;
}
@@ -167,8 +167,8 @@ ro_local_history_tooltip(struct ro_local_history_window *lhw, int x, int y)
nsurl_length(url) > 256 ? 256 : nsurl_length(url),
&width);
if (error) {
- LOG("xwimptextop_string_width: 0x%x: %s",
- error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimptextop_string_width: 0x%x: %s",
+ error->errnum, error->errmess);
ro_warn_user("WimpError", error->errmess);
nsurl_unref(url);
return NSERROR_NOMEM;
@@ -182,8 +182,8 @@ ro_local_history_tooltip(struct ro_local_history_window *lhw, int x, int y)
ic.i = 0;
error = xwimp_get_icon_state(&ic);
if (error) {
- LOG("xwimp_get_icon_state: 0x%x: %s",
- error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_get_icon_state: 0x%x: %s",
+ error->errnum, error->errmess);
ro_warn_user("WimpError", error->errmess);
return NSERROR_NOMEM;
}
@@ -191,8 +191,8 @@ ro_local_history_tooltip(struct ro_local_history_window *lhw, int x, int y)
ic.icon.extent.x0, ic.icon.extent.y0,
width + 16, ic.icon.extent.y1);
if (error) {
- LOG("xwimp_resize_icon: 0x%x: %s",
- error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_resize_icon: 0x%x: %s",
+ error->errnum, error->errmess);
ro_warn_user("WimpError", error->errmess);
return NSERROR_NOMEM;
}
@@ -200,8 +200,8 @@ ro_local_history_tooltip(struct ro_local_history_window *lhw, int x, int y)
state.w = dialog_tooltip;
error = xwimp_get_window_state(&state);
if (error) {
- LOG("xwimp_get_window_state: 0x%x: %s",
- error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_get_window_state: 0x%x: %s",
+ error->errnum, error->errmess);
ro_warn_user("WimpError", error->errmess);
return NSERROR_NOMEM;
}
@@ -211,15 +211,16 @@ ro_local_history_tooltip(struct ro_local_history_window *lhw, int x, int y)
box.y0 = -36;
error = xwimp_set_extent(dialog_tooltip, &box);
if (error) {
- LOG("xwimp_set_extent: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_set_extent: 0x%x: %s",
+ error->errnum, error->errmess);
ro_warn_user("WimpError", error->errmess);
return NSERROR_NOMEM;
}
error = xwimp_get_pointer_info(&pointer);
if (error) {
- LOG("xwimp_get_pointer_info: 0x%x: %s",
- error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_get_pointer_info: 0x%x: %s",
+ error->errnum, error->errmess);
ro_warn_user("WimpError", error->errmess);
return NSERROR_NOMEM;
}
@@ -233,8 +234,8 @@ ro_local_history_tooltip(struct ro_local_history_window *lhw, int x, int y)
/* open window */
error = xwimp_open_window(PTR_WIMP_OPEN(&state));
if (error) {
- LOG("xwimp_open_window: 0x%x: %s",
- error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_open_window: 0x%x: %s",
+ error->errnum, error->errmess);
ro_warn_user("WimpError", error->errmess);
return NSERROR_NOMEM;
}
@@ -363,8 +364,8 @@ ro_local_history_open(struct ro_local_history_window *lhw, wimp_w parent)
box.y0 = -height;
error = xwimp_set_extent(lhw->core.wh, &box);
if (error) {
- LOG("xwimp_set_extent: 0x%x: %s",
- error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_set_extent: 0x%x: %s",
+ error->errnum, error->errmess);
ro_warn_user("WimpError", error->errmess);
return NSERROR_NOMEM;
}
@@ -373,8 +374,8 @@ ro_local_history_open(struct ro_local_history_window *lhw, wimp_w parent)
state.w = lhw->core.wh;
error = xwimp_get_window_state(&state);
if (error) {
- LOG("xwimp_get_window_state: 0x%x: %s",
- error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_get_window_state: 0x%x: %s",
+ error->errnum, error->errmess);
ro_warn_user("WimpError", error->errmess);
return NSERROR_NOMEM;
}
@@ -385,8 +386,8 @@ ro_local_history_open(struct ro_local_history_window *lhw, wimp_w parent)
state.next = wimp_HIDDEN;
error = xwimp_open_window(PTR_WIMP_OPEN(&state));
if (error) {
- LOG("xwimp_open_window: 0x%x: %s",
- error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_open_window: 0x%x: %s",
+ error->errnum, error->errmess);
ro_warn_user("WimpError", error->errmess);
return NSERROR_NOMEM;
}
@@ -403,10 +404,10 @@ nserror ro_gui_local_history_present(wimp_w parent, struct browser_window *bw)
res = ro_local_history_init(bw, &local_history_window);
if (res == NSERROR_OK) {
- LOG("Presenting");
+ NSLOG(netsurf, INFO, "Presenting");
res = ro_local_history_open(local_history_window, parent);
} else {
- LOG("Failed presenting error code %d", res);
+ NSLOG(netsurf, INFO, "Failed presenting error code %d", res);
}
return res;
diff --git a/frontends/riscos/menus.c b/frontends/riscos/menus.c
index d46afa28e..a6e978a6c 100644
--- a/frontends/riscos/menus.c
+++ b/frontends/riscos/menus.c
@@ -232,7 +232,8 @@ void ro_gui_menu_create(wimp_menu *menu, int x, int y, wimp_w w)
current_menu_open = true;
error = xwimp_create_menu(menu, x - 64, y);
if (error) {
- LOG("xwimp_create_menu: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_create_menu: 0x%x: %s",
+ error->errnum, error->errmess);
ro_warn_user("MenuError", error->errmess);
ro_gui_menu_closed();
}
@@ -258,14 +259,16 @@ void ro_gui_popup_menu(wimp_menu *menu, wimp_w w, wimp_i i)
icon_state.i = i;
error = xwimp_get_window_state(&state);
if (error) {
- LOG("xwimp_get_window_state: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_get_window_state: 0x%x: %s",
+ error->errnum, error->errmess);
ro_warn_user("MenuError", error->errmess);
return;
}
error = xwimp_get_icon_state(&icon_state);
if (error) {
- LOG("xwimp_get_icon_state: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_get_icon_state: 0x%x: %s",
+ error->errnum, error->errmess);
ro_warn_user("MenuError", error->errmess);
return;
}
@@ -291,7 +294,8 @@ void ro_gui_menu_destroy(void)
error = xwimp_create_menu(wimp_CLOSE_MENU, 0, 0);
if (error) {
- LOG("xwimp_create_menu: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_create_menu: 0x%x: %s",
+ error->errnum, error->errmess);
ro_warn_user("MenuError", error->errmess);
}
@@ -354,7 +358,8 @@ void ro_gui_menu_selection(wimp_selection *selection)
/* re-open the menu for Adjust clicks */
error = xwimp_get_pointer_info(&pointer);
if (error) {
- LOG("xwimp_get_pointer_info: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_get_pointer_info: 0x%x: %s",
+ error->errnum, error->errmess);
ro_warn_user("WimpError", error->errmess);
ro_gui_menu_closed();
return;
@@ -420,7 +425,8 @@ void ro_gui_menu_warning(wimp_message_menu_warning *warning)
error = xwimp_create_sub_menu(menu_entry->sub_menu,
warning->pos.x, warning->pos.y);
if (error) {
- LOG("xwimp_create_sub_menu: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_create_sub_menu: 0x%x: %s",
+ error->errnum, error->errmess);
ro_warn_user("MenuError", error->errmess);
}
}
@@ -485,7 +491,8 @@ void ro_gui_menu_refresh(wimp_menu *menu)
os_error *error;
error = xwimp_create_menu(current_menu, 0, 0);
if (error) {
- LOG("xwimp_create_menu: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_create_menu: 0x%x: %s",
+ error->errnum, error->errmess);
ro_warn_user("MenuError", error->errmess);
}
}
@@ -851,7 +858,8 @@ int ro_gui_menu_get_checksum(void)
error = xwimp_get_menu_state((wimp_menu_state_flags)0,
&menu_tree, 0, 0);
if (error) {
- LOG("xwimp_get_menu_state: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_get_menu_state: 0x%x: %s",
+ error->errnum, error->errmess);
ro_warn_user("MenuError", error->errmess);
return 0;
}
@@ -894,7 +902,8 @@ bool ro_gui_menu_translate(struct menu_definition *menu)
/* read current alphabet */
error = xosbyte1(osbyte_ALPHABET_NUMBER, 127, 0, &alphabet);
if (error) {
- LOG("failed reading alphabet: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "failed reading alphabet: 0x%x: %s",
+ error->errnum, error->errmess);
/* assume Latin1 */
alphabet = territory_ALPHABET_LATIN1;
}
@@ -909,7 +918,7 @@ bool ro_gui_menu_translate(struct menu_definition *menu)
0, &translated);
if (err != NSERROR_OK) {
assert(err != NSERROR_BAD_ENCODING);
- LOG("utf8_to_enc failed");
+ NSLOG(netsurf, INFO, "utf8_to_enc failed");
return false;
}
@@ -926,7 +935,7 @@ bool ro_gui_menu_translate(struct menu_definition *menu)
0, &translated);
if (err != NSERROR_OK) {
assert(err != NSERROR_BAD_ENCODING);
- LOG("utf8_to_enc failed");
+ NSLOG(netsurf, INFO, "utf8_to_enc failed");
return false;
}
diff --git a/frontends/riscos/message.c b/frontends/riscos/message.c
index 1c54ea0b7..7a0216185 100644
--- a/frontends/riscos/message.c
+++ b/frontends/riscos/message.c
@@ -64,7 +64,8 @@ bool ro_message_send_message(wimp_event_no event, wimp_message *message,
/* send a message */
error = xwimp_send_message(event, message, task);
if (error) {
- LOG("xwimp_send_message: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_send_message: 0x%x: %s",
+ error->errnum, error->errmess);
ro_warn_user("WimpError", error->errmess);
return false;
}
@@ -101,7 +102,10 @@ bool ro_message_send_message_to_window(wimp_event_no event, wimp_message *messag
/* send a message */
error = xwimp_send_message_to_window(event, message, to_w, to_i, to_t);
if (error) {
- LOG("xwimp_send_message_to_window: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO,
+ "xwimp_send_message_to_window: 0x%x: %s",
+ error->errnum,
+ error->errmess);
ro_warn_user("WimpError", error->errmess);
return false;
}
diff --git a/frontends/riscos/mouse.c b/frontends/riscos/mouse.c
index a0cc0e7ce..89184cff3 100644
--- a/frontends/riscos/mouse.c
+++ b/frontends/riscos/mouse.c
@@ -81,7 +81,8 @@ void ro_mouse_poll(void)
error = xwimp_get_pointer_info(&pointer);
if (error) {
- LOG("xwimp_get_pointer_info: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_get_pointer_info: 0x%x: %s",
+ error->errnum, error->errmess);
ro_warn_user("WimpError", error->errmess);
return;
}
@@ -194,7 +195,7 @@ void ro_mouse_track_start(void (*poll_end)(wimp_leaving *leaving, void *data),
ro_mouse_ignore_leaving_event == false)
ro_mouse_poll_end_callback(NULL, ro_mouse_poll_data);
- LOG("Unexpected mouse track termination.");
+ NSLOG(netsurf, INFO, "Unexpected mouse track termination.");
ro_mouse_ignore_leaving_event = false;
ro_mouse_poll_end_callback = NULL;
diff --git a/frontends/riscos/plotters.c b/frontends/riscos/plotters.c
index b459ba1f9..2fbd12aeb 100644
--- a/frontends/riscos/plotters.c
+++ b/frontends/riscos/plotters.c
@@ -79,15 +79,16 @@ ro_plot_draw_path(const draw_path * const path,
error = xcolourtrans_set_gcol(c << 8, 0, os_ACTION_OVERWRITE, 0, 0);
if (error) {
- LOG("xcolourtrans_set_gcol: 0x%x: %s",
- error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xcolourtrans_set_gcol: 0x%x: %s",
+ error->errnum, error->errmess);
return NSERROR_INVALID;
}
error = xdraw_stroke(path, 0, 0, 0, width * 2 * 256,
&line_style, dash_pattern);
if (error) {
- LOG("xdraw_stroke: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xdraw_stroke: 0x%x: %s", error->errnum,
+ error->errmess);
return NSERROR_INVALID;
}
@@ -115,8 +116,8 @@ ro_plot_clip(const struct redraw_context *ctx, const struct rect *clip)
int clip_y1 = ro_plot_origin_y - clip->y1 * 2;
if (clip_x1 < clip_x0 || clip_y0 < clip_y1) {
- LOG("bad clip rectangle %i %i %i %i",
- clip_x0, clip_y0, clip_x1, clip_y1);
+ NSLOG(netsurf, INFO, "bad clip rectangle %i %i %i %i",
+ clip_x0, clip_y0, clip_x1, clip_y1);
return NSERROR_BAD_SIZE;
}
@@ -132,7 +133,8 @@ ro_plot_clip(const struct redraw_context *ctx, const struct rect *clip)
error = xos_writen(buf, 9);
if (error) {
- LOG("xos_writen: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xos_writen: 0x%x: %s", error->errnum,
+ error->errmess);
return NSERROR_INVALID;
}
@@ -173,8 +175,8 @@ ro_plot_arc(const struct redraw_context *ctx,
os_ACTION_OVERWRITE, 0, 0);
if (error) {
- LOG("xcolourtrans_set_gcol: 0x%x: %s",
- error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xcolourtrans_set_gcol: 0x%x: %s",
+ error->errnum, error->errmess);
return NSERROR_INVALID;
}
@@ -188,19 +190,22 @@ ro_plot_arc(const struct redraw_context *ctx,
error = xos_plot(os_MOVE_TO, x, y); /* move to centre */
if (error) {
- LOG("xos_plot: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xos_plot: 0x%x: %s", error->errnum,
+ error->errmess);
return NSERROR_INVALID;
}
error = xos_plot(os_MOVE_TO, sx, sy); /* move to start */
if (error) {
- LOG("xos_plot: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xos_plot: 0x%x: %s", error->errnum,
+ error->errmess);
return NSERROR_INVALID;
}
error = xos_plot(os_PLOT_ARC | os_PLOT_TO, ex, ey); /* arc to end */
if (error) {
- LOG("xos_plot: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xos_plot: 0x%x: %s", error->errnum,
+ error->errmess);
return NSERROR_INVALID;
}
@@ -230,20 +235,24 @@ ro_plot_disc(const struct redraw_context *ctx,
error = xcolourtrans_set_gcol(style->fill_colour << 8, 0,
os_ACTION_OVERWRITE, 0, 0);
if (error) {
- LOG("xcolourtrans_set_gcol: 0x%x: %s",
- error->errnum, error->errmess);
+ NSLOG(netsurf, INFO,
+ "xcolourtrans_set_gcol: 0x%x: %s",
+ error->errnum,
+ error->errmess);
return NSERROR_INVALID;
}
error = xos_plot(os_MOVE_TO,
ro_plot_origin_x + x * 2,
ro_plot_origin_y - y * 2);
if (error) {
- LOG("xos_plot: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xos_plot: 0x%x: %s",
+ error->errnum, error->errmess);
return NSERROR_INVALID;
}
error = xos_plot(os_PLOT_CIRCLE | os_PLOT_BY, radius * 2, 0);
if (error) {
- LOG("xos_plot: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xos_plot: 0x%x: %s",
+ error->errnum, error->errmess);
return NSERROR_INVALID;
}
}
@@ -253,22 +262,26 @@ ro_plot_disc(const struct redraw_context *ctx,
error = xcolourtrans_set_gcol(style->stroke_colour << 8, 0,
os_ACTION_OVERWRITE, 0, 0);
if (error) {
- LOG("xcolourtrans_set_gcol: 0x%x: %s",
- error->errnum, error->errmess);
+ NSLOG(netsurf, INFO,
+ "xcolourtrans_set_gcol: 0x%x: %s",
+ error->errnum,
+ error->errmess);
return NSERROR_INVALID;
}
error = xos_plot(os_MOVE_TO,
ro_plot_origin_x + x * 2,
ro_plot_origin_y - y * 2);
if (error) {
- LOG("xos_plot: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xos_plot: 0x%x: %s",
+ error->errnum, error->errmess);
return NSERROR_INVALID;
}
error = xos_plot(os_PLOT_CIRCLE_OUTLINE | os_PLOT_BY,
radius * 2, 0);
if (error) {
- LOG("xos_plot: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xos_plot: 0x%x: %s",
+ error->errnum, error->errmess);
return NSERROR_INVALID;
}
}
@@ -343,8 +356,10 @@ ro_plot_rectangle(const struct redraw_context *ctx,
colourtrans_USE_ECFS_GCOL,
os_ACTION_OVERWRITE, 0, 0);
if (error) {
- LOG("xcolourtrans_set_gcol: 0x%x: %s",
- error->errnum, error->errmess);
+ NSLOG(netsurf, INFO,
+ "xcolourtrans_set_gcol: 0x%x: %s",
+ error->errnum,
+ error->errmess);
return NSERROR_INVALID;
}
@@ -352,7 +367,8 @@ ro_plot_rectangle(const struct redraw_context *ctx,
ro_plot_origin_x + rect->x0 * 2,
ro_plot_origin_y - rect->y0 * 2 - 1);
if (error) {
- LOG("xos_plot: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xos_plot: 0x%x: %s",
+ error->errnum, error->errmess);
return NSERROR_INVALID;
}
@@ -360,7 +376,8 @@ ro_plot_rectangle(const struct redraw_context *ctx,
ro_plot_origin_x + rect->x1 * 2 - 1,
ro_plot_origin_y - rect->y1 * 2);
if (error) {
- LOG("xos_plot: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xos_plot: 0x%x: %s",
+ error->errnum, error->errmess);
return NSERROR_INVALID;
}
}
@@ -441,13 +458,14 @@ ro_plot_polygon(const struct redraw_context *ctx,
error = xcolourtrans_set_gcol(style->fill_colour << 8,
0, os_ACTION_OVERWRITE, 0, 0);
if (error) {
- LOG("xcolourtrans_set_gcol: 0x%x: %s",
- error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xcolourtrans_set_gcol: 0x%x: %s",
+ error->errnum, error->errmess);
return NSERROR_INVALID;
}
error = xdraw_fill((draw_path *) path, 0, 0, 0);
if (error) {
- LOG("xdraw_fill: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xdraw_fill: 0x%x: %s", error->errnum,
+ error->errmess);
return NSERROR_INVALID;
}
@@ -494,13 +512,13 @@ ro_plot_path(const struct redraw_context *ctx,
}
if (p[0] != PLOTTER_PATH_MOVE) {
- LOG("path doesn't start with a move");
+ NSLOG(netsurf, INFO, "path doesn't start with a move");
goto error;
}
path = malloc(sizeof *path * (n + 10));
if (!path) {
- LOG("out of memory");
+ NSLOG(netsurf, INFO, "out of memory");
goto error;
}
@@ -528,7 +546,7 @@ ro_plot_path(const struct redraw_context *ctx,
path[i + 6] = -p[i + 6] * 2 * 256;
i += 7;
} else {
- LOG("bad path command %f", p[i]);
+ NSLOG(netsurf, INFO, "bad path command %f", p[i]);
goto error;
}
}
@@ -546,15 +564,17 @@ ro_plot_path(const struct redraw_context *ctx,
error = xcolourtrans_set_gcol(pstyle->fill_colour << 8, 0,
os_ACTION_OVERWRITE, 0, 0);
if (error) {
- LOG("xcolourtrans_set_gcol: 0x%x: %s",
- error->errnum, error->errmess);
+ NSLOG(netsurf, INFO,
+ "xcolourtrans_set_gcol: 0x%x: %s",
+ error->errnum,
+ error->errmess);
goto error;
}
error = xdraw_fill((draw_path *) path, 0, &trfm, 0);
if (error) {
- LOG("xdraw_stroke: 0x%x: %s",
- error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xdraw_stroke: 0x%x: %s",
+ error->errnum, error->errmess);
goto error;
}
}
@@ -563,16 +583,18 @@ ro_plot_path(const struct redraw_context *ctx,
error = xcolourtrans_set_gcol(pstyle->stroke_colour << 8, 0,
os_ACTION_OVERWRITE, 0, 0);
if (error) {
- LOG("xcolourtrans_set_gcol: 0x%x: %s",
- error->errnum, error->errmess);
+ NSLOG(netsurf, INFO,
+ "xcolourtrans_set_gcol: 0x%x: %s",
+ error->errnum,
+ error->errmess);
goto error;
}
error = xdraw_stroke((draw_path *) path, 0, &trfm, 0,
width * 2 * 256, &line_style, 0);
if (error) {
- LOG("xdraw_stroke: 0x%x: %s",
- error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xdraw_stroke: 0x%x: %s",
+ error->errnum, error->errmess);
goto error;
}
}
@@ -623,7 +645,7 @@ ro_plot_bitmap(const struct redraw_context *ctx,
buffer = riscos_bitmap_get_buffer(bitmap);
if (!buffer) {
- LOG("bitmap_get_buffer failed");
+ NSLOG(netsurf, INFO, "bitmap_get_buffer failed");
return NSERROR_INVALID;
}
@@ -669,8 +691,10 @@ ro_plot_text(const struct redraw_context *ctx,
fstyle->background << 8, fstyle->foreground << 8,
14, 0, 0, 0);
if (error) {
- LOG("xcolourtrans_set_font_colours: 0x%x: %s",
- error->errnum, error->errmess);
+ NSLOG(netsurf, INFO,
+ "xcolourtrans_set_font_colours: 0x%x: %s",
+ error->errnum,
+ error->errmess);
return NSERROR_INVALID;
}
diff --git a/frontends/riscos/print.c b/frontends/riscos/print.c
index b7ddd4e53..d965baff4 100644
--- a/frontends/riscos/print.c
+++ b/frontends/riscos/print.c
@@ -169,7 +169,8 @@ void ro_gui_print_prepare(struct gui_window *g)
/* Read Printer Driver name */
error = xpdriver_info(0, 0, 0, 0, &desc, 0, 0, 0);
if (error) {
- LOG("xpdriver_info: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xpdriver_info: 0x%x: %s",
+ error->errnum, error->errmess);
printers_exists = false;
}
@@ -306,7 +307,8 @@ void print_send_printsave(struct hlcache_handle *h)
e = xwimp_send_message(wimp_USER_MESSAGE_RECORDED,
(wimp_message *)&m, 0);
if (e) {
- LOG("xwimp_send_message: 0x%x: %s", e->errnum, e->errmess);
+ NSLOG(netsurf, INFO, "xwimp_send_message: 0x%x: %s",
+ e->errnum, e->errmess);
ro_warn_user("WimpError", e->errmess);
ro_print_cleanup();
}
@@ -330,7 +332,8 @@ bool print_send_printtypeknown(wimp_message *m)
m->action = message_PRINT_TYPE_KNOWN;
e = xwimp_send_message(wimp_USER_MESSAGE, m, m->sender);
if (e) {
- LOG("xwimp_send_message: 0x%x: %s", e->errnum, e->errmess);
+ NSLOG(netsurf, INFO, "xwimp_send_message: 0x%x: %s",
+ e->errnum, e->errmess);
ro_warn_user("WimpError", e->errmess);
return false;
}
@@ -436,7 +439,8 @@ bool ro_print_ack(wimp_message *m)
/* read printer driver type */
error = xpdriver_info(&info_type, 0, 0, 0, 0, 0, 0, 0);
if (error) {
- LOG("xpdriver_info: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xpdriver_info: 0x%x: %s",
+ error->errnum, error->errmess);
ro_warn_user("PrintError", error->errmess);
ro_print_cleanup();
return true;
@@ -461,7 +465,8 @@ bool ro_print_ack(wimp_message *m)
error = xwimp_send_message(wimp_USER_MESSAGE_RECORDED, m, m->sender);
if (error) {
- LOG("xwimp_send_message: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_send_message: 0x%x: %s",
+ error->errnum, error->errmess);
ro_warn_user("WimpError", error->errmess);
/* and delete temporary file */
xosfile_delete(m->data.data_xfer.file_name,
@@ -533,7 +538,8 @@ bool print_document(struct gui_window *g, const char *filename)
/* read printer driver features */
error = xpdriver_info(0, 0, 0, &features, 0, 0, 0, 0);
if (error) {
- LOG("xpdriver_info: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xpdriver_info: 0x%x: %s",
+ error->errnum, error->errmess);
ro_warn_user("PrintError", error->errmess);
return false;
}
@@ -541,7 +547,8 @@ bool print_document(struct gui_window *g, const char *filename)
/* read page size */
error = xpdriver_page_size(0, 0, &left, &bottom, &right, &top);
if (error) {
- LOG("xpdriver_page_size: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xpdriver_page_size: 0x%x: %s",
+ error->errnum, error->errmess);
ro_warn_user("PrintError", error->errmess);
return false;
}
@@ -564,7 +571,8 @@ bool print_document(struct gui_window *g, const char *filename)
error = xosfind_openoutw(osfind_NO_PATH | osfind_ERROR_IF_DIR |
osfind_ERROR_IF_ABSENT, filename, 0, &fhandle);
if (error) {
- LOG("xosfind_openoutw: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xosfind_openoutw: 0x%x: %s",
+ error->errnum, error->errmess);
ro_warn_user("PrintError", error->errmess);
return false;
}
@@ -572,7 +580,8 @@ bool print_document(struct gui_window *g, const char *filename)
/* select print job */
error = xpdriver_select_jobw(fhandle, "NetSurf", &old_job);
if (error) {
- LOG("xpdriver_select_jobw: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xpdriver_select_jobw: 0x%x: %s",
+ error->errnum, error->errmess);
ro_warn_user("PrintError", error->errmess);
xosfind_closew(fhandle);
return false;
@@ -632,18 +641,23 @@ bool print_document(struct gui_window *g, const char *filename)
/* give page rectangle */
error = xpdriver_give_rectangle(0, &b, &t, &p, os_COLOUR_WHITE);
if (error) {
- LOG("xpdriver_give_rectangle: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO,
+ "xpdriver_give_rectangle: 0x%x: %s",
+ error->errnum,
+ error->errmess);
error_message = error->errmess;
goto error;
}
- LOG("given rectangle: [(%d, %d), (%d, %d)]", b.x0, b.y0, b.x1, b.y1);
+ NSLOG(netsurf, INFO, "given rectangle: [(%d, %d), (%d, %d)]",
+ b.x0, b.y0, b.x1, b.y1);
/* and redraw the document */
error = xpdriver_draw_page(print_num_copies, &b, 0, 0,
&more, 0);
if (error) {
- LOG("xpdriver_draw_page: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xpdriver_draw_page: 0x%x: %s",
+ error->errnum, error->errmess);
error_message = error->errmess;
goto error;
}
@@ -657,7 +671,9 @@ bool print_document(struct gui_window *g, const char *filename)
.plot = &ro_plotters
};
- LOG("redrawing area: [(%d, %d), (%d, %d)]", b.x0, b.y0, b.x1, b.y1);
+ NSLOG(netsurf, INFO,
+ "redrawing area: [(%d, %d), (%d, %d)]", b.x0,
+ b.y0, b.x1, b.y1);
clip.x0 = (b.x0 - ro_plot_origin_x) / 2;
clip.y0 = (ro_plot_origin_y - b.y1) / 2;
clip.x1 = (b.x1 - ro_plot_origin_x) / 2;
@@ -679,7 +695,10 @@ bool print_document(struct gui_window *g, const char *filename)
error = xpdriver_get_rectangle(&b, &more, 0);
if (error) {
- LOG("xpdriver_get_rectangle: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO,
+ "xpdriver_get_rectangle: 0x%x: %s",
+ error->errnum,
+ error->errmess);
error_message = error->errmess;
goto error;
}
@@ -701,14 +720,16 @@ bool print_document(struct gui_window *g, const char *filename)
error = (os_error *) _swix(PDriver_EndJob, _IN(0), (int) fhandle);
if (error) {
- LOG("xpdriver_end_jobw: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xpdriver_end_jobw: 0x%x: %s",
+ error->errnum, error->errmess);
error_message = error->errmess;
goto error;
}
error = xosfind_closew(fhandle);
if (error) {
- LOG("xosfind_closew: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xosfind_closew: 0x%x: %s",
+ error->errnum, error->errmess);
ro_warn_user("PrintError", error->errmess);
return false;
}
@@ -716,7 +737,10 @@ bool print_document(struct gui_window *g, const char *filename)
if (old_job) {
error = xpdriver_select_jobw(old_job, 0, 0);
if (error) {
- LOG("xpdriver_select_jobw: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO,
+ "xpdriver_select_jobw: 0x%x: %s",
+ error->errnum,
+ error->errmess);
ro_warn_user("PrintError", error->errmess);
/* the printing succeeded anyway */
return true;
@@ -855,11 +879,14 @@ print_fonts_plot_text(const struct redraw_context *ctx,
text, length, 0, 0, print_fonts_callback, 0);
if (code != rufl_OK) {
if (code == rufl_FONT_MANAGER_ERROR) {
- LOG("rufl_paint_callback: rufl_FONT_MANAGER_ERROR: ""0x%x: %s",
- rufl_fm_error->errnum, rufl_fm_error->errmess);
+ NSLOG(netsurf, INFO,
+ "rufl_paint_callback: rufl_FONT_MANAGER_ERROR: ""0x%x: %s",
+ rufl_fm_error->errnum,
+ rufl_fm_error->errmess);
print_fonts_error = rufl_fm_error->errmess;
} else {
- LOG("rufl_paint_callback: 0x%x", code);
+ NSLOG(netsurf, INFO, "rufl_paint_callback: 0x%x",
+ code);
}
return NSERROR_INVALID;
}
@@ -934,18 +961,22 @@ const char *print_declare_fonts(struct hlcache_handle *h)
}
for (i = 0; i != print_fonts_count; ++i) {
- LOG("%u %s", i, print_fonts_list[i]);
+ NSLOG(netsurf, INFO, "%u %s", i, print_fonts_list[i]);
error = xpdriver_declare_font(0, print_fonts_list[i],
pdriver_KERNED);
if (error) {
- LOG("xpdriver_declare_font: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO,
+ "xpdriver_declare_font: 0x%x: %s",
+ error->errnum,
+ error->errmess);
error_message = error->errmess;
goto end;
}
}
error = xpdriver_declare_font(0, 0, 0);
if (error) {
- LOG("xpdriver_declare_font: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xpdriver_declare_font: 0x%x: %s",
+ error->errnum, error->errmess);
error_message = error->errmess;
goto end;
}
diff --git a/frontends/riscos/query.c b/frontends/riscos/query.c
index 1d7cf5120..49aea6321 100644
--- a/frontends/riscos/query.c
+++ b/frontends/riscos/query.c
@@ -175,7 +175,7 @@ query_id query_user_xy(const char *query, const char *detail,
err = utf8_to_local_encoding(yes, 0, &local_text);
if (err != NSERROR_OK) {
assert(err != NSERROR_BAD_ENCODING);
- LOG("utf8_to_local_encoding_failed");
+ NSLOG(netsurf, INFO, "utf8_to_local_encoding_failed");
local_text = NULL;
}
@@ -191,7 +191,8 @@ query_id query_user_xy(const char *query, const char *detail,
error = xwimptextop_string_width(icn->data.indirected_text.text, len, &width);
if (error) {
- LOG("xwimptextop_string_width: 0x%x:%s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimptextop_string_width: 0x%x:%s",
+ error->errnum, error->errmess);
width = len * 16;
}
if (!query_yes_width) query_yes_width = icn->extent.x1 - icn->extent.x0;
@@ -204,7 +205,7 @@ query_id query_user_xy(const char *query, const char *detail,
err = utf8_to_local_encoding(no, 0, &local_text);
if (err != NSERROR_OK) {
assert(err != NSERROR_BAD_ENCODING);
- LOG("utf8_to_local_encoding_failed");
+ NSLOG(netsurf, INFO, "utf8_to_local_encoding_failed");
local_text = NULL;
}
@@ -222,7 +223,8 @@ query_id query_user_xy(const char *query, const char *detail,
icn->extent.x1 = tx - 16;
error = xwimptextop_string_width(icn->data.indirected_text.text, len, &width);
if (error) {
- LOG("xwimptextop_string_width: 0x%x:%s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimptextop_string_width: 0x%x:%s",
+ error->errnum, error->errmess);
width = len * 16;
}
width += 28;
@@ -263,7 +265,8 @@ query_id query_user_xy(const char *query, const char *detail,
error = xwimp_set_caret_position(qw->window, (wimp_i)-1, 0, 0, 1 << 25, -1);
if (error) {
- LOG("xwimp_get_caret_position: 0x%x : %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_get_caret_position: 0x%x : %s",
+ error->errnum, error->errmess);
ro_warn_user("WimpError", error->errmess);
}
@@ -307,7 +310,10 @@ void ro_gui_query_window_bring_to_front(query_id id)
error = xwimp_set_caret_position(qw->window, (wimp_i)-1, 0, 0, 1 << 25, -1);
if (error) {
- LOG("xwimp_get_caret_position: 0x%x : %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO,
+ "xwimp_get_caret_position: 0x%x : %s",
+ error->errnum,
+ error->errmess);
ro_warn_user("WimpError", error->errmess);
}
}
@@ -327,7 +333,8 @@ void ro_gui_query_close(wimp_w w)
ro_gui_dialog_close(w);
error = xwimp_delete_window(qw->window);
if (error) {
- LOG("xwimp_delete_window: 0x%x:%s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_delete_window: 0x%x:%s",
+ error->errnum, error->errmess);
ro_warn_user("WimpError", error->errmess);
}
ro_gui_wimp_event_finalise(w);
diff --git a/frontends/riscos/save.c b/frontends/riscos/save.c
index bed0f5dd1..76ce6d3e5 100644
--- a/frontends/riscos/save.c
+++ b/frontends/riscos/save.c
@@ -166,7 +166,8 @@ wimp_w ro_gui_saveas_create(const char *template_name)
error = xosmodule_alloc(area_size, (void **) &area);
if (error) {
- LOG("xosmodule_alloc: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xosmodule_alloc: 0x%x: %s",
+ error->errnum, error->errmess);
xwimp_close_template();
die(error->errmess);
} else {
@@ -176,7 +177,10 @@ wimp_w ro_gui_saveas_create(const char *template_name)
error = xosspriteop_clear_sprites(osspriteop_USER_AREA, saveas_area);
if (error) {
- LOG("xosspriteop_clear_sprites: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO,
+ "xosspriteop_clear_sprites: 0x%x: %s",
+ error->errnum,
+ error->errmess);
ro_warn_user("MiscError", error->errmess);
xosmodule_free(saveas_area);
@@ -192,7 +196,8 @@ wimp_w ro_gui_saveas_create(const char *template_name)
/* create window */
error = xwimp_create_window(window, &w);
if (error) {
- LOG("xwimp_create_window: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_create_window: 0x%x: %s",
+ error->errnum, error->errmess);
xwimp_close_template();
die(error->errmess);
}
@@ -212,7 +217,8 @@ void ro_gui_saveas_quit(void)
if (saveas_area) {
os_error *error = xosmodule_free(saveas_area);
if (error) {
- LOG("xosmodule_free: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xosmodule_free: 0x%x: %s",
+ error->errnum, error->errmess);
ro_warn_user("MiscError", error->errmess);
}
saveas_area = NULL;
@@ -239,14 +245,14 @@ ro_gui_save_create_thumbnail(struct hlcache_handle *h, const char *name)
bitmap = riscos_bitmap_create(34, 34, BITMAP_NEW | BITMAP_OPAQUE | BITMAP_CLEAR_MEMORY);
if (!bitmap) {
- LOG("Thumbnail initialisation failed.");
+ NSLOG(netsurf, INFO, "Thumbnail initialisation failed.");
return false;
}
riscos_bitmap_render(bitmap, h);
area = riscos_bitmap_convert_8bpp(bitmap);
riscos_bitmap_destroy(bitmap);
if (!area) {
- LOG("Thumbnail conversion failed.");
+ NSLOG(netsurf, INFO, "Thumbnail conversion failed.");
return false;
}
@@ -391,7 +397,10 @@ ro_gui_save_set_state(struct hlcache_handle *h, gui_save_type save_type,
}
if (error) {
- LOG("ro_gui_wimp_get_sprite: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO,
+ "ro_gui_wimp_get_sprite: 0x%x: %s",
+ error->errnum,
+ error->errmess);
ro_warn_user("MiscError", error->errmess);
} else {
/* the sprite area should always be large enough for
@@ -501,7 +510,8 @@ static void ro_gui_save_drag_end(wimp_dragged *drag, void *data)
error = xwimp_get_pointer_info(&pointer);
if (error) {
- LOG("xwimp_get_pointer_info: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_get_pointer_info: 0x%x: %s",
+ error->errnum, error->errmess);
ro_warn_user("WimpError", error->errmess);
return;
}
@@ -627,7 +637,8 @@ static void ro_gui_save_done(void)
error = xwimp_send_message(wimp_USER_MESSAGE, message,
message->sender);
if (error) {
- LOG("xwimp_send_message: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_send_message: 0x%x: %s",
+ error->errnum, error->errmess);
ro_warn_user("SaveError", error->errmess);
}
}
@@ -667,7 +678,10 @@ static void ro_gui_save_done(void)
ro_gui_dialog_close(dialog_saveas);
error = xwimp_create_menu(wimp_CLOSE_MENU, 0, 0);
if (error) {
- LOG("xwimp_create_menu: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO,
+ "xwimp_create_menu: 0x%x: %s",
+ error->errnum,
+ error->errmess);
ro_warn_user("MenuError", error->errmess);
}
}
@@ -770,8 +784,8 @@ static void ro_gui_save_set_file_type(const char *path, lwc_string *mime_type)
error = xosfile_set_type(path, rotype);
if (error != NULL) {
- LOG("xosfile_set_type: 0x%x: %s",
- error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xosfile_set_type: 0x%x: %s",
+ error->errnum, error->errmess);
}
}
@@ -798,7 +812,8 @@ static bool ro_gui_save_complete(struct hlcache_handle *h, char *path)
/* Create dir */
error = xosfile_create_dir(path, 0);
if (error) {
- LOG("xosfile_create_dir: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xosfile_create_dir: 0x%x: %s",
+ error->errnum, error->errmess);
ro_warn_user("SaveError", error->errmess);
return false;
}
@@ -807,7 +822,7 @@ static bool ro_gui_save_complete(struct hlcache_handle *h, char *path)
snprintf(buf, sizeof buf, "%s.!Run", path);
fp = fopen(buf, "w");
if (!fp) {
- LOG("fopen(): errno = %i", errno);
+ NSLOG(netsurf, INFO, "fopen(): errno = %i", errno);
ro_warn_user("SaveError", strerror(errno));
return false;
}
@@ -816,7 +831,8 @@ static bool ro_gui_save_complete(struct hlcache_handle *h, char *path)
fclose(fp);
error = xosfile_set_type(buf, 0xfeb);
if (error) {
- LOG("xosfile_set_type: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xosfile_set_type: 0x%x: %s",
+ error->errnum, error->errmess);
ro_warn_user("SaveError", error->errmess);
return false;
}
@@ -825,7 +841,8 @@ static bool ro_gui_save_complete(struct hlcache_handle *h, char *path)
snprintf(buf, sizeof buf, "%s.!RunImage", path);
fp = fopen(buf, "w");
if (!fp) {
- LOG("Creating !RunImage failed: errno = %i", errno);
+ NSLOG(netsurf, INFO, "Creating !RunImage failed: errno = %i",
+ errno);
} else {
fclose(fp);
}
@@ -851,7 +868,10 @@ static bool ro_gui_save_complete(struct hlcache_handle *h, char *path)
error = xosspriteop_save_sprite_file(osspriteop_NAME, saveas_area, buf);
if (error) {
- LOG("xosspriteop_save_sprite_file: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO,
+ "xosspriteop_save_sprite_file: 0x%x: %s",
+ error->errnum,
+ error->errmess);
ro_warn_user("SaveError", error->errmess);
return false;
}
@@ -897,7 +917,10 @@ static bool ro_gui_save_object_native(struct hlcache_handle *h, char *path)
(byte *) source_data,
(byte *) source_data + source_size);
if (error != NULL) {
- LOG("xosfile_save_stamped: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO,
+ "xosfile_save_stamped: 0x%x: %s",
+ error->errnum,
+ error->errmess);
ro_warn_user("SaveError", error->errmess);
return false;
}
@@ -947,7 +970,8 @@ ro_gui_save_content(struct hlcache_handle *h, char *path, bool force_overwrite)
error = xosfile_read_stamped(path, &obj_type,
NULL, NULL, NULL, NULL, NULL);
if (error) {
- LOG("xosfile_read_stamped: 0x%x:%s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xosfile_read_stamped: 0x%x:%s",
+ error->errnum, error->errmess);
ro_warn_user("SaveError", error->errmess);
return false;
}
@@ -1003,7 +1027,10 @@ ro_gui_save_content(struct hlcache_handle *h, char *path, bool force_overwrite)
(byte *) source_data,
(byte *) source_data + source_size);
if (error) {
- LOG("xosfile_save_stamped: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO,
+ "xosfile_save_stamped: 0x%x: %s",
+ error->errnum,
+ error->errmess);
ro_warn_user("SaveError", error->errmess);
return false;
}
@@ -1029,14 +1056,20 @@ ro_gui_save_content(struct hlcache_handle *h, char *path, bool force_overwrite)
return false;
error = xosfile_set_type(path, 0xfaf);
if (error)
- LOG("xosfile_set_type: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO,
+ "xosfile_set_type: 0x%x: %s",
+ error->errnum,
+ error->errmess);
break;
case GUI_SAVE_HISTORY_EXPORT_HTML:
if (global_history_export(path, NULL) != NSERROR_OK)
return false;
error = xosfile_set_type(path, 0xfaf);
if (error)
- LOG("xosfile_set_type: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO,
+ "xosfile_set_type: 0x%x: %s",
+ error->errnum,
+ error->errmess);
break;
case GUI_SAVE_TEXT_SELECTION:
@@ -1056,7 +1089,10 @@ ro_gui_save_content(struct hlcache_handle *h, char *path, bool force_overwrite)
return ro_gui_save_clipboard(path);
default:
- LOG("Unexpected content type: %d, path %s", gui_save_current_type, path);
+ NSLOG(netsurf, INFO,
+ "Unexpected content type: %d, path %s",
+ gui_save_current_type,
+ path);
return false;
}
return true;
@@ -1121,7 +1157,8 @@ void gui_drag_save_object(struct gui_window *g,
error = xwimp_get_pointer_info(&pointer);
if (error) {
- LOG("xwimp_get_pointer_info: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_get_pointer_info: 0x%x: %s",
+ error->errnum, error->errmess);
ro_warn_user("WimpError", error->errmess);
return;
}
@@ -1158,7 +1195,8 @@ void gui_drag_save_selection(struct gui_window *g, const char *selection)
error = xwimp_get_pointer_info(&pointer);
if (error) {
- LOG("xwimp_get_pointer_info: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_get_pointer_info: 0x%x: %s",
+ error->errnum, error->errmess);
ro_warn_user("WimpError", error->errmess);
return;
}
@@ -1210,8 +1248,8 @@ void ro_gui_drag_save_link(gui_save_type save_type, const nsurl *url,
error = xwimp_get_pointer_info(&pointer);
if (error) {
- LOG("xwimp_get_pointer_info: 0x%x: %s",
- error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_get_pointer_info: 0x%x: %s",
+ error->errnum, error->errmess);
ro_warn_user("WimpError", error->errmess);
return;
}
@@ -1252,7 +1290,10 @@ void ro_gui_drag_icon(int x, int y, const char *sprite)
saveas_area, (osspriteop_id)sprite, NULL);
if (error) {
if (error->errnum != error_SPRITE_OP_DOESNT_EXIST) {
- LOG("xosspriteop_select_sprite: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO,
+ "xosspriteop_select_sprite: 0x%x: %s",
+ error->errnum,
+ error->errmess);
ro_warn_user("MiscError", error->errmess);
}
}
@@ -1272,7 +1313,8 @@ void ro_gui_drag_icon(int x, int y, const char *sprite)
return;
}
- LOG("xdragasprite_start: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xdragasprite_start: 0x%x: %s",
+ error->errnum, error->errmess);
}
drag.type = wimp_DRAG_USER_FIXED;
@@ -1285,7 +1327,8 @@ void ro_gui_drag_icon(int x, int y, const char *sprite)
error = xwimp_drag_box(&drag);
if (error) {
- LOG("xwimp_drag_box: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_drag_box: 0x%x: %s",
+ error->errnum, error->errmess);
ro_warn_user("DragError", error->errmess);
} else {
dragbox_active = true;
@@ -1323,14 +1366,20 @@ void ro_gui_drag_box_cancel(void)
if (using_dragasprite) {
error = xdragasprite_stop();
if (error) {
- LOG("xdragasprite_stop: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO,
+ "xdragasprite_stop: 0x%x: %s",
+ error->errnum,
+ error->errmess);
ro_warn_user("WimpError", error->errmess);
}
}
else {
error = xwimp_drag_box(NULL);
if (error) {
- LOG("xwimp_drag_box: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO,
+ "xwimp_drag_box: 0x%x: %s",
+ error->errnum,
+ error->errmess);
ro_warn_user("WimpError", error->errmess);
}
}
@@ -1384,7 +1433,8 @@ void ro_gui_save_datasave_ack(wimp_message *message)
default:
if (!gui_save_content) {
- LOG("unexpected DataSaveAck: gui_save_content not set");
+ NSLOG(netsurf, INFO,
+ "unexpected DataSaveAck: gui_save_content not set");
return;
}
break;
diff --git a/frontends/riscos/save_draw.c b/frontends/riscos/save_draw.c
index 1e0bc1ec6..9ee730434 100644
--- a/frontends/riscos/save_draw.c
+++ b/frontends/riscos/save_draw.c
@@ -54,7 +54,7 @@ static int ro_save_draw_height;
*/
static nserror ro_save_draw_error(pencil_code code)
{
- LOG("code %i", code);
+ NSLOG(netsurf, INFO, "code %i", code);
switch (code) {
case pencil_OK:
@@ -333,13 +333,13 @@ ro_save_draw_path(const struct redraw_context *ctx,
return NSERROR_OK;
if (p[0] != PLOTTER_PATH_MOVE) {
- LOG("path doesn't start with a move");
+ NSLOG(netsurf, INFO, "path doesn't start with a move");
return NSERROR_INVALID;
}
path = malloc(sizeof *path * (n + 10));
if (!path) {
- LOG("out of memory");
+ NSLOG(netsurf, INFO, "out of memory");
return NSERROR_INVALID;
}
@@ -389,7 +389,7 @@ ro_save_draw_path(const struct redraw_context *ctx,
i += 7;
empty_path = false;
} else {
- LOG("bad path command %f", p[i]);
+ NSLOG(netsurf, INFO, "bad path command %f", p[i]);
free(path);
return NSERROR_INVALID;
}
@@ -624,8 +624,8 @@ bool save_as_draw(struct hlcache_handle *h, const char *path)
(byte *) drawfile_buffer,
(byte *) drawfile_buffer + drawfile_size);
if (error) {
- LOG("xosfile_save_stamped failed: 0x%x: %s",
- error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xosfile_save_stamped failed: 0x%x: %s",
+ error->errnum, error->errmess);
ro_warn_user("SaveError", error->errmess);
pencil_free(ro_save_draw_diagram);
return false;
diff --git a/frontends/riscos/schedule.c b/frontends/riscos/schedule.c
index 54308b7a9..cb44d906d 100644
--- a/frontends/riscos/schedule.c
+++ b/frontends/riscos/schedule.c
@@ -108,7 +108,7 @@ nserror riscos_schedule(int t, void (*callback)(void *p), void *p)
entry = malloc(sizeof *entry);
if (!entry) {
- LOG("malloc failed");
+ NSLOG(netsurf, INFO, "malloc failed");
return NSERROR_NOMEM;
}
diff --git a/frontends/riscos/sslcert.c b/frontends/riscos/sslcert.c
index 85b84456e..4d81268f4 100644
--- a/frontends/riscos/sslcert.c
+++ b/frontends/riscos/sslcert.c
@@ -82,14 +82,14 @@ static void ro_gui_cert_release_window(struct ro_cert_window *certw)
error = xwimp_delete_window(certw->wh);
if (error) {
- LOG("xwimp_delete_window: 0x%x:%s",
- error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_delete_window: 0x%x:%s",
+ error->errnum, error->errmess);
}
error = xwimp_delete_window(certw->core.wh);
if (error) {
- LOG("xwimp_delete_window: 0x%x:%s",
- error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_delete_window: 0x%x:%s",
+ error->errnum, error->errmess);
}
free(certw);
@@ -165,16 +165,16 @@ static nserror cert_attach_pane(wimp_w parent, wimp_w pane)
winfo.w = pane;
error = xwimp_get_window_info_header_only(&winfo);
if (error) {
- LOG("xwimp_get_window_info: 0x%x: %s",
- error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_get_window_info: 0x%x: %s",
+ error->errnum, error->errmess);
return NSERROR_INIT_FAILED;
}
wstate.w = parent;
error = xwimp_get_window_state(&wstate);
if (error) {
- LOG("xwimp_get_window_state: 0x%x: %s",
- error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_get_window_state: 0x%x: %s",
+ error->errnum, error->errmess);
return NSERROR_INIT_FAILED;
}
@@ -182,8 +182,8 @@ static nserror cert_attach_pane(wimp_w parent, wimp_w pane)
istate.i = ICON_SSL_PANE;
error = xwimp_get_icon_state(&istate);
if (error) {
- LOG("xwimp_get_icon_state: 0x%x: %s",
- error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_get_icon_state: 0x%x: %s",
+ error->errnum, error->errmess);
return NSERROR_INIT_FAILED;
}
@@ -211,8 +211,8 @@ static nserror cert_attach_pane(wimp_w parent, wimp_w pane)
if (set_extent) {
error = xwimp_set_extent(pane, &(winfo.extent));
if (error) {
- LOG("xwimp_set_extent: 0x%x: %s",
- error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_set_extent: 0x%x: %s",
+ error->errnum, error->errmess);
return NSERROR_INIT_FAILED;
}
}
@@ -225,8 +225,8 @@ static nserror cert_attach_pane(wimp_w parent, wimp_w pane)
wimp_CHILD_LINKS_PARENT_VISIBLE_BOTTOM_OR_LEFT << wimp_CHILD_LS_EDGE_SHIFT |
wimp_CHILD_LINKS_PARENT_VISIBLE_BOTTOM_OR_LEFT << wimp_CHILD_RS_EDGE_SHIFT);
if (error) {
- LOG("xwimp_open_window_nested: 0x%x: %s",
- error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_open_window_nested: 0x%x: %s",
+ error->errnum, error->errmess);
return NSERROR_INIT_FAILED;
}
@@ -336,8 +336,8 @@ gui_cert_verify(nsurl *url,
/* Create the SSL window */
error = xwimp_create_window(dialog_cert_template, &ncwin->wh);
if (error) {
- LOG("xwimp_create_window: 0x%x: %s",
- error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_create_window: 0x%x: %s",
+ error->errnum, error->errmess);
free(ncwin);
return NSERROR_INIT_FAILED;
}
@@ -345,8 +345,8 @@ gui_cert_verify(nsurl *url,
/* create ssl viewer pane window */
error = xwimp_create_window(cert_tree_template, &ncwin->core.wh);
if (error) {
- LOG("xwimp_create_window: 0x%x: %s",
- error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_create_window: 0x%x: %s",
+ error->errnum, error->errmess);
free(ncwin);
return NSERROR_INIT_FAILED;
}
diff --git a/frontends/riscos/textarea.c b/frontends/riscos/textarea.c
index d9872927c..6f41c640b 100644
--- a/frontends/riscos/textarea.c
+++ b/frontends/riscos/textarea.c
@@ -138,7 +138,7 @@ uintptr_t ro_textarea_create(wimp_w parent, wimp_i icon, unsigned int flags,
ret = malloc(sizeof(struct text_area));
if (!ret) {
- LOG("malloc failed");
+ NSLOG(netsurf, INFO, "malloc failed");
return 0;
}
@@ -148,7 +148,7 @@ uintptr_t ro_textarea_create(wimp_w parent, wimp_i icon, unsigned int flags,
ret->flags = flags;
ret->text = malloc(64);
if (!ret->text) {
- LOG("malloc failed");
+ NSLOG(netsurf, INFO, "malloc failed");
free(ret);
return 0;
}
@@ -160,7 +160,7 @@ uintptr_t ro_textarea_create(wimp_w parent, wimp_i icon, unsigned int flags,
// ret->selection_end = (unsigned int)-1;
ret->font_family = strdup(font_family ? font_family : "Corpus");
if (!ret->font_family) {
- LOG("strdup failed");
+ NSLOG(netsurf, INFO, "strdup failed");
free(ret->text);
free(ret);
return 0;
@@ -181,7 +181,8 @@ uintptr_t ro_textarea_create(wimp_w parent, wimp_i icon, unsigned int flags,
text_area_definition.title_fg = wimp_COLOUR_BLACK;
error = xwimp_create_window(&text_area_definition, &ret->window);
if (error) {
- LOG("xwimp_create_window: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_create_window: 0x%x: %s",
+ error->errnum, error->errmess);
free(ret->font_family);
free(ret->text);
free(ret);
@@ -228,7 +229,8 @@ bool ro_textarea_update(uintptr_t self)
state.w = ta->parent;
error = xwimp_get_window_state(&state);
if (error) {
- LOG("xwimp_get_window_state: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_get_window_state: 0x%x: %s",
+ error->errnum, error->errmess);
return false;
}
@@ -236,7 +238,8 @@ bool ro_textarea_update(uintptr_t self)
istate.i = ta->icon;
error = xwimp_get_icon_state(&istate);
if (error) {
- LOG("xwimp_get_icon_state: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_get_icon_state: 0x%x: %s",
+ error->errnum, error->errmess);
return false;
}
@@ -267,7 +270,8 @@ bool ro_textarea_update(uintptr_t self)
error = xwimp_set_extent(ta->window, &extent);
if (error) {
- LOG("xwimp_set_extent: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_set_extent: 0x%x: %s",
+ error->errnum, error->errmess);
return false;
}
@@ -282,7 +286,8 @@ bool ro_textarea_update(uintptr_t self)
wimp_CHILD_LINKS_PARENT_VISIBLE_BOTTOM_OR_LEFT
<< wimp_CHILD_RS_EDGE_SHIFT);
if (error) {
- LOG("xwimp_open_window_nested: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_open_window_nested: 0x%x: %s",
+ error->errnum, error->errmess);
return false;
}
@@ -307,7 +312,8 @@ void ro_textarea_destroy(uintptr_t self)
error = xwimp_delete_window(ta->window);
if (error) {
- LOG("xwimp_delete_window: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_delete_window: 0x%x: %s",
+ error->errnum, error->errmess);
}
ro_gui_wimp_event_finalise(ta->window);
@@ -331,14 +337,14 @@ bool ro_textarea_set_text(uintptr_t self, const char *text)
ta = (struct text_area *)self;
if (!ta || ta->magic != MAGIC) {
- LOG("magic doesn't match");
+ NSLOG(netsurf, INFO, "magic doesn't match");
return true;
}
if (len >= ta->text_alloc) {
char *temp = realloc(ta->text, len + 64);
if (!temp) {
- LOG("realloc failed");
+ NSLOG(netsurf, INFO, "realloc failed");
return false;
}
ta->text = temp;
@@ -368,7 +374,7 @@ int ro_textarea_get_text(uintptr_t self, char *buf, unsigned int len)
ta = (struct text_area *)self;
if (!ta || ta->magic != MAGIC) {
- LOG("magic doesn't match");
+ NSLOG(netsurf, INFO, "magic doesn't match");
return -1;
}
@@ -378,7 +384,7 @@ int ro_textarea_get_text(uintptr_t self, char *buf, unsigned int len)
}
if (len < ta->text_len) {
- LOG("buffer too small");
+ NSLOG(netsurf, INFO, "buffer too small");
return -1;
}
@@ -403,7 +409,7 @@ void ro_textarea_insert_text(uintptr_t self, unsigned int index,
ta = (struct text_area *)self;
if (!ta || ta->magic != MAGIC) {
- LOG("magic doesn't match");
+ NSLOG(netsurf, INFO, "magic doesn't match");
return;
}
@@ -420,7 +426,7 @@ void ro_textarea_insert_text(uintptr_t self, unsigned int index,
if (b_len + ta->text_len >= ta->text_alloc) {
char *temp = realloc(ta->text, b_len + ta->text_len + 64);
if (!temp) {
- LOG("realloc failed");
+ NSLOG(netsurf, INFO, "realloc failed");
return;
}
@@ -457,7 +463,7 @@ void ro_textarea_replace_text(uintptr_t self, unsigned int start,
ta = (struct text_area *)self;
if (!ta || ta->magic != MAGIC) {
- LOG("magic doesn't match");
+ NSLOG(netsurf, INFO, "magic doesn't match");
return;
}
@@ -491,7 +497,7 @@ void ro_textarea_replace_text(uintptr_t self, unsigned int start,
char *temp = realloc(ta->text,
b_len + ta->text_len - (b_end - b_start) + 64);
if (!temp) {
- LOG("realloc failed");
+ NSLOG(netsurf, INFO, "realloc failed");
return;
}
@@ -532,7 +538,7 @@ void ro_textarea_set_caret(uintptr_t self, unsigned int caret)
ta = (struct text_area *)self;
if (!ta || ta->magic != MAGIC) {
- LOG("magic doesn't match");
+ NSLOG(netsurf, INFO, "magic doesn't match");
return;
}
@@ -574,9 +580,10 @@ void ro_textarea_set_caret(uintptr_t self, unsigned int caret)
b_off - ta->lines[ta->caret_pos.line].b_start, &x);
if (code != rufl_OK) {
if (code == rufl_FONT_MANAGER_ERROR)
- LOG("rufl_width: 0x%x: %s", rufl_fm_error->errnum, rufl_fm_error->errmess);
+ NSLOG(netsurf, INFO, "rufl_width: 0x%x: %s",
+ rufl_fm_error->errnum, rufl_fm_error->errmess);
else
- LOG("rufl_width: 0x%x", code);
+ NSLOG(netsurf, INFO, "rufl_width: 0x%x", code);
return;
}
@@ -585,7 +592,8 @@ void ro_textarea_set_caret(uintptr_t self, unsigned int caret)
ta->line_height / 4 + ta->line_spacing,
os_line_height.y, -1);
if (error) {
- LOG("xwimp_set_caret_position: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_set_caret_position: 0x%x: %s",
+ error->errnum, error->errmess);
return;
}
}
@@ -609,7 +617,7 @@ void ro_textarea_set_caret_xy(uintptr_t self, int x, int y)
ta = (struct text_area *)self;
if (!ta || ta->magic != MAGIC) {
- LOG("magic doesn't match");
+ NSLOG(netsurf, INFO, "magic doesn't match");
return;
}
@@ -623,7 +631,8 @@ void ro_textarea_set_caret_xy(uintptr_t self, int x, int y)
state.w = ta->window;
error = xwimp_get_window_state(&state);
if (error) {
- LOG("xwimp_get_window_state: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_get_window_state: 0x%x: %s",
+ error->errnum, error->errmess);
return;
}
@@ -644,9 +653,10 @@ void ro_textarea_set_caret_xy(uintptr_t self, int x, int y)
x, &b_off, &x);
if (code != rufl_OK) {
if (code == rufl_FONT_MANAGER_ERROR)
- LOG("rufl_x_to_offset: 0x%x: %s", rufl_fm_error->errnum, rufl_fm_error->errmess);
+ NSLOG(netsurf, INFO, "rufl_x_to_offset: 0x%x: %s",
+ rufl_fm_error->errnum, rufl_fm_error->errmess);
else
- LOG("rufl_x_to_offset: 0x%x", code);
+ NSLOG(netsurf, INFO, "rufl_x_to_offset: 0x%x", code);
return;
}
@@ -670,7 +680,7 @@ unsigned int ro_textarea_get_caret(uintptr_t self)
ta = (struct text_area *)self;
if (!ta || ta->magic != MAGIC) {
- LOG("magic doesn't match");
+ NSLOG(netsurf, INFO, "magic doesn't match");
return -1;
}
@@ -711,7 +721,7 @@ void ro_textarea_reflow(struct text_area *ta, unsigned int line)
ta->lines =
malloc(LINE_CHUNK_SIZE * sizeof(struct line_info));
if (!ta->lines) {
- LOG("malloc failed");
+ NSLOG(netsurf, INFO, "malloc failed");
return;
}
}
@@ -734,9 +744,13 @@ void ro_textarea_reflow(struct text_area *ta, unsigned int line)
&b_off, &x);
if (code != rufl_OK) {
if (code == rufl_FONT_MANAGER_ERROR)
- LOG("rufl_x_to_offset: 0x%x: %s", rufl_fm_error->errnum, rufl_fm_error->errmess);
+ NSLOG(netsurf, INFO,
+ "rufl_x_to_offset: 0x%x: %s",
+ rufl_fm_error->errnum,
+ rufl_fm_error->errmess);
else
- LOG("rufl_x_to_offset: 0x%x", code);
+ NSLOG(netsurf, INFO,
+ "rufl_x_to_offset: 0x%x", code);
return;
}
@@ -745,7 +759,7 @@ void ro_textarea_reflow(struct text_area *ta, unsigned int line)
(line_count + LINE_CHUNK_SIZE) *
sizeof(struct line_info));
if (!temp) {
- LOG("realloc failed");
+ NSLOG(netsurf, INFO, "realloc failed");
return;
}
@@ -809,7 +823,8 @@ void ro_textarea_reflow(struct text_area *ta, unsigned int line)
error = xwimp_set_extent(ta->window, &extent);
if (error) {
- LOG("xwimp_set_extent: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_set_extent: 0x%x: %s",
+ error->errnum, error->errmess);
return;
}
@@ -826,7 +841,10 @@ void ro_textarea_reflow(struct text_area *ta, unsigned int line)
error = xwimp_get_window_state_and_nesting(&state,
&parent, &linkage);
if (error) {
- LOG("xwimp_get_window_state_and_nesting: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO,
+ "xwimp_get_window_state_and_nesting: 0x%x: %s",
+ error->errnum,
+ error->errmess);
return;
}
@@ -839,7 +857,10 @@ void ro_textarea_reflow(struct text_area *ta, unsigned int line)
state.w = ta->window;
error = xwimp_get_window_state(&state);
if (error) {
- LOG("xwimp_get_window_state: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO,
+ "xwimp_get_window_state: 0x%x: %s",
+ error->errnum,
+ error->errmess);
return;
}
@@ -853,7 +874,10 @@ void ro_textarea_reflow(struct text_area *ta, unsigned int line)
error = xwimp_open_window_nested(PTR_WIMP_OPEN(&state),
parent, linkage);
if (error) {
- LOG("xwimp_open_window_nested: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO,
+ "xwimp_open_window_nested: 0x%x: %s",
+ error->errnum,
+ error->errmess);
return;
}
@@ -1009,7 +1033,10 @@ bool ro_textarea_key_press(wimp_key *key)
(wimp_message*)&keypress, ta->parent,
ta->icon, 0);
if (error) {
- LOG("xwimp_send_message: 0x%x:%s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO,
+ "xwimp_send_message: 0x%x:%s",
+ error->errnum,
+ error->errmess);
}
break;
}
@@ -1060,7 +1087,8 @@ void ro_textarea_redraw_internal(wimp_draw *redraw, bool update)
else
error = xwimp_redraw_window(redraw, &more);
if (error) {
- LOG("xwimp_redraw_window: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_redraw_window: 0x%x: %s",
+ error->errnum, error->errmess);
return;
}
@@ -1076,13 +1104,17 @@ void ro_textarea_redraw_internal(wimp_draw *redraw, bool update)
colourtrans_SET_BG_GCOL | colourtrans_USE_ECFS_GCOL,
os_ACTION_OVERWRITE, 0, 0);
if (error) {
- LOG("xcolourtrans_set_gcol: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO,
+ "xcolourtrans_set_gcol: 0x%x: %s",
+ error->errnum,
+ error->errmess);
return;
}
error = xos_clg();
if (error) {
- LOG("xos_clg: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xos_clg: 0x%x: %s",
+ error->errnum, error->errmess);
return;
}
@@ -1113,7 +1145,10 @@ void ro_textarea_redraw_internal(wimp_draw *redraw, bool update)
0xD9D9D900 : 0xFFFFFF00,
0x00000000, 14, 0, 0, 0);
if (error) {
- LOG("xcolourtrans_set_font_colours: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO,
+ "xcolourtrans_set_font_colours: 0x%x: %s",
+ error->errnum,
+ error->errmess);
return;
}
@@ -1128,15 +1163,20 @@ void ro_textarea_redraw_internal(wimp_draw *redraw, bool update)
rufl_BLEND_FONT);
if (code != rufl_OK) {
if (code == rufl_FONT_MANAGER_ERROR)
- LOG("rufl_paint: rufl_FONT_MANAGER_ERROR: 0x%x: %s", rufl_fm_error->errnum, rufl_fm_error->errmess);
+ NSLOG(netsurf, INFO,
+ "rufl_paint: rufl_FONT_MANAGER_ERROR: 0x%x: %s",
+ rufl_fm_error->errnum,
+ rufl_fm_error->errmess);
else
- LOG("rufl_paint: 0x%x", code);
+ NSLOG(netsurf, INFO,
+ "rufl_paint: 0x%x", code);
}
}
error = xwimp_get_rectangle(redraw, &more);
if (error) {
- LOG("xwimp_get_rectangle: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_get_rectangle: 0x%x: %s",
+ error->errnum, error->errmess);
return;
}
}
@@ -1153,7 +1193,8 @@ void ro_textarea_open(wimp_open *open)
error = xwimp_open_window(open);
if (error) {
- LOG("xwimp_open_window: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_open_window: 0x%x: %s",
+ error->errnum, error->errmess);
return;
}
}
diff --git a/frontends/riscos/textselection.c b/frontends/riscos/textselection.c
index 5a430c06f..e5be27791 100644
--- a/frontends/riscos/textselection.c
+++ b/frontends/riscos/textselection.c
@@ -92,12 +92,13 @@ void gui_start_selection(struct gui_window *g)
wimp_drag drag;
os_error *error;
- LOG("starting text_selection drag");
+ NSLOG(netsurf, INFO, "starting text_selection drag");
state.w = g->window;
error = xwimp_get_window_state(&state);
if (error) {
- LOG("xwimp_get_window_state 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_get_window_state 0x%x: %s",
+ error->errnum, error->errmess);
ro_warn_user("WimpError", error->errmess);
return;
}
@@ -111,7 +112,8 @@ void gui_start_selection(struct gui_window *g)
error = xwimp_send_message(wimp_USER_MESSAGE,
(wimp_message*)&msg, wimp_BROADCAST);
if (error) {
- LOG("xwimp_send_message: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_send_message: 0x%x: %s",
+ error->errnum, error->errmess);
ro_warn_user("WimpError", error->errmess);
}
owns_caret_and_selection = true;
@@ -127,7 +129,8 @@ void gui_start_selection(struct gui_window *g)
wimp_AUTO_SCROLL_ENABLE_HORIZONTAL,
&scroll, 0);
if (error)
- LOG("xwimp_auto_scroll: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_auto_scroll: 0x%x: %s",
+ error->errnum, error->errmess);
ro_mouse_drag_start(ro_gui_selection_drag_end, ro_gui_window_mouse_at,
NULL, g);
@@ -141,7 +144,8 @@ void gui_start_selection(struct gui_window *g)
error = xwimp_drag_box(&drag);
if (error) {
- LOG("xwimp_drag_box: 0x%x : %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_drag_box: 0x%x : %s",
+ error->errnum, error->errmess);
ro_warn_user("WimpError", error->errmess);
}
last_start_window = g;
@@ -166,17 +170,20 @@ static void ro_gui_selection_drag_end(wimp_dragged *drag, void *data)
scroll.w = g->window;
error = xwimp_auto_scroll(0, &scroll, 0);
if (error)
- LOG("xwimp_auto_scroll: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_auto_scroll: 0x%x: %s",
+ error->errnum, error->errmess);
error = xwimp_drag_box((wimp_drag*)-1);
if (error) {
- LOG("xwimp_drag_box: 0x%x : %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_drag_box: 0x%x : %s",
+ error->errnum, error->errmess);
ro_warn_user("WimpError", error->errmess);
}
error = xwimp_get_pointer_info(&pointer);
if (error) {
- LOG("xwimp_get_pointer_info 0x%x : %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_get_pointer_info 0x%x : %s",
+ error->errnum, error->errmess);
ro_warn_user("WimpError", error->errmess);
return;
}
@@ -217,7 +224,7 @@ static void gui_set_clipboard(const char *buffer, size_t length,
wimp_full_message_claim_entity msg;
os_error *error;
- LOG("claiming clipboard");
+ NSLOG(netsurf, INFO, "claiming clipboard");
msg.size = sizeof(msg);
msg.your_ref = 0;
@@ -227,13 +234,14 @@ static void gui_set_clipboard(const char *buffer, size_t length,
error = xwimp_send_message(wimp_USER_MESSAGE,
(wimp_message*)&msg, wimp_BROADCAST);
if (error) {
- LOG("xwimp_send_message: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_send_message: 0x%x: %s",
+ error->errnum, error->errmess);
ro_warn_user("WimpError", error->errmess);
}
owns_clipboard = true;
}
- LOG("clipboard now holds %zd bytes", clip_length);
+ NSLOG(netsurf, INFO, "clipboard now holds %zd bytes", clip_length);
}
@@ -441,7 +449,7 @@ void ro_gui_selection_claim_entity(wimp_full_message_claim_entity *claim)
/* ignore our own broadcasts! */
if (claim->sender != task_handle) {
- LOG("%x", claim->flags);
+ NSLOG(netsurf, INFO, "%x", claim->flags);
if (claim->flags & wimp_CLAIM_CARET_OR_SELECTION) {
owns_caret_and_selection = false;
@@ -474,7 +482,7 @@ void ro_gui_selection_data_request(wimp_full_message_data_request *req)
// bits ftype = req->file_types[i];
// if (ftype == ~0U) break; /* list terminator */
//
-// LOG("type %x", ftype);
+// NSLOG(netsurf, INFO, "type %x", ftype);
// i++;
// }
@@ -524,7 +532,8 @@ bool ro_gui_save_clipboard(const char *path)
free(local_cb);
if (error) {
- LOG("xosfile_save_stamped: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xosfile_save_stamped: 0x%x: %s",
+ error->errnum, error->errmess);
ro_warn_user("SaveError", error->errmess);
return false;
}
@@ -606,7 +615,8 @@ void ro_gui_selection_send_dragging(wimp_pointer *pointer)
{
wimp_full_message_dragging dragmsg;
- LOG("sending DRAGGING to %p, %d", pointer->w, pointer->i);
+ NSLOG(netsurf, INFO, "sending DRAGGING to %p, %d", pointer->w,
+ pointer->i);
dragmsg.size = offsetof(wimp_full_message_dragging, file_types) + 8;
dragmsg.your_ref = 0;
diff --git a/frontends/riscos/theme.c b/frontends/riscos/theme.c
index b0b4ab879..341b7f7cd 100644
--- a/frontends/riscos/theme.c
+++ b/frontends/riscos/theme.c
@@ -16,8 +16,9 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-/** \file
- * Window themes (implementation).
+/**
+ * \file
+ * Window themes implementation.
*/
#include <alloca.h>
@@ -180,8 +181,10 @@ static void ro_gui_theme_get_available_in_dir(const char *directory)
(osgbpb_info_list *) &info, 1, context,
sizeof(info), 0, &read_count, &context);
if (error) {
- LOG("xosgbpb_dir_entries_info: 0x%x: %s",
- error->errnum, error->errmess);
+ NSLOG(netsurf, INFO,
+ "xosgbpb_dir_entries_info: 0x%x: %s",
+ error->errnum,
+ error->errmess);
if (error->errnum == 0xd6) /* no such dir */
return;
ro_warn_user("MiscError", error->errmess);
@@ -364,7 +367,7 @@ bool ro_gui_theme_add_descriptor(const char *folder, const char *leafname)
/* create a full filename */
filename = malloc(strlen(folder) + strlen(leafname) + 2);
if (!filename) {
- LOG("No memory for malloc");
+ NSLOG(netsurf, INFO, "No memory for malloc");
ro_warn_user("NoMemory", 0);
return false;
}
@@ -374,7 +377,8 @@ bool ro_gui_theme_add_descriptor(const char *folder, const char *leafname)
error = xosfind_openinw(osfind_NO_PATH, filename, 0,
&file_handle);
if (error) {
- LOG("xosfind_openinw: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xosfind_openinw: 0x%x: %s",
+ error->errnum, error->errmess);
ro_warn_user("FileError", error->errmess);
free(filename);
return false;
@@ -389,7 +393,8 @@ bool ro_gui_theme_add_descriptor(const char *folder, const char *leafname)
0, &output_left);
xosfind_closew(file_handle);
if (error) {
- LOG("xosbgpb_read_atw: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xosbgpb_read_atw: 0x%x: %s",
+ error->errnum, error->errmess);
ro_warn_user("FileError", error->errmess);
free(filename);
return false;
@@ -403,7 +408,7 @@ bool ro_gui_theme_add_descriptor(const char *folder, const char *leafname)
current = (struct theme_descriptor *)calloc(1,
sizeof(struct theme_descriptor));
if (!current) {
- LOG("calloc failed");
+ NSLOG(netsurf, INFO, "calloc failed");
ro_warn_user("NoMemory", 0);
free(filename);
return false;
@@ -521,7 +526,7 @@ bool ro_gui_theme_open(struct theme_descriptor *descriptor, bool list)
descriptor->theme = (struct theme *)calloc(1,
sizeof(struct theme));
if (!descriptor->theme) {
- LOG("calloc() failed");
+ NSLOG(netsurf, INFO, "calloc() failed");
ro_warn_user("NoMemory", 0);
continue;
}
@@ -531,7 +536,10 @@ bool ro_gui_theme_open(struct theme_descriptor *descriptor, bool list)
error = xosfile_read_stamped_no_path(descriptor->filename,
&obj_type, 0, 0, &file_size, 0, 0);
if (error) {
- LOG("xosfile_read_stamped_no_path: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO,
+ "xosfile_read_stamped_no_path: 0x%x: %s",
+ error->errnum,
+ error->errmess);
ro_warn_user("FileError", error->errmess);
continue;
}
@@ -539,7 +547,7 @@ bool ro_gui_theme_open(struct theme_descriptor *descriptor, bool list)
continue;
raw_data = malloc(file_size);
if (!raw_data) {
- LOG("malloc() failed");
+ NSLOG(netsurf, INFO, "malloc() failed");
ro_warn_user("NoMemory", 0);
continue;
}
@@ -547,7 +555,10 @@ bool ro_gui_theme_open(struct theme_descriptor *descriptor, bool list)
(byte *)raw_data, 0, 0, 0, 0, 0);
if (error) {
free(raw_data);
- LOG("xosfile_load_stamped_no_path: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO,
+ "xosfile_load_stamped_no_path: 0x%x: %s",
+ error->errnum,
+ error->errmess);
ro_warn_user("FileError", error->errmess);
continue;
}
@@ -556,7 +567,10 @@ bool ro_gui_theme_open(struct theme_descriptor *descriptor, bool list)
error = xsquash_decompress_return_sizes(-1, &workspace_size, 0);
if (error) {
free(raw_data);
- LOG("xsquash_decompress_return_sizes: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO,
+ "xsquash_decompress_return_sizes: 0x%x: %s",
+ error->errnum,
+ error->errmess);
ro_warn_user("MiscError", error->errmess);
continue;
}
@@ -566,7 +580,7 @@ bool ro_gui_theme_open(struct theme_descriptor *descriptor, bool list)
if ((!decompressed) || (!workspace)) {
free(decompressed);
free(raw_data);
- LOG("malloc() failed");
+ NSLOG(netsurf, INFO, "malloc() failed");
ro_warn_user("NoMemory", 0);
continue;
}
@@ -581,7 +595,8 @@ bool ro_gui_theme_open(struct theme_descriptor *descriptor, bool list)
free(raw_data);
if (error) {
free(decompressed);
- LOG("xsquash_decompress: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xsquash_decompress: 0x%x: %s",
+ error->errnum, error->errmess);
ro_warn_user("MiscError", error->errmess);
continue;
}
@@ -599,7 +614,10 @@ bool ro_gui_theme_open(struct theme_descriptor *descriptor, bool list)
descriptor->theme->sprite_area,
sprite_name, 16, i, 0);
if (error) {
- LOG("xosspriteop_return_name: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO,
+ "xosspriteop_return_name: 0x%x: %s",
+ error->errnum,
+ error->errmess);
ro_warn_user("MiscError", error->errmess);
continue;
}
@@ -614,7 +632,10 @@ bool ro_gui_theme_open(struct theme_descriptor *descriptor, bool list)
&dimensions.x, &dimensions.y,
(osbool *) 0, &mode);
if (error) {
- LOG("xosspriteop_read_sprite_info: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO,
+ "xosspriteop_read_sprite_info: 0x%x: %s",
+ error->errnum,
+ error->errmess);
ro_warn_user("MiscError", error->errmess);
continue;
}
diff --git a/frontends/riscos/theme_install.c b/frontends/riscos/theme_install.c
index 43ecb4687..fbca9e4fa 100644
--- a/frontends/riscos/theme_install.c
+++ b/frontends/riscos/theme_install.c
@@ -182,7 +182,7 @@ bool ro_gui_theme_install_apply(wimp_w w)
/* convert spaces to hard spaces */
theme_file = strdup(theme_install_descriptor.name);
if (!theme_file) {
- LOG("malloc failed");
+ NSLOG(netsurf, INFO, "malloc failed");
ro_warn_user("NoMemory", 0);
return false;
}
@@ -203,7 +203,8 @@ bool ro_gui_theme_install_apply(wimp_w w)
(byte *) source_data,
(byte *) source_data + source_size);
if (error) {
- LOG("xosfile_save_stamped: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xosfile_save_stamped: 0x%x: %s",
+ error->errnum, error->errmess);
ro_warn_user("ThemeInstallErr", 0);
free(theme_file);
return false;
diff --git a/frontends/riscos/toolbar.c b/frontends/riscos/toolbar.c
index 2b5cb3415..758c90cc2 100644
--- a/frontends/riscos/toolbar.c
+++ b/frontends/riscos/toolbar.c
@@ -227,7 +227,7 @@ struct toolbar *ro_toolbar_create(struct theme_descriptor *descriptor,
toolbar = calloc(sizeof(struct toolbar), 1);
if (toolbar == NULL) {
- LOG("No memory for malloc()");
+ NSLOG(netsurf, INFO, "No memory for malloc()");
ro_warn_user("NoMemory", 0);
return NULL;
}
@@ -366,7 +366,8 @@ bool ro_toolbar_rebuild(struct toolbar *toolbar)
old_window = toolbar->toolbar_handle;
error = xwimp_delete_window(toolbar->toolbar_handle);
if (error)
- LOG("xwimp_delete_window: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_delete_window: 0x%x: %s",
+ error->errnum, error->errmess);
toolbar->toolbar_handle = NULL;
}
@@ -375,7 +376,8 @@ bool ro_toolbar_rebuild(struct toolbar *toolbar)
error = xwimp_create_window(&ro_toolbar_window,
&toolbar->toolbar_handle);
if (error) {
- LOG("xwimp_create_window: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_create_window: 0x%x: %s",
+ error->errnum, error->errmess);
ro_warn_user("WimpError", error->errmess);
return false;
}
@@ -493,7 +495,8 @@ bool ro_toolbar_rebuild(struct toolbar *toolbar)
icon.icon.data.indirected_text.size = 1;
error = xwimp_create_icon(&icon, &toolbar->editor_div1);
if (error) {
- LOG("xwimp_create_icon: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_create_icon: 0x%x: %s",
+ error->errnum, error->errmess);
ro_warn_user("WimpError", error->errmess);
toolbar->editor_div1 = -1;
}
@@ -558,7 +561,10 @@ bool ro_toolbar_attach(struct toolbar *toolbar, wimp_w parent)
wimp_CHILD_LINKS_PARENT_VISIBLE_TOP_OR_RIGHT
<< wimp_CHILD_TS_EDGE_SHIFT);
if (error) {
- LOG("xwimp_open_window_nested: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO,
+ "xwimp_open_window_nested: 0x%x: %s",
+ error->errnum,
+ error->errmess);
ro_warn_user("WimpError", error->errmess);
return false;
}
@@ -568,7 +574,8 @@ bool ro_toolbar_attach(struct toolbar *toolbar, wimp_w parent)
error = xwimp_close_window(toolbar->toolbar_handle);
if (error) {
- LOG("xwimp_close_window: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_close_window: 0x%x: %s",
+ error->errnum, error->errmess);
ro_warn_user("WimpError", error->errmess);
return false;
}
@@ -601,7 +608,10 @@ bool ro_toolbar_process(struct toolbar *toolbar, int width, bool reformat)
outline.w = toolbar->parent_handle;
error = xwimp_get_window_outline(&outline);
if (error) {
- LOG("xwimp_get_window_outline: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO,
+ "xwimp_get_window_outline: 0x%x: %s",
+ error->errnum,
+ error->errmess);
ro_warn_user("WimpError", error->errmess);
return false;
}
@@ -621,7 +631,10 @@ bool ro_toolbar_process(struct toolbar *toolbar, int width, bool reformat)
state.w = toolbar->parent_handle;
error = xwimp_get_window_state(&state);
if (error) {
- LOG("xwimp_get_window_state: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO,
+ "xwimp_get_window_state: 0x%x: %s",
+ error->errnum,
+ error->errmess);
ro_warn_user("WimpError", error->errmess);
return false;
}
@@ -647,7 +660,10 @@ bool ro_toolbar_process(struct toolbar *toolbar, int width, bool reformat)
error = xwimp_set_extent(toolbar->toolbar_handle,
&extent);
if (error) {
- LOG("xwimp_get_window_state: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO,
+ "xwimp_get_window_state: 0x%x: %s",
+ error->errnum,
+ error->errmess);
ro_warn_user("WimpError", error->errmess);
}
@@ -935,7 +951,7 @@ void ro_toolbar_destroy(struct toolbar *toolbar)
if (toolbar == NULL)
return;
- LOG("Destroying toolbar 0x%x", (unsigned int)toolbar);
+ NSLOG(netsurf, INFO, "Destroying toolbar 0x%x", (unsigned int)toolbar);
/* Destroy the widgets. */
@@ -994,7 +1010,8 @@ void ro_toolbar_redraw(wimp_draw *redraw)
error = xwimp_redraw_window(redraw, &more);
if (error) {
- LOG("xwimp_redraw_window: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_redraw_window: 0x%x: %s",
+ error->errnum, error->errmess);
ro_warn_user("WimpError", error->errmess);
return;
}
@@ -1013,7 +1030,8 @@ void ro_toolbar_redraw(wimp_draw *redraw)
error = xwimp_get_rectangle(redraw, &more);
if (error) {
- LOG("xwimp_get_rectangle: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_get_rectangle: 0x%x: %s",
+ error->errnum, error->errmess);
ro_warn_user("WimpError", error->errmess);
return;
}
@@ -1046,7 +1064,8 @@ bool ro_toolbar_click(wimp_pointer *pointer)
state.w = toolbar->toolbar_handle;
error = xwimp_get_window_state(&state);
if (error) {
- LOG("xwimp_get_window_state: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_get_window_state: 0x%x: %s",
+ error->errnum, error->errmess);
ro_warn_user("WimpError", error->errmess);
return false;
}
@@ -1325,7 +1344,8 @@ const char *ro_toolbar_get_help_suffix(wimp_w w, wimp_i i, os_coord *pos,
state.w = toolbar->toolbar_handle;
error = xwimp_get_window_state(&state);
if (error) {
- LOG("xwimp_get_window_state: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_get_window_state: 0x%x: %s",
+ error->errnum, error->errmess);
ro_warn_user("WimpError", error->errmess);
return NULL;
}
diff --git a/frontends/riscos/ucstables.c b/frontends/riscos/ucstables.c
index 8e538ef95..3e31c992e 100644
--- a/frontends/riscos/ucstables.c
+++ b/frontends/riscos/ucstables.c
@@ -623,7 +623,8 @@ nserror utf8_from_local_encoding(const char *string, size_t len, char **result)
off - prev_off, &temp, NULL);
if (err != NSERROR_OK) {
assert(err != NSERROR_BAD_ENCODING);
- LOG("utf8_from_enc failed");
+ NSLOG(netsurf, INFO,
+ "utf8_from_enc failed");
free(*result);
return NSERROR_NOMEM;
}
@@ -665,7 +666,7 @@ nserror utf8_from_local_encoding(const char *string, size_t len, char **result)
&temp, NULL);
if (err != NSERROR_OK) {
assert(err != NSERROR_BAD_ENCODING);
- LOG("utf8_from_enc failed");
+ NSLOG(netsurf, INFO, "utf8_from_enc failed");
free(*result);
return NSERROR_NOMEM;
}
@@ -680,7 +681,7 @@ nserror utf8_from_local_encoding(const char *string, size_t len, char **result)
/* and copy into more reasonably-sized buffer */
temp = realloc((*result), cur_off + 1);
if (!temp) {
- LOG("realloc failed");
+ NSLOG(netsurf, INFO, "realloc failed");
free(*result);
return NSERROR_NOMEM;
}
diff --git a/frontends/riscos/uri.c b/frontends/riscos/uri.c
index a2f126b31..d79cfe56d 100644
--- a/frontends/riscos/uri.c
+++ b/frontends/riscos/uri.c
@@ -120,7 +120,8 @@ void ro_uri_bounce(wimp_message *msg)
/* Get required buffer size */
e = xuri_request_uri(0, NULL, 0, message->handle, &size);
if (e) {
- LOG("xuri_request_uri: %d: %s", e->errnum, e->errmess);
+ NSLOG(netsurf, INFO, "xuri_request_uri: %d: %s", e->errnum,
+ e->errmess);
return;
}
@@ -131,7 +132,8 @@ void ro_uri_bounce(wimp_message *msg)
/* Get URI */
e = xuri_request_uri(0, uri_buf, size, message->handle, 0);
if (e) {
- LOG("xuri_request_uri: %d: %s", e->errnum, e->errmess);
+ NSLOG(netsurf, INFO, "xuri_request_uri: %d: %s", e->errnum,
+ e->errmess);
free(uri_buf);
return;
}
diff --git a/frontends/riscos/url_complete.c b/frontends/riscos/url_complete.c
index 16c6e3a2e..82c2d2c67 100644
--- a/frontends/riscos/url_complete.c
+++ b/frontends/riscos/url_complete.c
@@ -171,7 +171,8 @@ bool ro_gui_url_complete_keypress(struct toolbar *toolbar, uint32_t key)
-(url_complete_matches_selection + 1) * 44,
65536, -url_complete_matches_selection * 44);
if (error) {
- LOG("xwimp_force_redraw: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_force_redraw: 0x%x: %s",
+ error->errnum, error->errmess);
ro_warn_user("WimpError", error->errmess);
}
@@ -210,7 +211,10 @@ bool ro_gui_url_complete_keypress(struct toolbar *toolbar, uint32_t key)
state.w = parent;
error = xwimp_get_window_state(&state);
if (error) {
- LOG("xwimp_get_window_state: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO,
+ "xwimp_get_window_state: 0x%x: %s",
+ error->errnum,
+ error->errmess);
ro_warn_user("WimpError", error->errmess);
return false;
}
@@ -228,7 +232,10 @@ bool ro_gui_url_complete_keypress(struct toolbar *toolbar, uint32_t key)
error = xwimp_force_redraw(dialog_url_complete,
0, -(i + 1) * 44, 65536, -i * 44);
if (error) {
- LOG("xwimp_force_redraw: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO,
+ "xwimp_force_redraw: 0x%x: %s",
+ error->errnum,
+ error->errmess);
ro_warn_user("WimpError",
error->errmess);
}
@@ -281,7 +288,8 @@ bool ro_gui_url_complete_keypress(struct toolbar *toolbar, uint32_t key)
0, -(old_selection + 1) * 44,
65536, -old_selection * 44);
if (error) {
- LOG("xwimp_force_redraw: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_force_redraw: 0x%x: %s",
+ error->errnum, error->errmess);
ro_warn_user("WimpError", error->errmess);
}
@@ -289,7 +297,8 @@ bool ro_gui_url_complete_keypress(struct toolbar *toolbar, uint32_t key)
0, -(url_complete_matches_selection + 1) * 44,
65536, -url_complete_matches_selection * 44);
if (error) {
- LOG("xwimp_force_redraw: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_force_redraw: 0x%x: %s",
+ error->errnum, error->errmess);
ro_warn_user("WimpError", error->errmess);
}
@@ -320,7 +329,8 @@ bool ro_gui_url_complete_keypress(struct toolbar *toolbar, uint32_t key)
state.w = dialog_url_complete;
error = xwimp_get_window_state(&state);
if (error) {
- LOG("xwimp_get_window_state: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_get_window_state: 0x%x: %s",
+ error->errnum, error->errmess);
ro_warn_user("WimpError", error->errmess);
return true;
}
@@ -335,7 +345,8 @@ bool ro_gui_url_complete_keypress(struct toolbar *toolbar, uint32_t key)
error = xwimp_open_window(PTR_WIMP_OPEN(&state));
if (error) {
- LOG("xwimp_open_window: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_open_window: 0x%x: %s",
+ error->errnum, error->errmess);
ro_warn_user("WimpError", error->errmess);
return true;
}
@@ -411,7 +422,8 @@ void ro_gui_url_complete_resize(struct toolbar *toolbar, wimp_open *open)
state.w = dialog_url_complete;
error = xwimp_get_window_state(&state);
if (error) {
- LOG("xwimp_get_window_state: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_get_window_state: 0x%x: %s",
+ error->errnum, error->errmess);
ro_warn_user("WimpError", error->errmess);
return;
}
@@ -423,13 +435,14 @@ void ro_gui_url_complete_resize(struct toolbar *toolbar, wimp_open *open)
toolbar_state.w = ro_toolbar_get_window(toolbar);
error = xwimp_get_window_state(&toolbar_state);
if (error) {
- LOG("xwimp_get_window_state: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_get_window_state: 0x%x: %s",
+ error->errnum, error->errmess);
ro_warn_user("WimpError", error->errmess);
return;
}
if (!ro_toolbar_get_url_field_extent(toolbar, &url_extent)) {
- LOG("Failed to read URL field extent.");
+ NSLOG(netsurf, INFO, "Failed to read URL field extent.");
return;
}
@@ -438,7 +451,8 @@ void ro_gui_url_complete_resize(struct toolbar *toolbar, wimp_open *open)
extent.x1 = 65536;
error = xwimp_set_extent(dialog_url_complete, &extent);
if (error) {
- LOG("xwimp_set_extent: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_set_extent: 0x%x: %s",
+ error->errnum, error->errmess);
ro_warn_user("WimpError", error->errmess);
return;
}
@@ -460,14 +474,16 @@ void ro_gui_url_complete_resize(struct toolbar *toolbar, wimp_open *open)
if (state.visible.x1 - state.visible.x0 < 0) {
error = xwimp_close_window(dialog_url_complete);
if (error) {
- LOG("xwimp_close_window: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_close_window: 0x%x: %s",
+ error->errnum, error->errmess);
ro_warn_user("WimpError", error->errmess);
}
} else {
error = xwimp_open_window_nested_with_flags(&state,
(wimp_w)-1, 0);
if (error) {
- LOG("xwimp_open_window: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_open_window: 0x%x: %s",
+ error->errnum, error->errmess);
ro_warn_user("WimpError", error->errmess);
return;
}
@@ -507,7 +523,8 @@ bool ro_gui_url_complete_close(void)
error = xwimp_close_window(dialog_url_complete);
if (error) {
- LOG("xwimp_close_window: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_close_window: 0x%x: %s",
+ error->errnum, error->errmess);
ro_warn_user("WimpError", error->errmess);
}
@@ -547,7 +564,7 @@ void ro_gui_url_complete_redraw(wimp_draw *redraw)
/* no matches? no redraw */
if (!url_complete_matches) {
- LOG("Attempt to redraw with no matches made");
+ NSLOG(netsurf, INFO, "Attempt to redraw with no matches made");
/* Fill is never used, so make it something obvious */
ro_gui_user_redraw(redraw, false, os_COLOUR_BLACK);
return;
@@ -582,7 +599,10 @@ void ro_gui_url_complete_redraw(wimp_draw *redraw)
error = xwimp_plot_icon(&url_complete_icon);
if (error) {
- LOG("xwimp_plot_icon: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO,
+ "xwimp_plot_icon: 0x%x: %s",
+ error->errnum,
+ error->errmess);
ro_warn_user("WimpError", error->errmess);
}
@@ -604,7 +624,10 @@ void ro_gui_url_complete_redraw(wimp_draw *redraw)
url_complete_sprite.extent.y0 = -(line + 1) * 44;
error = xwimp_plot_icon(&url_complete_sprite);
if (error) {
- LOG("xwimp_plot_icon: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO,
+ "xwimp_plot_icon: 0x%x: %s",
+ error->errnum,
+ error->errmess);
ro_warn_user("WimpError", error->errmess);
}
}
@@ -658,7 +681,8 @@ bool ro_gui_url_complete_click(wimp_pointer *pointer)
state.w = dialog_url_complete;
error = xwimp_get_window_state(&state);
if (error) {
- LOG("xwimp_get_window_state: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_get_window_state: 0x%x: %s",
+ error->errnum, error->errmess);
ro_warn_user("WimpError", error->errmess);
return false;
}
@@ -685,14 +709,16 @@ bool ro_gui_url_complete_click(wimp_pointer *pointer)
0, -(old_selection + 1) * 44,
65536, -old_selection * 44);
if (error) {
- LOG("xwimp_force_redraw: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_force_redraw: 0x%x: %s",
+ error->errnum, error->errmess);
ro_warn_user("WimpError", error->errmess);
}
error = xwimp_force_redraw(dialog_url_complete,
0, -(url_complete_matches_selection + 1) * 44,
65536, -url_complete_matches_selection * 44);
if (error) {
- LOG("xwimp_force_redraw: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_force_redraw: 0x%x: %s",
+ error->errnum, error->errmess);
ro_warn_user("WimpError", error->errmess);
}
}
diff --git a/frontends/riscos/url_protocol.c b/frontends/riscos/url_protocol.c
index 9a7ae062c..184aaeab0 100644
--- a/frontends/riscos/url_protocol.c
+++ b/frontends/riscos/url_protocol.c
@@ -75,17 +75,19 @@ void ro_url_message_received(wimp_message *message)
} else {
if (!url_message->indirect.url.offset) {
- LOG("no URL in message");
+ NSLOG(netsurf, INFO, "no URL in message");
return;
}
if (28 < message->size &&
url_message->indirect.body_file.offset) {
- LOG("POST for URL message not implemented");
+ NSLOG(netsurf, INFO,
+ "POST for URL message not implemented");
return;
}
if (url_message->indirect.url.offset < 28 ||
236 <= url_message->indirect.url.offset) {
- LOG("external pointers in URL message unimplemented");
+ NSLOG(netsurf, INFO,
+ "external pointers in URL message unimplemented");
/* these messages have never been seen in the wild,
* and there is the problem of invalid addresses which
* would cause an abort */
@@ -122,7 +124,8 @@ void ro_url_message_received(wimp_message *message)
error = xwimp_send_message(wimp_USER_MESSAGE_ACKNOWLEDGE, message,
message->sender);
if (error) {
- LOG("xwimp_send_message: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_send_message: 0x%x: %s",
+ error->errnum, error->errmess);
ro_warn_user("WimpError", error->errmess);
}
@@ -165,7 +168,8 @@ void ro_url_broadcast(const char *url)
error = xwimp_send_message(wimp_USER_MESSAGE_RECORDED,
(wimp_message *) &message, 0);
if (error) {
- LOG("xwimp_send_message: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_send_message: 0x%x: %s",
+ error->errnum, error->errmess);
ro_warn_user("WimpError", error->errmess);
}
}
@@ -184,7 +188,7 @@ void ro_url_load(const char *url)
colon = strchr(url, ':');
if (!colon) {
- LOG("invalid url '%s'", url);
+ NSLOG(netsurf, INFO, "invalid url '%s'", url);
return;
}
@@ -204,7 +208,8 @@ void ro_url_load(const char *url)
error = xwimp_start_task(command, 0);
if (error) {
- LOG("xwimp_start_task: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_start_task: 0x%x: %s",
+ error->errnum, error->errmess);
ro_warn_user("WimpError", error->errmess);
}
diff --git a/frontends/riscos/wimp.c b/frontends/riscos/wimp.c
index abf099a55..d851ab59e 100644
--- a/frontends/riscos/wimp.c
+++ b/frontends/riscos/wimp.c
@@ -103,7 +103,10 @@ void ro_gui_wimp_cache_furniture_sizes(wimp_w w)
furniture_sizes.border_widths.x1 = 40;
error = xwimpextend_get_furniture_sizes(&furniture_sizes);
if (error) {
- LOG("xwimpextend_get_furniture_sizes: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO,
+ "xwimpextend_get_furniture_sizes: 0x%x: %s",
+ error->errnum,
+ error->errmess);
ro_warn_user("WimpError", error->errmess);
}
}
@@ -123,13 +126,15 @@ bool ro_gui_wimp_read_eig_factors(os_mode mode, int *xeig, int *yeig)
error = xos_read_mode_variable(mode, os_MODEVAR_XEIG_FACTOR, xeig, 0);
if (error) {
- LOG("xos_read_mode_variable: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xos_read_mode_variable: 0x%x: %s",
+ error->errnum, error->errmess);
ro_warn_user("MiscError", error->errmess);
return false;
}
error = xos_read_mode_variable(mode, os_MODEVAR_YEIG_FACTOR, yeig, 0);
if (error) {
- LOG("xos_read_mode_variable: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xos_read_mode_variable: 0x%x: %s",
+ error->errnum, error->errmess);
ro_warn_user("MiscError", error->errmess);
return false;
}
@@ -196,14 +201,16 @@ void ro_gui_force_redraw_icon(wimp_w w, wimp_i i)
ic.i = i;
error = xwimp_get_icon_state(&ic);
if (error) {
- LOG("xwimp_get_icon_state: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_get_icon_state: 0x%x: %s",
+ error->errnum, error->errmess);
ro_warn_user("WimpError", error->errmess);
return;
}
error = xwimp_force_redraw(w, ic.icon.extent.x0, ic.icon.extent.y0,
ic.icon.extent.x1, ic.icon.extent.y1);
if (error) {
- LOG("xwimp_force_redraw: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_force_redraw: 0x%x: %s",
+ error->errnum, error->errmess);
ro_warn_user("WimpError", error->errmess);
}
}
@@ -235,7 +242,8 @@ const char *ro_gui_get_icon_string(wimp_w w, wimp_i i)
ic.i = i;
error = xwimp_get_icon_state(&ic);
if (error) {
- LOG("xwimp_get_icon_state: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_get_icon_state: 0x%x: %s",
+ error->errnum, error->errmess);
ro_warn_user("WimpError", error->errmess);
return NULL;
}
@@ -277,7 +285,7 @@ void ro_gui_set_icon_string(wimp_w w, wimp_i i, const char *text, bool is_utf8)
if (err != NSERROR_OK) {
/* A bad encoding should never happen, so assert this */
assert(err != NSERROR_BAD_ENCODING);
- LOG("utf8_to_enc failed");
+ NSLOG(netsurf, INFO, "utf8_to_enc failed");
/* Paranoia */
local_text = NULL;
}
@@ -292,7 +300,8 @@ void ro_gui_set_icon_string(wimp_w w, wimp_i i, const char *text, bool is_utf8)
ic.i = i;
error = xwimp_get_icon_state(&ic);
if (error) {
- LOG("xwimp_get_icon_state: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_get_icon_state: 0x%x: %s",
+ error->errnum, error->errmess);
ro_warn_user("WimpError", error->errmess);
goto exit;
}
@@ -325,7 +334,10 @@ void ro_gui_set_icon_string(wimp_w w, wimp_i i, const char *text, bool is_utf8)
(button_type == wimp_BUTTON_WRITE_CLICK_DRAG)) {
error = xwimp_get_caret_position(&caret);
if (error) {
- LOG("xwimp_get_caret_position: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO,
+ "xwimp_get_caret_position: 0x%x: %s",
+ error->errnum,
+ error->errmess);
ro_warn_user("WimpError", error->errmess);
goto exit;
}
@@ -336,7 +348,10 @@ void ro_gui_set_icon_string(wimp_w w, wimp_i i, const char *text, bool is_utf8)
error = xwimp_set_caret_position(w, i, caret.pos.x,
caret.pos.y, -1, caret.index);
if (error) {
- LOG("xwimp_set_caret_position: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO,
+ "xwimp_set_caret_position: 0x%x: %s",
+ error->errnum,
+ error->errmess);
ro_warn_user("WimpError", error->errmess);
}
}
@@ -433,7 +448,8 @@ void ro_gui_set_icon_selected_state(wimp_w w, wimp_i i, bool state)
error = xwimp_set_icon_state(w, i,
(state ? wimp_ICON_SELECTED : 0), wimp_ICON_SELECTED);
if (error) {
- LOG("xwimp_set_icon_state: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_set_icon_state: 0x%x: %s",
+ error->errnum, error->errmess);
ro_warn_user("WimpError", error->errmess);
}
}
@@ -452,7 +468,8 @@ bool ro_gui_get_icon_selected_state(wimp_w w, wimp_i i)
ic.i = i;
error = xwimp_get_icon_state(&ic);
if (error) {
- LOG("xwimp_get_icon_state: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_get_icon_state: 0x%x: %s",
+ error->errnum, error->errmess);
ro_warn_user("WimpError", error->errmess);
return false;
}
@@ -478,7 +495,8 @@ void ro_gui_set_icon_shaded_state(wimp_w w, wimp_i i, bool state)
error = xwimp_set_icon_state(w, i,
(state ? wimp_ICON_SHADED : 0), wimp_ICON_SHADED);
if (error) {
- LOG("xwimp_get_icon_state: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_get_icon_state: 0x%x: %s",
+ error->errnum, error->errmess);
ro_warn_user("WimpError", error->errmess);
}
if (!state)
@@ -487,7 +505,8 @@ void ro_gui_set_icon_shaded_state(wimp_w w, wimp_i i, bool state)
/* ensure the caret is not in a shaded icon */
error = xwimp_get_caret_position(&caret);
if (error) {
- LOG("xwimp_get_caret_position: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_get_caret_position: 0x%x: %s",
+ error->errnum, error->errmess);
ro_warn_user("WimpError", error->errmess);
return;
}
@@ -499,7 +518,8 @@ void ro_gui_set_icon_shaded_state(wimp_w w, wimp_i i, bool state)
/* lose the caret */
error = xwimp_set_caret_position((wimp_w)-1, (wimp_i)-1, -1, -1, -1, -1);
if (error) {
- LOG("xwimp_set_caret_position: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_set_caret_position: 0x%x: %s",
+ error->errnum, error->errmess);
ro_warn_user("WimpError", error->errmess);
return;
}
@@ -540,7 +560,8 @@ void ro_gui_set_icon_deleted_state(wimp_w w, wimp_i i, bool state)
error = xwimp_set_icon_state(w, i,
(state ? wimp_ICON_DELETED : 0), wimp_ICON_DELETED);
if (error) {
- LOG("xwimp_get_icon_state: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_get_icon_state: 0x%x: %s",
+ error->errnum, error->errmess);
ro_warn_user("WimpError", error->errmess);
}
if (!state)
@@ -549,7 +570,8 @@ void ro_gui_set_icon_deleted_state(wimp_w w, wimp_i i, bool state)
/* ensure the caret is not in a shaded icon */
error = xwimp_get_caret_position(&caret);
if (error) {
- LOG("xwimp_get_caret_position: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_get_caret_position: 0x%x: %s",
+ error->errnum, error->errmess);
ro_warn_user("WimpError", error->errmess);
return;
}
@@ -561,7 +583,8 @@ void ro_gui_set_icon_deleted_state(wimp_w w, wimp_i i, bool state)
/* lose the caret */
error = xwimp_set_caret_position((wimp_w)-1, (wimp_i)-1, -1, -1, -1, -1);
if (error) {
- LOG("xwimp_set_caret_position: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_set_caret_position: 0x%x: %s",
+ error->errnum, error->errmess);
ro_warn_user("WimpError", error->errmess);
return;
}
@@ -597,7 +620,8 @@ void ro_gui_set_icon_button_type(wimp_w w, wimp_i i, int type)
error = xwimp_set_icon_state(w, i, wimp_ICON_BUTTON_TYPE,
(type << wimp_ICON_BUTTON_TYPE_SHIFT));
if (error) {
- LOG("xwimp_set_icon_state: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_set_icon_state: 0x%x: %s",
+ error->errnum, error->errmess);
ro_warn_user("WimpError", error->errmess);
}
}
@@ -622,7 +646,8 @@ void ro_gui_set_icon_sprite(wimp_w w, wimp_i i, osspriteop_area *area,
ic.i = i;
error = xwimp_get_icon_state(&ic);
if (error) {
- LOG("xwimp_get_icon_state: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_get_icon_state: 0x%x: %s",
+ error->errnum, error->errmess);
ro_warn_user("WimpError", error->errmess);
return;
}
@@ -659,7 +684,8 @@ void ro_gui_set_window_title(wimp_w w, const char *text)
window.w = w;
error = xwimp_get_window_info_header_only((wimp_window_info *)&window);
if (error) {
- LOG("xwimp_get_window_info: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_get_window_info: 0x%x: %s",
+ error->errnum, error->errmess);
ro_warn_user("WimpError", error->errmess);
return;
}
@@ -670,7 +696,7 @@ void ro_gui_set_window_title(wimp_w w, const char *text)
/* A bad encoding should never happen,
* so assert this */
assert(err != NSERROR_BAD_ENCODING);
- LOG("utf8_to_enc failed");
+ NSLOG(netsurf, INFO, "utf8_to_enc failed");
return;
}
@@ -686,7 +712,8 @@ void ro_gui_set_window_title(wimp_w w, const char *text)
*/
error = xwimp_force_redraw_title(w);
if (error) {
- LOG("xwimp_force_redraw_title: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_force_redraw_title: 0x%x: %s",
+ error->errnum, error->errmess);
ro_warn_user("WimpError", error->errmess);
return;
}
@@ -713,7 +740,8 @@ bool ro_gui_set_caret_first(wimp_w w)
win_state.w = w;
error = xwimp_get_window_state(&win_state);
if (error) {
- LOG("xwimp_get_window_state: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_get_window_state: 0x%x: %s",
+ error->errnum, error->errmess);
ro_warn_user("WimpError", error->errmess);
return false;
}
@@ -724,7 +752,8 @@ bool ro_gui_set_caret_first(wimp_w w)
window.w = w;
error = xwimp_get_window_info_header_only((wimp_window_info *)&window);
if (error) {
- LOG("xwimp_get_window_info: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_get_window_info: 0x%x: %s",
+ error->errnum, error->errmess);
ro_warn_user("WimpError", error->errmess);
return false;
}
@@ -735,7 +764,10 @@ bool ro_gui_set_caret_first(wimp_w w)
state.i = icon;
error = xwimp_get_icon_state(&state);
if (error) {
- LOG("xwimp_get_icon_state: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO,
+ "xwimp_get_icon_state: 0x%x: %s",
+ error->errnum,
+ error->errmess);
ro_warn_user("WimpError", error->errmess);
return false;
}
@@ -752,7 +784,10 @@ bool ro_gui_set_caret_first(wimp_w w)
error = xwimp_set_caret_position(w, icon, 0, 0, -1,
strlen(state.icon.data.indirected_text.text));
if (error) {
- LOG("xwimp_set_caret_position: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO,
+ "xwimp_set_caret_position: 0x%x: %s",
+ error->errnum,
+ error->errmess);
ro_warn_user("WimpError", error->errmess);
}
return true;
@@ -778,7 +813,10 @@ osspriteop_area *ro_gui_load_sprite_file(const char *pathname)
error = xosfile_read_stamped_no_path(pathname,
&obj_type, 0, 0, &len, 0, 0);
if (error) {
- LOG("xosfile_read_stamped_no_path: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO,
+ "xosfile_read_stamped_no_path: 0x%x: %s",
+ error->errnum,
+ error->errmess);
ro_warn_user("MiscError", error->errmess);
return 0;
}
@@ -801,7 +839,10 @@ osspriteop_area *ro_gui_load_sprite_file(const char *pathname)
error = xosspriteop_load_sprite_file(osspriteop_USER_AREA,
area, pathname);
if (error) {
- LOG("xosspriteop_load_sprite_file: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO,
+ "xosspriteop_load_sprite_file: 0x%x: %s",
+ error->errnum,
+ error->errmess);
ro_warn_user("MiscError", error->errmess);
free(area);
return 0;
@@ -831,7 +872,10 @@ bool ro_gui_wimp_sprite_exists(const char *sprite)
error = xwimpspriteop_select_sprite(sprite, 0);
if (error) {
if (error->errnum != error_SPRITE_OP_DOESNT_EXIST) {
- LOG("xwimpspriteop_select_sprite: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO,
+ "xwimpspriteop_select_sprite: 0x%x: %s",
+ error->errnum,
+ error->errmess);
ro_warn_user("MiscError", error->errmess);
}
return false;
@@ -904,7 +948,10 @@ bool ro_gui_wimp_get_sprite_dimensions(osspriteop_area *area, char *sprite,
if (height != NULL)
*height = dimensions.y;
} else if (error->errnum != error_SPRITE_OP_DOESNT_EXIST) {
- LOG("xosspriteop_read_sprite_info: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO,
+ "xosspriteop_read_sprite_info: 0x%x: %s",
+ error->errnum,
+ error->errmess);
ro_warn_user("MiscError", error->errmess);
return false;
}
@@ -929,7 +976,8 @@ void ro_gui_user_redraw(wimp_draw *redraw, bool user_fill,
error = xwimp_redraw_window(redraw, &more);
if (error) {
- LOG("xwimp_redraw_window: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_redraw_window: 0x%x: %s",
+ error->errnum, error->errmess);
ro_warn_user("WimpError", error->errmess);
return;
}
@@ -939,14 +987,18 @@ void ro_gui_user_redraw(wimp_draw *redraw, bool user_fill,
colourtrans_SET_BG_GCOL,
os_ACTION_OVERWRITE, 0, 0);
if (error) {
- LOG("xcolourtrans_set_gcol: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO,
+ "xcolourtrans_set_gcol: 0x%x: %s",
+ error->errnum,
+ error->errmess);
ro_warn_user("MiscError", error->errmess);
}
os_clg();
}
error = xwimp_get_rectangle(redraw, &more);
if (error) {
- LOG("xwimp_get_rectangle: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_get_rectangle: 0x%x: %s",
+ error->errnum, error->errmess);
ro_warn_user("WimpError", error->errmess);
return;
}
@@ -973,7 +1025,8 @@ void ro_gui_wimp_update_window_furniture(wimp_w w, wimp_window_flags bic_mask,
state.w = w;
error = xwimp_get_window_state_and_nesting(&state, &parent, &linkage);
if (error) {
- LOG("xwimp_get_window_state: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_get_window_state: 0x%x: %s",
+ error->errnum, error->errmess);
ro_warn_user("WimpError", error->errmess);
return;
}
@@ -986,7 +1039,8 @@ void ro_gui_wimp_update_window_furniture(wimp_w w, wimp_window_flags bic_mask,
state.next = wimp_HIDDEN;
error = xwimp_open_window_nested_with_flags(&state, parent, linkage);
if (error) {
- LOG("xwimp_open_window: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_open_window: 0x%x: %s",
+ error->errnum, error->errmess);
ro_warn_user("WimpError", error->errmess);
return;
}
@@ -994,7 +1048,8 @@ void ro_gui_wimp_update_window_furniture(wimp_w w, wimp_window_flags bic_mask,
if (!open) {
error = xwimp_close_window(w);
if (error) {
- LOG("xwimp_close_window: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_close_window: 0x%x: %s",
+ error->errnum, error->errmess);
ro_warn_user("WimpError", error->errmess);
return;
}
@@ -1016,7 +1071,8 @@ bool ro_gui_wimp_check_window_furniture(wimp_w w, wimp_window_flags mask)
state.w = w;
error = xwimp_get_window_state(&state);
if (error) {
- LOG("xwimp_get_window_state: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_get_window_state: 0x%x: %s",
+ error->errnum, error->errmess);
ro_warn_user("WimpError", error->errmess);
return false;
}
@@ -1116,7 +1172,8 @@ void ro_gui_scroll(wimp_scroll *scroll)
error = xwimp_open_window((wimp_open *) scroll);
if (error) {
- LOG("xwimp_open_window: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_open_window: 0x%x: %s",
+ error->errnum, error->errmess);
}
}
diff --git a/frontends/riscos/wimp_event.c b/frontends/riscos/wimp_event.c
index 015e87baf..cdca470da 100644
--- a/frontends/riscos/wimp_event.c
+++ b/frontends/riscos/wimp_event.c
@@ -156,7 +156,9 @@ bool ro_gui_wimp_event_memorise(wimp_w w)
ro_gui_get_icon_string(window->w, event->i));
if (!event->previous_value.textual) {
error = true;
- LOG("Unable to store state for icon %i", event->i);
+ NSLOG(netsurf, INFO,
+ "Unable to store state for icon %i",
+ event->i);
}
break;
case EVENT_CHECKBOX:
@@ -267,7 +269,10 @@ bool ro_gui_wimp_event_transfer(wimp_w from, wimp_w to)
struct event_window *window;
int h;
- LOG("Transferring all events from window 0x%x to window 0x%x", (unsigned int)from, (unsigned int)to);
+ NSLOG(netsurf, INFO,
+ "Transferring all events from window 0x%x to window 0x%x",
+ (unsigned int)from,
+ (unsigned int)to);
window = ro_gui_wimp_event_remove_window(from);
if (window == NULL || window->w != from)
@@ -293,7 +298,8 @@ void ro_gui_wimp_event_finalise(wimp_w w)
struct event_window *window;
struct icon_event *event;
- LOG("Removing all events for window 0x%x", (unsigned int)w);
+ NSLOG(netsurf, INFO, "Removing all events for window 0x%x",
+ (unsigned int)w);
window = ro_gui_wimp_event_remove_window(w);
if (!window)
return;
@@ -330,7 +336,8 @@ void ro_gui_wimp_event_deregister(wimp_w w, wimp_i i)
struct event_window *window;
struct icon_event *event, *parent, *child;
- LOG("Removing all events for window 0x%x, icon %d", (unsigned int)w, (int)i);
+ NSLOG(netsurf, INFO, "Removing all events for window 0x%x, icon %d",
+ (unsigned int)w, (int)i);
window = ro_gui_wimp_event_get_window(w);
if (!window)
return;
@@ -344,7 +351,8 @@ void ro_gui_wimp_event_deregister(wimp_w w, wimp_i i)
child = event->next;
if (event->i == i) {
- LOG("Removing event 0x%x", (unsigned int)event);
+ NSLOG(netsurf, INFO, "Removing event 0x%x",
+ (unsigned int)event);
if (parent == NULL)
window->first = child;
@@ -576,7 +584,8 @@ bool ro_gui_wimp_event_menu_selection(wimp_w w, wimp_i i, wimp_menu *menu,
ic.i = event->data.menu_gright.field;
error = xwimp_get_icon_state(&ic);
if (error) {
- LOG("xwimp_get_icon_state: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_get_icon_state: 0x%x: %s",
+ error->errnum, error->errmess);
ro_warn_user("WimpError", error->errmess);
return false;
}
@@ -586,7 +595,8 @@ bool ro_gui_wimp_event_menu_selection(wimp_w w, wimp_i i, wimp_menu *menu,
return prepared;
error = xwimp_get_caret_position(&caret);
if (error) {
- LOG("xwimp_get_caret_position: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_get_caret_position: 0x%x: %s",
+ error->errnum, error->errmess);
ro_warn_user("WimpError", error->errmess);
return false;
}
@@ -594,7 +604,10 @@ bool ro_gui_wimp_event_menu_selection(wimp_w w, wimp_i i, wimp_menu *menu,
error = xwimp_set_caret_position(window->w, event->data.menu_gright.field,
-1, -1, -1, strlen(menu_entry->data.indirected_text.text));
if (error) {
- LOG("xwimp_set_caret_position: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO,
+ "xwimp_set_caret_position: 0x%x: %s",
+ error->errnum,
+ error->errmess);
ro_warn_user("WimpError", error->errmess);
}
}
@@ -666,7 +679,7 @@ bool ro_gui_wimp_event_mouse_click(wimp_pointer *pointer)
for (search = window->first; search; search = search->next)
if (search->i == event->data.linked_icon) break;
if (!search) {
- LOG("Incorrect reference.");
+ NSLOG(netsurf, INFO, "Incorrect reference.");
return false;
}
stepping = search->data.numeric_field.stepping;
@@ -703,13 +716,19 @@ bool ro_gui_wimp_event_mouse_click(wimp_pointer *pointer)
open.w = pointer->w;
error = xwimp_get_window_state(&open);
if (error) {
- LOG("xwimp_get_window_state: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO,
+ "xwimp_get_window_state: 0x%x: %s",
+ error->errnum,
+ error->errmess);
ro_warn_user("WimpError", error->errmess);
return false;
}
error = xwimp_get_caret_position(&caret);
if (error) {
- LOG("xwimp_get_caret_position: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO,
+ "xwimp_get_caret_position: 0x%x: %s",
+ error->errnum,
+ error->errmess);
ro_warn_user("WimpError", error->errmess);
return false;
}
@@ -718,7 +737,10 @@ bool ro_gui_wimp_event_mouse_click(wimp_pointer *pointer)
ro_gui_menu_destroy();
error = xwimp_open_window(PTR_WIMP_OPEN(&open));
if (error) {
- LOG("xwimp_open_window: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO,
+ "xwimp_open_window: 0x%x: %s",
+ error->errnum,
+ error->errmess);
ro_warn_user("WimpError", error->errmess);
return false;
}
@@ -728,7 +750,10 @@ bool ro_gui_wimp_event_mouse_click(wimp_pointer *pointer)
caret.pos.x, caret.pos.y,
-1, caret.index);
if (error) {
- LOG("xwimp_set_caret_position: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO,
+ "xwimp_set_caret_position: 0x%x: %s",
+ error->errnum,
+ error->errmess);
ro_warn_user("WimpError", error->errmess);
}
}
@@ -796,7 +821,8 @@ void ro_gui_wimp_event_prepare_gright_menu(wimp_w w, struct icon_event *event)
ic.i = event->data.menu_gright.field;
error = xwimp_get_icon_state(&ic);
if (error) {
- LOG("xwimp_get_icon_state: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_get_icon_state: 0x%x: %s",
+ error->errnum, error->errmess);
ro_warn_user("WimpError", error->errmess);
return;
}
@@ -903,7 +929,8 @@ bool ro_gui_wimp_event_keypress(wimp_key *key)
*/
error = xosbyte1(osbyte_ALPHABET_NUMBER, 127, 0, &t_alphabet);
if (error) {
- LOG("failed reading alphabet: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "failed reading alphabet: 0x%x: %s",
+ error->errnum, error->errmess);
/* prevent any corruption of ucstable */
t_alphabet = alphabet;
}
@@ -917,7 +944,10 @@ bool ro_gui_wimp_event_keypress(wimp_key *key)
error = xserviceinternational_get_ucs_conversion_table(
alphabet, &unclaimed, &ostable);
if (error != NULL) {
- LOG("failed reading UCS conversion table: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO,
+ "failed reading UCS conversion table: 0x%x: %s",
+ error->errnum,
+ error->errmess);
/* Try using our own table instead */
ucstable = ucstable_from_alphabet(alphabet);
} else if (unclaimed) {
@@ -974,7 +1004,9 @@ bool ro_gui_wimp_event_keypress(wimp_key *key)
/* If this ever happens,
* RISC OS' UTF8 keyboard
* drivers are broken */
- LOG("unexpected UTF8 start"" byte %x (ignoring)", c);
+ NSLOG(netsurf, INFO,
+ "unexpected UTF8 start"" byte %x (ignoring)",
+ c);
return true;
}
/* Anything else is ASCII, so just
@@ -985,7 +1017,9 @@ bool ro_gui_wimp_event_keypress(wimp_key *key)
/* If this ever happens,
* RISC OS' UTF8 keyboard
* drivers are broken */
- LOG("unexpected keycode: ""%x (ignoring)", c);
+ NSLOG(netsurf, INFO,
+ "unexpected keycode: ""%x (ignoring)",
+ c);
return true;
}
@@ -1074,7 +1108,8 @@ bool ro_gui_wimp_event_close_window(wimp_w w)
{
struct event_window *window;
- LOG("Close event received for window 0x%x", (unsigned int)w);
+ NSLOG(netsurf, INFO, "Close event received for window 0x%x",
+ (unsigned int)w);
if (w == ro_gui_wimp_event_submenu)
ro_gui_wimp_event_submenu = 0;
window = ro_gui_wimp_event_find_window(w);
@@ -1615,7 +1650,8 @@ struct event_window *ro_gui_wimp_event_get_window(wimp_w w)
if (window)
return window;
- LOG("Creating structure for window 0x%x", (unsigned int)w);
+ NSLOG(netsurf, INFO, "Creating structure for window 0x%x",
+ (unsigned int)w);
window = calloc(1, sizeof(struct event_window));
if (!window)
return NULL;
diff --git a/frontends/riscos/window.c b/frontends/riscos/window.c
index 6dbcc325b..986e5c55d 100644
--- a/frontends/riscos/window.c
+++ b/frontends/riscos/window.c
@@ -206,7 +206,8 @@ gui_window_place_caret(struct gui_window *g,
error = xwimp_set_caret_position(g->window, -1,
x * 2, -(y + height) * 2, height * 2, -1);
if (error) {
- LOG("xwimp_set_caret_position: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_set_caret_position: 0x%x: %s",
+ error->errnum, error->errmess);
ro_warn_user("WimpError", error->errmess);
}
}
@@ -235,7 +236,10 @@ static void gui_window_set_extent(struct gui_window *g, int width, int height)
state.w = g->window;
error = xwimp_get_window_state(&state);
if (error) {
- LOG("xwimp_get_window_state: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO,
+ "xwimp_get_window_state: 0x%x: %s",
+ error->errnum,
+ error->errmess);
ro_warn_user("WimpError", error->errmess);
return;
}
@@ -266,7 +270,8 @@ static void gui_window_set_extent(struct gui_window *g, int width, int height)
os_box extent = { 0, -height, width, toolbar_height };
error = xwimp_set_extent(g->window, &extent);
if (error) {
- LOG("xwimp_set_extent: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_set_extent: 0x%x: %s",
+ error->errnum, error->errmess);
ro_warn_user("WimpError", error->errmess);
return;
}
@@ -309,7 +314,8 @@ static void ro_gui_window_open(wimp_open *open)
state.w = g->window;
error = xwimp_get_window_state_and_nesting(&state, &parent, &linkage);
if (error) {
- LOG("xwimp_get_window_state: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_get_window_state: 0x%x: %s",
+ error->errnum, error->errmess);
ro_warn_user("WimpError", error->errmess);
return;
}
@@ -414,7 +420,8 @@ static void ro_gui_window_open(wimp_open *open)
error = xwimp_open_window_nested_with_flags(&state, parent, linkage);
if (error) {
- LOG("xwimp_open_window: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_open_window: 0x%x: %s",
+ error->errnum, error->errmess);
ro_warn_user("WimpError", error->errmess);
return;
}
@@ -453,8 +460,10 @@ static void gui_window_update_extent(struct gui_window *g)
info.w = g->window;
error = xwimp_get_window_info_header_only(&info);
if (error) {
- LOG("xwimp_get_window_info_header_only: 0x%x: %s",
- error->errnum, error->errmess);
+ NSLOG(netsurf, INFO,
+ "xwimp_get_window_info_header_only: 0x%x: %s",
+ error->errnum,
+ error->errmess);
ro_warn_user("WimpError", error->errmess);
return;
}
@@ -1046,7 +1055,8 @@ ro_gui_window_scroll_action(struct gui_window *g,
state.w = g->window;
error = xwimp_get_window_state(&state);
if (error) {
- LOG("xwimp_get_window_state: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_get_window_state: 0x%x: %s",
+ error->errnum, error->errmess);
return;
}
@@ -1060,7 +1070,8 @@ ro_gui_window_scroll_action(struct gui_window *g,
error = xwimp_get_pointer_info(&pointer);
if (error) {
- LOG("xwimp_get_pointer_info 0x%x : %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_get_pointer_info 0x%x : %s",
+ error->errnum, error->errmess);
ro_warn_user("WimpError", error->errmess);
return;
}
@@ -1180,7 +1191,8 @@ ro_gui_window_scroll_action(struct gui_window *g,
error = xwimp_open_window((wimp_open *) &state);
if (error) {
- LOG("xwimp_open_window: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_open_window: 0x%x: %s",
+ error->errnum, error->errmess);
}
}
}
@@ -1218,7 +1230,8 @@ ro_gui_window_handle_local_keypress(struct gui_window *g,
ro_error = xwimp_get_pointer_info(&pointer);
if (ro_error) {
- LOG("xwimp_get_pointer_info: 0x%x: %s\n", ro_error->errnum, ro_error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_get_pointer_info: 0x%x: %s\n",
+ ro_error->errnum, ro_error->errmess);
ro_warn_user("WimpError", ro_error->errmess);
return false;
}
@@ -1528,8 +1541,8 @@ static void ro_gui_window_close(wimp_w w)
error = xwimp_get_pointer_info(&pointer);
if (error) {
- LOG("xwimp_get_pointer_info: 0x%x: %s",
- error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_get_pointer_info: 0x%x: %s",
+ error->errnum, error->errmess);
ro_warn_user("WimpError", error->errmess);
return;
}
@@ -1559,7 +1572,10 @@ static void ro_gui_window_close(wimp_w w)
}
error = xos_cli(temp_name);
if (error) {
- LOG("xos_cli: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO,
+ "xos_cli: 0x%x: %s",
+ error->errnum,
+ error->errmess);
ro_warn_user("MiscError", error->errmess);
return;
}
@@ -1611,7 +1627,8 @@ static void ro_gui_window_redraw(wimp_draw *redraw)
error = xwimp_redraw_window(redraw, &more);
if (error) {
- LOG("xwimp_redraw_window: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_redraw_window: 0x%x: %s",
+ error->errnum, error->errmess);
ro_warn_user("WimpError", error->errmess);
return;
}
@@ -1653,7 +1670,8 @@ static void ro_gui_window_redraw(wimp_draw *redraw)
if (error && !(ro_gui_current_redraw_gui->
option.buffer_everything &&
error->errnum == error_WIMP_GET_RECT)) {
- LOG("xwimp_get_rectangle: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_get_rectangle: 0x%x: %s",
+ error->errnum, error->errmess);
ro_warn_user("WimpError", error->errmess);
ro_gui_current_redraw_gui = NULL;
return;
@@ -1971,7 +1989,7 @@ ro_gui_window_prepare_form_select_menu(struct gui_window *g,
if (err != NSERROR_OK) {
/* badenc should never happen */
assert(err != NSERROR_BAD_ENCODING);
- LOG("utf8_to_local_encoding failed");
+ NSLOG(netsurf, INFO, "utf8_to_local_encoding failed");
ro_warn_user("NoMemory", 0);
ro_gui_menu_destroy();
return false;
@@ -1997,7 +2015,7 @@ ro_gui_window_prepare_form_select_menu(struct gui_window *g,
temp = cnv_space2nbsp(option->text);
if (!temp) {
- LOG("cnv_space2nbsp failed");
+ NSLOG(netsurf, INFO, "cnv_space2nbsp failed");
ro_warn_user("NoMemory", 0);
ro_gui_menu_destroy();
return false;
@@ -2009,7 +2027,7 @@ ro_gui_window_prepare_form_select_menu(struct gui_window *g,
/* A bad encoding should never happen,
* so assert this */
assert(err != NSERROR_BAD_ENCODING);
- LOG("utf8_to_enc failed");
+ NSLOG(netsurf, INFO, "utf8_to_enc failed");
ro_warn_user("NoMemory", 0);
ro_gui_menu_destroy();
return false;
@@ -2831,7 +2849,10 @@ ro_gui_window_menu_select(wimp_w w,
state.w = w;
oserror = xwimp_get_window_state(&state);
if (oserror) {
- LOG("xwimp_get_window_state: 0x%x: %s", oserror->errnum, oserror->errmess);
+ NSLOG(netsurf, INFO,
+ "xwimp_get_window_state: 0x%x: %s",
+ oserror->errnum,
+ oserror->errmess);
ro_warn_user("WimpError", oserror->errmess);
}
nsoption_set_int(window_x, state.visible.x0);
@@ -3209,7 +3230,10 @@ static struct gui_window *gui_window_create(struct browser_window *bw,
state.w = existing->window;
error = xwimp_get_window_state(&state);
if (error) {
- LOG("xwimp_get_window_state: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO,
+ "xwimp_get_window_state: 0x%x: %s",
+ error->errnum,
+ error->errmess);
ro_warn_user("WimpError", error->errmess);
}
window.visible.x0 = state.visible.x0;
@@ -3313,7 +3337,8 @@ static struct gui_window *gui_window_create(struct browser_window *bw,
error = xwimp_create_window(&window, &g->window);
if (error) {
- LOG("xwimp_create_window: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_create_window: 0x%x: %s",
+ error->errnum, error->errmess);
ro_warn_user("WimpError", error->errmess);
free(g);
return 0;
@@ -3382,8 +3407,8 @@ static struct gui_window *gui_window_create(struct browser_window *bw,
state.w = g->window;
error = xwimp_get_window_state(&state);
if (error) {
- LOG("xwimp_get_window_state: 0x%x: %s",
- error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_get_window_state: 0x%x: %s",
+ error->errnum, error->errmess);
ro_warn_user("WimpError", error->errmess);
return g;
}
@@ -3459,7 +3484,8 @@ static void gui_window_destroy(struct gui_window *g)
/* delete window */
error = xwimp_delete_window(w);
if (error) {
- LOG("xwimp_delete_window: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_delete_window: 0x%x: %s",
+ error->errnum, error->errmess);
ro_warn_user("WimpError", error->errmess);
}
ro_gui_wimp_event_finalise(w);
@@ -3515,7 +3541,8 @@ static bool gui_window_get_scroll(struct gui_window *g, int *sx, int *sy)
state.w = g->window;
error = xwimp_get_window_state(&state);
if (error) {
- LOG("xwimp_get_window_state: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_get_window_state: 0x%x: %s",
+ error->errnum, error->errmess);
ro_warn_user("WimpError", error->errmess);
return false;
}
@@ -3550,8 +3577,8 @@ gui_window_set_scroll(struct gui_window *g, const struct rect *rect)
state.w = g->window;
error = xwimp_get_window_state(&state);
if (error) {
- LOG("xwimp_get_window_state: 0x%x: %s",
- error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_get_window_state: 0x%x: %s",
+ error->errnum, error->errmess);
ro_warn_user("WimpError", error->errmess);
return NSERROR_BAD_PARAMETER;
}
@@ -3731,8 +3758,8 @@ static void gui_window_remove_caret(struct gui_window *g)
error = xwimp_get_caret_position(&caret);
if (error) {
- LOG("xwimp_get_caret_position: 0x%x: %s",
- error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_get_caret_position: 0x%x: %s",
+ error->errnum, error->errmess);
ro_warn_user("WimpError", error->errmess);
return;
}
@@ -3776,20 +3803,25 @@ static void ro_gui_window_scroll_end(wimp_dragged *drag, void *data)
error = xwimp_drag_box((wimp_drag*)-1);
if (error) {
- LOG("xwimp_drag_box: 0x%x : %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_drag_box: 0x%x : %s",
+ error->errnum, error->errmess);
ro_warn_user("WimpError", error->errmess);
}
error = xwimp_get_pointer_info(&pointer);
if (error) {
- LOG("xwimp_get_pointer_info 0x%x : %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_get_pointer_info 0x%x : %s",
+ error->errnum, error->errmess);
ro_warn_user("WimpError", error->errmess);
return;
}
error = xwimpspriteop_set_pointer_shape("ptr_default", 0x31, 0, 0, 0, 0);
if (error) {
- LOG("xwimpspriteop_set_pointer_shape: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO,
+ "xwimpspriteop_set_pointer_shape: 0x%x: %s",
+ error->errnum,
+ error->errmess);
ro_warn_user("WimpError", error->errmess);
}
@@ -3814,7 +3846,8 @@ static bool gui_window_scroll_start(struct gui_window *g)
error = xwimp_get_pointer_info(&pointer);
if (error) {
- LOG("xwimp_get_pointer_info 0x%x : %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_get_pointer_info 0x%x : %s",
+ error->errnum, error->errmess);
ro_warn_user("WimpError", error->errmess);
return false;
}
@@ -3822,7 +3855,8 @@ static bool gui_window_scroll_start(struct gui_window *g)
info.w = g->window;
error = xwimp_get_window_info_header_only((wimp_window_info*)&info);
if (error) {
- LOG("xwimp_get_window_state: 0x%x : %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_get_window_state: 0x%x : %s",
+ error->errnum, error->errmess);
ro_warn_user("WimpError", error->errmess);
return false;
}
@@ -3844,7 +3878,8 @@ static bool gui_window_scroll_start(struct gui_window *g)
error = xwimp_drag_box(&drag);
if (error) {
- LOG("xwimp_drag_box: 0x%x : %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_drag_box: 0x%x : %s",
+ error->errnum, error->errmess);
ro_warn_user("WimpError", error->errmess);
return false;
}
@@ -3876,7 +3911,10 @@ gui_window_drag_start(struct gui_window *g,
* duration */
os_error *error = xwimp_get_pointer_info(&pointer);
if (error) {
- LOG("xwimp_get_pointer_info 0x%x : %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO,
+ "xwimp_get_pointer_info 0x%x : %s",
+ error->errnum,
+ error->errmess);
ro_warn_user("WimpError", error->errmess);
return false;
}
@@ -3893,7 +3931,8 @@ gui_window_drag_start(struct gui_window *g,
error = xwimp_drag_box(&drag);
if (error) {
- LOG("xwimp_drag_box: 0x%x : %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_drag_box: 0x%x : %s",
+ error->errnum, error->errmess);
ro_warn_user("WimpError", error->errmess);
return false;
}
@@ -3955,7 +3994,8 @@ gui_window_create_form_select_menu(struct gui_window *g,
error = xwimp_get_pointer_info(&pointer);
if (error) {
- LOG("xwimp_get_pointer_info: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_get_pointer_info: 0x%x: %s",
+ error->errnum, error->errmess);
ro_warn_user("WimpError", error->errmess);
ro_gui_menu_destroy();
return;
@@ -3988,7 +4028,8 @@ ro_gui_window_import_text(struct gui_window *g, const char *filename)
error = xosfile_read_stamped(filename, &obj_type, NULL, NULL,
&size, NULL, NULL);
if (error) {
- LOG("xosfile_read_stamped: 0x%x:%s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xosfile_read_stamped: 0x%x:%s",
+ error->errnum, error->errmess);
ro_warn_user("FileError", error->errmess);
return true; /* was for us, but it didn't work! */
}
@@ -4007,7 +4048,8 @@ ro_gui_window_import_text(struct gui_window *g, const char *filename)
NULL, NULL, NULL, NULL, NULL);
if (error) {
- LOG("xosfile_load_stamped: 0x%x:%s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xosfile_load_stamped: 0x%x:%s",
+ error->errnum, error->errmess);
ro_warn_user("LoadError", error->errmess);
free(buf);
return true;
@@ -4017,7 +4059,7 @@ ro_gui_window_import_text(struct gui_window *g, const char *filename)
if (ret != NSERROR_OK) {
/* bad encoding shouldn't happen */
assert(ret != NSERROR_BAD_ENCODING);
- LOG("utf8_from_local_encoding failed");
+ NSLOG(netsurf, INFO, "utf8_from_local_encoding failed");
free(buf);
ro_warn_user("NoMemory", NULL);
return true;
@@ -4206,8 +4248,10 @@ ro_gui_window_invalidate_area(struct gui_window *g, const struct rect *rect)
info.w = g->window;
error = xwimp_get_window_info_header_only(&info);
if (error) {
- LOG("xwimp_get_window_info_header_only: 0x%x: %s",
- error->errnum, error->errmess);
+ NSLOG(netsurf, INFO,
+ "xwimp_get_window_info_header_only: 0x%x: %s",
+ error->errnum,
+ error->errmess);
ro_warn_user("WimpError", error->errmess);
return NSERROR_INVALID;
}
@@ -4216,8 +4260,8 @@ ro_gui_window_invalidate_area(struct gui_window *g, const struct rect *rect)
info.extent.x0, info.extent.y0,
info.extent.x1, info.extent.y1);
if (error) {
- LOG("xwimp_force_redraw: 0x%x: %s",
- error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_force_redraw: 0x%x: %s",
+ error->errnum, error->errmess);
ro_warn_user("WimpError", error->errmess);
return NSERROR_INVALID;
}
@@ -4251,7 +4295,7 @@ ro_gui_window_invalidate_area(struct gui_window *g, const struct rect *rect)
}
cur = malloc(sizeof(struct update_box));
if (!cur) {
- LOG("No memory for malloc.");
+ NSLOG(netsurf, INFO, "No memory for malloc.");
return NSERROR_NOMEM;
}
@@ -4323,7 +4367,8 @@ bool ro_gui_window_dataload(struct gui_window *g, wimp_message *message)
message->your_ref = message->my_ref;
error = xwimp_send_message(wimp_USER_MESSAGE, message, message->sender);
if (error) {
- LOG("xwimp_send_message: 0x%x: %s\n", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_send_message: 0x%x: %s\n",
+ error->errnum, error->errmess);
ro_warn_user("WimpError", error->errmess);
}
@@ -4375,12 +4420,14 @@ ro_gui_window_iconise(struct gui_window *g, wimp_full_message_window_info *wi)
(osspriteop_id)overlay, &width, &height, NULL,
NULL);
if (error) {
- LOG("xosspriteop_read_sprite_info: 0x%x: %s",
- error->errnum, error->errmess);
+ NSLOG(netsurf, INFO,
+ "xosspriteop_read_sprite_info: 0x%x: %s",
+ error->errnum,
+ error->errmess);
ro_warn_user("MiscError", error->errmess);
overlay = NULL;
} else if (sprite_bpp(overlay) != 8) {
- LOG("overlay sprite is not 8bpp");
+ NSLOG(netsurf, INFO, "overlay sprite is not 8bpp");
overlay = NULL;
}
}
@@ -4389,7 +4436,7 @@ ro_gui_window_iconise(struct gui_window *g, wimp_full_message_window_info *wi)
bitmap = riscos_bitmap_create(width, height,
BITMAP_NEW | BITMAP_OPAQUE | BITMAP_CLEAR_MEMORY);
if (!bitmap) {
- LOG("Thumbnail initialisation failed.");
+ NSLOG(netsurf, INFO, "Thumbnail initialisation failed.");
return;
}
riscos_bitmap_render(bitmap, h);
@@ -4399,7 +4446,7 @@ ro_gui_window_iconise(struct gui_window *g, wimp_full_message_window_info *wi)
area = riscos_bitmap_convert_8bpp(bitmap);
riscos_bitmap_destroy(bitmap);
if (!area) {
- LOG("Thumbnail conversion failed.");
+ NSLOG(netsurf, INFO, "Thumbnail conversion failed.");
return;
}
@@ -4420,7 +4467,8 @@ ro_gui_window_iconise(struct gui_window *g, wimp_full_message_window_info *wi)
error = xosspriteop_save_sprite_file(osspriteop_USER_AREA,
area, temp_fname);
if (error) {
- LOG("xosspriteop_save_sprite_file: 0x%x:%s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xosspriteop_save_sprite_file: 0x%x:%s",
+ error->errnum, error->errmess);
ro_warn_user("MiscError", error->errmess);
free(area);
return;
@@ -4428,7 +4476,10 @@ ro_gui_window_iconise(struct gui_window *g, wimp_full_message_window_info *wi)
error = xwimpspriteop_merge_sprite_file(temp_fname);
if (error) {
- LOG("xwimpspriteop_merge_sprite_file: 0x%x:%s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO,
+ "xwimpspriteop_merge_sprite_file: 0x%x:%s",
+ error->errnum,
+ error->errmess);
ro_warn_user("WimpError", error->errmess);
remove(temp_fname);
free(area);
@@ -4453,7 +4504,8 @@ ro_gui_window_iconise(struct gui_window *g, wimp_full_message_window_info *wi)
error = xwimp_send_message(wimp_USER_MESSAGE, (wimp_message*)wi,
wi->sender);
if (error) {
- LOG("xwimp_send_message: 0x%x:%s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_send_message: 0x%x:%s",
+ error->errnum, error->errmess);
ro_warn_user("WimpError", error->errmess);
}
else {
@@ -4479,7 +4531,10 @@ bool ro_gui_toolbar_dataload(struct gui_window *g, wimp_message *message)
error = xwimp_send_message(wimp_USER_MESSAGE, message,
message->sender);
if (error) {
- LOG("xwimp_send_message: 0x%x: %s\n", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO,
+ "xwimp_send_message: 0x%x: %s\n",
+ error->errnum,
+ error->errmess);
ro_warn_user("WimpError", error->errmess);
}
return true;
@@ -4536,7 +4591,8 @@ void ro_gui_window_update_boxes(void)
error = xwimp_update_window(&update, &more);
if (error) {
- LOG("xwimp_update_window: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_update_window: 0x%x: %s",
+ error->errnum, error->errmess);
ro_warn_user("WimpError", error->errmess);
continue;
}
@@ -4569,7 +4625,10 @@ void ro_gui_window_update_boxes(void)
* found. This appears to be a bug in RISC OS. */
if (error && !(use_buffer &&
error->errnum == error_WIMP_GET_RECT)) {
- LOG("xwimp_get_rectangle: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO,
+ "xwimp_get_rectangle: 0x%x: %s",
+ error->errnum,
+ error->errmess);
ro_warn_user("WimpError", error->errmess);
ro_gui_current_redraw_gui = NULL;
continue;
@@ -4685,7 +4744,8 @@ ro_gui_window_to_window_pos(struct gui_window *g, int x, int y, os_coord *pos)
state.w = g->window;
error = xwimp_get_window_state(&state);
if (error) {
- LOG("xwimp_get_window_state: 0x%x:%s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_get_window_state: 0x%x:%s",
+ error->errnum, error->errmess);
ro_warn_user("WimpError", error->errmess);
return false;
}
@@ -4709,7 +4769,8 @@ bool ro_gui_window_to_screen_pos(struct gui_window *g,
state.w = g->window;
error = xwimp_get_window_state(&state);
if (error) {
- LOG("xwimp_get_window_state: 0x%x:%s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO, "xwimp_get_window_state: 0x%x:%s",
+ error->errnum, error->errmess);
ro_warn_user("WimpError", error->errmess);
return false;
}
@@ -4913,7 +4974,10 @@ void gui_window_set_pointer(struct gui_window *g, gui_pointer_shape shape)
error = xwimpspriteop_set_pointer_shape(entry->sprite_name,
1, entry->xactive, entry->yactive, 0, 0);
if (error) {
- LOG("xwimpspriteop_set_pointer_shape: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO,
+ "xwimpspriteop_set_pointer_shape: 0x%x: %s",
+ error->errnum,
+ error->errmess);
ro_warn_user("WimpError", error->errmess);
}
} else {
@@ -4923,7 +4987,10 @@ void gui_window_set_pointer(struct gui_window *g, gui_pointer_shape shape)
(osspriteop_id) entry->sprite_name,
1, entry->xactive, entry->yactive, 0, 0);
if (error) {
- LOG("xosspriteop_set_pointer_shape: 0x%x: %s", error->errnum, error->errmess);
+ NSLOG(netsurf, INFO,
+ "xosspriteop_set_pointer_shape: 0x%x: %s",
+ error->errnum,
+ error->errmess);
ro_warn_user("WimpError", error->errmess);
}
}
diff --git a/frontends/windows/Makefile b/frontends/windows/Makefile
index bd34b465e..50d0d4b44 100644
--- a/frontends/windows/Makefile
+++ b/frontends/windows/Makefile
@@ -15,7 +15,7 @@ $(eval $(call pkg_config_find_and_add,libcares,Cares))
$(eval $(call pkg_config_find_and_add,zlib,ZLib))
# libraries for windows API
-LDFLAGS += -lgnurx -lgdi32 -lcomctl32 -lws2_32 -lmsimg32 -lshlwapi -mwindows
+LDFLAGS += -lgnurx -lgdi32 -lcomctl32 -lws2_32 -lmsimg32 -lshlwapi -lcrypt32 -mwindows
CFLAGS += -U__STRICT_ANSI__ -mwin32
# only windows versions after XP are supported
diff --git a/frontends/windows/about.c b/frontends/windows/about.c
index 65c81cd7d..2cd855b55 100644
--- a/frontends/windows/about.c
+++ b/frontends/windows/about.c
@@ -52,7 +52,7 @@ static BOOL init_about_dialog(HWND hwnd)
hFont=CreateFont (26, 0, 0, 0, FW_BOLD, FALSE, FALSE, FALSE, ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH | FF_SWISS, "Arial");
if (hFont != NULL) {
- LOG("Setting font object");
+ NSLOG(netsurf, INFO, "Setting font object");
SendMessage(dlg_itm, WM_SETFONT, (WPARAM)hFont, 0);
}
@@ -85,7 +85,7 @@ static BOOL destroy_about_dialog(HWND hwnd)
if (dlg_itm != NULL) {
hFont = (HFONT)SendMessage(dlg_itm, WM_GETFONT, 0, 0);
if (hFont != NULL) {
- LOG("Destroyed font object");
+ NSLOG(netsurf, INFO, "Destroyed font object");
DeleteObject(hFont);
}
}
@@ -107,12 +107,12 @@ nsws_about_event_callback(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
case WM_COMMAND:
switch(LOWORD(wparam)) {
case IDOK:
- LOG("OK clicked");
+ NSLOG(netsurf, INFO, "OK clicked");
EndDialog(hwnd, IDOK);
break;
case IDCANCEL:
- LOG("Cancel clicked");
+ NSLOG(netsurf, INFO, "Cancel clicked");
EndDialog(hwnd, IDOK);
break;
diff --git a/frontends/windows/bitmap.c b/frontends/windows/bitmap.c
index f60dab613..eed3d3a15 100644
--- a/frontends/windows/bitmap.c
+++ b/frontends/windows/bitmap.c
@@ -52,7 +52,8 @@ void *win32_bitmap_create(int width, int height, unsigned int state)
HBITMAP windib;
uint8_t *pixdata;
- LOG("width %d, height %d, state %u", width, height, state);
+ NSLOG(netsurf, INFO, "width %d, height %d, state %u", width, height,
+ state);
pbmi = calloc(1, sizeof(BITMAPV5HEADER));
if (pbmi == NULL) {
@@ -96,7 +97,7 @@ void *win32_bitmap_create(int width, int height, unsigned int state)
bitmap->opaque = false;
}
- LOG("bitmap %p", bitmap);
+ NSLOG(netsurf, INFO, "bitmap %p", bitmap);
return bitmap;
}
@@ -115,7 +116,7 @@ static unsigned char *bitmap_get_buffer(void *bitmap)
{
struct bitmap *bm = bitmap;
if (bitmap == NULL) {
- LOG("NULL bitmap!");
+ NSLOG(netsurf, INFO, "NULL bitmap!");
return NULL;
}
@@ -134,7 +135,7 @@ static size_t bitmap_get_rowstride(void *bitmap)
struct bitmap *bm = bitmap;
if (bitmap == NULL) {
- LOG("NULL bitmap!");
+ NSLOG(netsurf, INFO, "NULL bitmap!");
return 0;
}
@@ -152,7 +153,7 @@ void win32_bitmap_destroy(void *bitmap)
struct bitmap *bm = bitmap;
if (bitmap == NULL) {
- LOG("NULL bitmap!");
+ NSLOG(netsurf, INFO, "NULL bitmap!");
return;
}
@@ -195,11 +196,12 @@ static void bitmap_set_opaque(void *bitmap, bool opaque)
struct bitmap *bm = bitmap;
if (bitmap == NULL) {
- LOG("NULL bitmap!");
+ NSLOG(netsurf, INFO, "NULL bitmap!");
return;
}
- LOG("setting bitmap %p to %s", bm, opaque ? "opaque" : "transparent");
+ NSLOG(netsurf, INFO, "setting bitmap %p to %s", bm,
+ opaque ? "opaque" : "transparent");
bm->opaque = opaque;
}
@@ -216,7 +218,7 @@ static bool bitmap_test_opaque(void *bitmap)
struct bitmap *bm = bitmap;
if (bitmap == NULL) {
- LOG("NULL bitmap!");
+ NSLOG(netsurf, INFO, "NULL bitmap!");
return false;
}
@@ -224,11 +226,11 @@ static bool bitmap_test_opaque(void *bitmap)
while (tst-- > 0) {
if (bm->pixdata[(tst << 2) + 3] != 0xff) {
- LOG("bitmap %p has transparency", bm);
+ NSLOG(netsurf, INFO, "bitmap %p has transparency", bm);
return false;
}
}
- LOG("bitmap %p is opaque", bm);
+ NSLOG(netsurf, INFO, "bitmap %p is opaque", bm);
return true;
}
@@ -243,7 +245,7 @@ static bool bitmap_get_opaque(void *bitmap)
struct bitmap *bm = bitmap;
if (bitmap == NULL) {
- LOG("NULL bitmap!");
+ NSLOG(netsurf, INFO, "NULL bitmap!");
return false;
}
@@ -255,7 +257,7 @@ static int bitmap_get_width(void *bitmap)
struct bitmap *bm = bitmap;
if (bitmap == NULL) {
- LOG("NULL bitmap!");
+ NSLOG(netsurf, INFO, "NULL bitmap!");
return 0;
}
@@ -267,7 +269,7 @@ static int bitmap_get_height(void *bitmap)
struct bitmap *bm = bitmap;
if (bitmap == NULL) {
- LOG("NULL bitmap!");
+ NSLOG(netsurf, INFO, "NULL bitmap!");
return 0;
}
@@ -324,12 +326,12 @@ bitmap_render(struct bitmap *bitmap, struct hlcache_handle *content)
.plot = &win_plotters
};
- width = min(content_get_width(content), 1024);
+ width = min(max(content_get_width(content), bitmap->width), 1024);
height = ((width * bitmap->height) + (bitmap->width / 2)) /
bitmap->width;
- LOG("bitmap %p for content %p width %d, height %d",
- bitmap, content, width, height);
+ NSLOG(netsurf, INFO, "bitmap %p for content %p width %d, height %d",
+ bitmap, content, width, height);
/* create two memory device contexts to put the bitmaps in */
bufferdc = CreateCompatibleDC(NULL);
diff --git a/frontends/windows/corewindow.c b/frontends/windows/corewindow.c
index 3c31c5e46..7d88ce7c4 100644
--- a/frontends/windows/corewindow.c
+++ b/frontends/windows/corewindow.c
@@ -155,7 +155,7 @@ nsw32_corewindow_vscroll(struct nsw32_corewindow *nsw32_cw,
SCROLLINFO si; /* current scroll information */
SCROLLINFO usi; /* updated scroll infomation for scrollwindowex */
- LOG("VSCROLL");
+ NSLOG(netsurf, INFO, "VSCROLL");
si.cbSize = sizeof(si);
si.fMask = SIF_ALL;
@@ -230,7 +230,7 @@ nsw32_corewindow_hscroll(struct nsw32_corewindow *nsw32_cw,
SCROLLINFO si; /* current scroll information */
SCROLLINFO usi; /* updated scroll infomation for scrollwindowex */
- LOG("VSCROLL");
+ NSLOG(netsurf, INFO, "VSCROLL");
si.cbSize = sizeof(si);
si.fMask = SIF_ALL;
@@ -450,7 +450,7 @@ nsw32_cw_update_size(struct core_window *cw, int width, int height)
nsw32_cw->content_width = width;
nsw32_cw->content_height = height;
- LOG("new content size w:%d h:%d", width, height);
+ NSLOG(netsurf, INFO, "new content size w:%d h:%d", width, height);
update_scrollbars(nsw32_cw);
}
@@ -527,7 +527,7 @@ nsw32_corewindow_init(HINSTANCE hInstance,
CS_DBLCLKS;
}
- LOG("creating hInstance %p core window", hInstance);
+ NSLOG(netsurf, INFO, "creating hInstance %p core window", hInstance);
nsw32_cw->hWnd = CreateWindowEx(0,
windowclassname_corewindow,
nsw32_cw->title,
@@ -541,7 +541,7 @@ nsw32_corewindow_init(HINSTANCE hInstance,
hInstance,
NULL);
if (nsw32_cw->hWnd == NULL) {
- LOG("Window create failed");
+ NSLOG(netsurf, INFO, "Window create failed");
return NSERROR_NOMEM;
}
diff --git a/frontends/windows/download.c b/frontends/windows/download.c
index 3a969834e..dfcd2b5a4 100644
--- a/frontends/windows/download.c
+++ b/frontends/windows/download.c
@@ -253,7 +253,8 @@ gui_download_window_create(download_context *ctx, struct gui_window *gui)
strcat(destination, "/");
if (strlen(destination) + strlen(filename) < PATH_MAX - 1)
strcat(destination, filename);
- LOG("download %s [%s] from %s to %s", filename, size, domain, destination);
+ NSLOG(netsurf, INFO, "download %s [%s] from %s to %s", filename,
+ size, domain, destination);
w->title = filename;
w->domain = domain;
w->size = total_size;
@@ -313,7 +314,8 @@ gui_download_window_data(struct gui_download_window *w, const char *data,
struct timeval val;
res = fwrite((void *)data, 1, size, w->file);
if (res != size)
- LOG("file write error %d of %d", size - res, size);
+ NSLOG(netsurf, INFO, "file write error %d of %d", size - res,
+ size);
w->downloaded += res;
w->progress = (unsigned int)(((long long)(w->downloaded) * 10000)
/ w->size);
@@ -327,7 +329,7 @@ gui_download_window_data(struct gui_download_window *w, const char *data,
static void gui_download_window_error(struct gui_download_window *w,
const char *error_msg)
{
- LOG("error %s", error_msg);
+ NSLOG(netsurf, INFO, "error %s", error_msg);
}
static void gui_download_window_done(struct gui_download_window *w)
diff --git a/frontends/windows/drawable.c b/frontends/windows/drawable.c
index 28a76cfe8..f491e0a2a 100644
--- a/frontends/windows/drawable.c
+++ b/frontends/windows/drawable.c
@@ -83,7 +83,7 @@ nsws_drawable_vscroll(struct gui_window *gw, HWND hwnd, WPARAM wparam)
SCROLLINFO si;
int mem;
- LOG("VSCROLL %d", gw->requestscrolly);
+ NSLOG(netsurf, INFO, "VSCROLL %d", gw->requestscrolly);
if (gw->requestscrolly != 0)
return 0;
@@ -157,7 +157,7 @@ nsws_drawable_hscroll(struct gui_window *gw, HWND hwnd, WPARAM wparam)
SCROLLINFO si;
int mem;
- LOG("HSCROLL %d", gw->requestscrollx);
+ NSLOG(netsurf, INFO, "HSCROLL %d", gw->requestscrollx);
if (gw->requestscrollx != 0)
return 0;
@@ -369,7 +369,8 @@ nsws_drawable_mouseup(struct gui_window *gw,
(gw->bw == NULL))
return 0;
- LOG("state 0x%x, press 0x%x", gw->mouse->state, press);
+ NSLOG(netsurf, INFO, "state 0x%x, press 0x%x", gw->mouse->state,
+ press);
if ((gw->mouse->state & press) != 0) {
gw->mouse->state &= ~press;
gw->mouse->state |= click;
@@ -383,10 +384,10 @@ nsws_drawable_mouseup(struct gui_window *gw,
gw->mouse->state &= ~BROWSER_MOUSE_MOD_3;
if ((gw->mouse->state & click) != 0) {
- LOG("mouse click bw %p, state 0x%x, x %f, y %f",
- gw->bw, gw->mouse->state,
- (x + gw->scrollx) / gw->scale,
- (y + gw->scrolly) / gw->scale);
+ NSLOG(netsurf, INFO,
+ "mouse click bw %p, state 0x%x, x %f, y %f", gw->bw,
+ gw->mouse->state, (x + gw->scrollx) / gw->scale,
+ (y + gw->scrolly) / gw->scale);
browser_window_mouse_click(gw->bw,
gw->mouse->state,
@@ -430,10 +431,9 @@ nsws_drawable_mousedown(struct gui_window *gw,
gw->mouse->pressed_x = (x + gw->scrollx) / gw->scale;
gw->mouse->pressed_y = (y + gw->scrolly) / gw->scale;
- LOG("mouse click bw %p, state %x, x %f, y %f",
- gw->bw, gw->mouse->state,
- (x + gw->scrollx) / gw->scale,
- (y + gw->scrolly) / gw->scale);
+ NSLOG(netsurf, INFO, "mouse click bw %p, state %x, x %f, y %f",
+ gw->bw, gw->mouse->state, (x + gw->scrollx) / gw->scale,
+ (y + gw->scrolly) / gw->scale);
browser_window_mouse_click(gw->bw, gw->mouse->state,
(x + gw->scrollx) / gw->scale,
@@ -466,7 +466,8 @@ nsws_drawable_mousemove(struct gui_window *gw, int x, int y)
(abs(x - gw->mouse->pressed_x) >= 5) &&
(abs(y - gw->mouse->pressed_y) >= 5)) {
- LOG("Drag start state 0x%x", gw->mouse->state);
+ NSLOG(netsurf, INFO, "Drag start state 0x%x",
+ gw->mouse->state);
if ((gw->mouse->state & BROWSER_MOUSE_PRESS_1) != 0) {
browser_window_mouse_click(gw->bw, BROWSER_MOUSE_DRAG_1,
@@ -515,7 +516,8 @@ nsws_window_drawable_event_callback(HWND hwnd,
gw = nsws_get_gui_window(hwnd);
if (gw == NULL) {
- LOG("Unable to find gui window structure for hwnd %p", hwnd);
+ NSLOG(netsurf, INFO,
+ "Unable to find gui window structure for hwnd %p", hwnd);
return DefWindowProc(hwnd, msg, wparam, lparam);
}
@@ -604,7 +606,7 @@ nsws_window_create_drawable(HINSTANCE hinstance,
if (hwnd == NULL) {
win_perror("WindowCreateDrawable");
- LOG("Window creation failed");
+ NSLOG(netsurf, INFO, "Window creation failed");
return NULL;
}
diff --git a/frontends/windows/filetype.c b/frontends/windows/filetype.c
index d31434aeb..a5fd9e95e 100644
--- a/frontends/windows/filetype.c
+++ b/frontends/windows/filetype.c
@@ -39,7 +39,7 @@
static const char *fetch_filetype(const char *unix_path)
{
int l;
- LOG("unix path %s", unix_path);
+ NSLOG(netsurf, INFO, "unix path %s", unix_path);
l = strlen(unix_path);
if (2 < l && strcasecmp(unix_path + l - 3, "css") == 0)
return "text/css";
diff --git a/frontends/windows/findfile.c b/frontends/windows/findfile.c
index e1c9595eb..e665530ba 100644
--- a/frontends/windows/findfile.c
+++ b/frontends/windows/findfile.c
@@ -99,7 +99,7 @@ char *nsws_find_resource(char *buf, const char *filename, const char *def)
char t[PATH_MAX];
if (cdir != NULL) {
- LOG("Found Home %s", cdir);
+ NSLOG(netsurf, INFO, "Found Home %s", cdir);
strcpy(t, cdir);
strcat(t, "/.netsurf/");
strcat(t, filename);
@@ -126,7 +126,7 @@ char *nsws_find_resource(char *buf, const char *filename, const char *def)
getcwd(t, PATH_MAX - SLEN("\\res\\") - strlen(filename));
strcat(t, "\\res\\");
strcat(t, filename);
- LOG("looking in %s", t);
+ NSLOG(netsurf, INFO, "looking in %s", t);
if ((realpath(t, buf) != NULL) && (access(buf, R_OK) == 0))
return buf;
diff --git a/frontends/windows/font.c b/frontends/windows/font.c
index 75464f992..37ccf23fe 100644
--- a/frontends/windows/font.c
+++ b/frontends/windows/font.c
@@ -309,10 +309,11 @@ win32_font_split(const plot_font_style_t *style,
}
}
-/*
- LOG("ret %d Split %u chars at %ipx: Split at char %i (%ipx) - %.*s",
- ret, length, x, *char_offset, *actual_x, *char_offset, string);
-*/
+
+ NSLOG(netsurf, DEEPDEBUG,
+ "ret %d Split %u chars at %ipx: Split at char %i (%ipx) - %.*s",
+ ret, length, x, *char_offset, *actual_x, *char_offset, string);
+
return ret;
}
diff --git a/frontends/windows/gui.c b/frontends/windows/gui.c
index 602dcd445..890bfae42 100644
--- a/frontends/windows/gui.c
+++ b/frontends/windows/gui.c
@@ -66,7 +66,7 @@ void win32_run(void)
int timeout; /* timeout in miliseconds */
UINT timer_id = 0;
- LOG("Starting messgae dispatcher");
+ NSLOG(netsurf, INFO, "Starting messgae dispatcher");
while (!win32_quit) {
/* run the scheduler and discover how long to wait for
@@ -128,7 +128,7 @@ static void gui_get_clipboard(char **buffer, size_t *length)
clipboard_handle = GetClipboardData(CF_TEXT);
if (clipboard_handle != NULL) {
content = GlobalLock(clipboard_handle);
- LOG("pasting %s", content);
+ NSLOG(netsurf, INFO, "pasting %s", content);
GlobalUnlock(clipboard_handle);
}
}
diff --git a/frontends/windows/main.c b/frontends/windows/main.c
index d019f10c7..a3a7c2b39 100644
--- a/frontends/windows/main.c
+++ b/frontends/windows/main.c
@@ -99,7 +99,7 @@ static nserror get_config_home(char **config_home_out)
*config_home_out = strdup(adPath);
- LOG("using config path \"%s\"", *config_home_out);
+ NSLOG(netsurf, INFO, "using config path \"%s\"", *config_home_out);
return NSERROR_OK;
}
@@ -343,15 +343,16 @@ WinMain(HINSTANCE hInstance, HINSTANCE hLastInstance, LPSTR lpcli, int ncmd)
/* Locate the correct user configuration directory path */
ret = get_config_home(&nsw32_config_home);
if (ret != NSERROR_OK) {
- LOG("Unable to locate a configuration directory.");
+ NSLOG(netsurf, INFO,
+ "Unable to locate a configuration directory.");
nsw32_config_home = NULL;
}
/* Initialise user options */
ret = nsw32_option_init(&argc, argv);
if (ret != NSERROR_OK) {
- LOG("Options failed to initialise (%s)\n",
- messages_get_errorcode(ret));
+ NSLOG(netsurf, INFO, "Options failed to initialise (%s)\n",
+ messages_get_errorcode(ret));
return 1;
}
@@ -365,7 +366,7 @@ WinMain(HINSTANCE hInstance, HINSTANCE hLastInstance, LPSTR lpcli, int ncmd)
/* common initialisation */
ret = netsurf_init(NULL);
if (ret != NSERROR_OK) {
- LOG("NetSurf failed to initialise");
+ NSLOG(netsurf, INFO, "NetSurf failed to initialise");
return 1;
}
@@ -392,7 +393,7 @@ WinMain(HINSTANCE hInstance, HINSTANCE hLastInstance, LPSTR lpcli, int ncmd)
addr = NETSURF_HOMEPAGE;
}
- LOG("calling browser_window_create");
+ NSLOG(netsurf, INFO, "calling browser_window_create");
ret = nsurl_create(addr, &url);
if (ret == NSERROR_OK) {
@@ -418,5 +419,8 @@ WinMain(HINSTANCE hInstance, HINSTANCE hLastInstance, LPSTR lpcli, int ncmd)
/* finalise options */
nsoption_finalise(nsoptions, nsoptions_default);
+ /* finalise logging */
+ nslog_finalise();
+
return 0;
}
diff --git a/frontends/windows/plot.c b/frontends/windows/plot.c
index 1bd0ba4a0..3668e4bb6 100644
--- a/frontends/windows/plot.c
+++ b/frontends/windows/plot.c
@@ -41,16 +41,6 @@
#include "windows/gui.h"
#include "windows/plot.h"
-
-/* set NSWS_PLOT_DEBUG to 0 for no debugging, 1 for debugging */
-/* #define NSWS_PLOT_DEBUG */
-
-#ifdef NSWS_PLOT_DEBUG
-#define PLOT_LOG(x...) LOG(x)
-#else
-#define PLOT_LOG(x...) ((void) 0)
-#endif
-
HDC plot_hdc;
/** currently set clipping rectangle */
@@ -84,7 +74,7 @@ plot_block(COLORREF col, int x, int y, int width, int height)
/* ensure the plot HDC is set */
if (plot_hdc == NULL) {
- LOG("HDC not set on call to plotters");
+ NSLOG(netsurf, INFO, "HDC not set on call to plotters");
return NSERROR_INVALID;
}
@@ -159,9 +149,9 @@ plot_alpha_bitmap(HDC hdc,
BITMAPINFO *bmi;
HBITMAP MemBMh;
- PLOT_LOG("%p bitmap %d,%d width %d height %d",
+ NSLOG(plot, DEEPDEBUG, "%p bitmap %d,%d width %d height %d",
bitmap, x, y, width, height);
- PLOT_LOG("clipped %ld,%ld to %ld,%ld",
+ NSLOG(plot, DEEPDEBUG, "clipped %ld,%ld to %ld,%ld",
plot_clip.left, plot_clip.top,
plot_clip.right, plot_clip.bottom);
@@ -172,7 +162,7 @@ plot_alpha_bitmap(HDC hdc,
if ((bitmap->width != width) ||
(bitmap->height != height)) {
- PLOT_LOG("scaling from %d,%d to %d,%d",
+ NSLOG(plot, DEEPDEBUG, "scaling from %d,%d to %d,%d",
bitmap->width, bitmap->height, width, height);
bitmap = bitmap_scale(bitmap, width, height);
if (bitmap == NULL) {
@@ -299,7 +289,7 @@ plot_bitmap(struct bitmap *bitmap, int x, int y, int width, int height)
/* ensure the plot HDC is set */
if (plot_hdc == NULL) {
- LOG("HDC not set on call to plotters");
+ NSLOG(netsurf, INFO, "HDC not set on call to plotters");
return NSERROR_INVALID;
}
@@ -344,7 +334,7 @@ plot_bitmap(struct bitmap *bitmap, int x, int y, int width, int height)
if (bltres == 0) {
res = NSERROR_INVALID;
}
- PLOT_LOG("bltres = %d", bltres);
+ NSLOG(plot, DEEPDEBUG, "bltres = %d", bltres);
} else {
/* Bitmap with alpha.*/
res = plot_alpha_bitmap(plot_hdc, bitmap, x, y, width, height);
@@ -366,7 +356,7 @@ plot_bitmap(struct bitmap *bitmap, int x, int y, int width, int height)
*/
static nserror clip(const struct redraw_context *ctx, const struct rect *clip)
{
- PLOT_LOG("clip %d,%d to %d,%d", clip->x0, clip->y0, clip->x1, clip->y1);
+ NSLOG(plot, DEEPDEBUG, "clip %d,%d to %d,%d", clip->x0, clip->y0, clip->x1, clip->y1);
plot_clip.left = clip->x0;
plot_clip.top = clip->y0;
@@ -399,12 +389,12 @@ arc(const struct redraw_context *ctx,
int x, int y,
int radius, int angle1, int angle2)
{
- PLOT_LOG("arc centre %d,%d radius %d from %d to %d", x, y, radius,
+ NSLOG(plot, DEEPDEBUG, "arc centre %d,%d radius %d from %d to %d", x, y, radius,
angle1, angle2);
/* ensure the plot HDC is set */
if (plot_hdc == NULL) {
- LOG("HDC not set on call to plotters");
+ NSLOG(netsurf, INFO, "HDC not set on call to plotters");
return NSERROR_INVALID;
}
@@ -511,11 +501,11 @@ disc(const struct redraw_context *ctx,
const plot_style_t *style,
int x, int y, int radius)
{
- PLOT_LOG("disc at %d,%d radius %d", x, y, radius);
+ NSLOG(plot, DEEPDEBUG, "disc at %d,%d radius %d", x, y, radius);
/* ensure the plot HDC is set */
if (plot_hdc == NULL) {
- LOG("HDC not set on call to plotters");
+ NSLOG(netsurf, INFO, "HDC not set on call to plotters");
return NSERROR_INVALID;
}
@@ -590,11 +580,12 @@ line(const struct redraw_context *ctx,
const plot_style_t *style,
const struct rect *line)
{
- PLOT_LOG("from %d,%d to %d,%d", x0, y0, x1, y1);
+ NSLOG(plot, DEEPDEBUG, "from %d,%d to %d,%d",
+ line->x0, line->y0, line->x1, line->y1);
/* ensure the plot HDC is set */
if (plot_hdc == NULL) {
- LOG("HDC not set on call to plotters");
+ NSLOG(netsurf, INFO, "HDC not set on call to plotters");
return NSERROR_INVALID;
}
@@ -656,12 +647,12 @@ rectangle(const struct redraw_context *ctx,
const plot_style_t *style,
const struct rect *rect)
{
- PLOT_LOG("rectangle from %d,%d to %d,%d",
+ NSLOG(plot, DEEPDEBUG, "rectangle from %d,%d to %d,%d",
rect->x0, rect->y0, rect->x1, rect->y1);
/* ensure the plot HDC is set */
if (plot_hdc == NULL) {
- LOG("HDC not set on call to plotters");
+ NSLOG(netsurf, INFO, "HDC not set on call to plotters");
return NSERROR_INVALID;
}
@@ -740,11 +731,11 @@ polygon(const struct redraw_context *ctx,
const int *p,
unsigned int n)
{
- PLOT_LOG("polygon %d points", n);
+ NSLOG(plot, DEEPDEBUG, "polygon %d points", n);
/* ensure the plot HDC is set */
if (plot_hdc == NULL) {
- LOG("HDC not set on call to plotters");
+ NSLOG(netsurf, INFO, "HDC not set on call to plotters");
return NSERROR_INVALID;
}
@@ -788,7 +779,7 @@ polygon(const struct redraw_context *ctx,
points[i].x = (long) p[2 * i];
points[i].y = (long) p[2 * i + 1];
- PLOT_LOG("%ld,%ld ", points[i].x, points[i].y);
+ NSLOG(plot, DEEPDEBUG, "%ld,%ld ", points[i].x, points[i].y);
}
SelectClipRgn(plot_hdc, clipregion);
@@ -831,7 +822,7 @@ path(const struct redraw_context *ctx,
float width,
const float transform[6])
{
- PLOT_LOG("path unimplemented");
+ NSLOG(plot, DEEPDEBUG, "path unimplemented");
return NSERROR_OK;
}
@@ -875,10 +866,10 @@ bitmap(const struct redraw_context *ctx,
/* Bail early if we can */
- PLOT_LOG("Plotting %p at %d,%d by %d,%d",bitmap, x,y,width,height);
+ NSLOG(plot, DEEPDEBUG, "Plotting %p at %d,%d by %d,%d",bitmap, x,y,width,height);
if (bitmap == NULL) {
- LOG("Passed null bitmap!");
+ NSLOG(netsurf, INFO, "Passed null bitmap!");
return NSERROR_OK;
}
@@ -937,8 +928,8 @@ bitmap(const struct redraw_context *ctx,
}
}
- PLOT_LOG("Tiled plotting %d,%d by %d,%d", x, y, width, height);
- PLOT_LOG("clipped %ld,%ld to %ld,%ld",
+ NSLOG(plot, DEEPDEBUG, "Tiled plotting %d,%d by %d,%d", x, y, width, height);
+ NSLOG(plot, DEEPDEBUG, "clipped %ld,%ld to %ld,%ld",
plot_clip.left, plot_clip.top,
plot_clip.right, plot_clip.bottom);
@@ -952,7 +943,7 @@ bitmap(const struct redraw_context *ctx,
for (; y > plot_clip.top; y -= height);
}
- PLOT_LOG("repeat from %d,%d to %ld,%ld",
+ NSLOG(plot, DEEPDEBUG, "repeat from %d,%d to %ld,%ld",
x, y, plot_clip.right, plot_clip.bottom);
/* tile down and across to extents */
@@ -989,11 +980,11 @@ text(const struct redraw_context *ctx,
const char *text,
size_t length)
{
- PLOT_LOG("words %s at %d,%d", text, x, y);
+ NSLOG(plot, DEEPDEBUG, "words %s at %d,%d", text, x, y);
/* ensure the plot HDC is set */
if (plot_hdc == NULL) {
- LOG("HDC not set on call to plotters");
+ NSLOG(netsurf, INFO, "HDC not set on call to plotters");
return NSERROR_INVALID;
}
diff --git a/frontends/windows/prefs.c b/frontends/windows/prefs.c
index f84ee1c96..591b57426 100644
--- a/frontends/windows/prefs.c
+++ b/frontends/windows/prefs.c
@@ -304,7 +304,8 @@ static BOOL CALLBACK options_appearance_dialog_handler(HWND hwnd,
case WM_COMMAND:
- LOG("WM_COMMAND Identifier 0x%x",LOWORD(wparam));
+ NSLOG(netsurf, INFO, "WM_COMMAND Identifier 0x%x",
+ LOWORD(wparam));
switch(LOWORD(wparam)) {
case IDC_PREFS_PROXYTYPE:
diff --git a/frontends/windows/schedule.c b/frontends/windows/schedule.c
index eae6c1d63..76358ec68 100644
--- a/frontends/windows/schedule.c
+++ b/frontends/windows/schedule.c
@@ -25,12 +25,6 @@
#include "windows/schedule.h"
-#ifdef DEBUG_SCHEDULER
-#define SRLOG(x...) LOG(x)
-#else
-#define SRLOG(x...) ((void) 0)
-#endif
-
/* linked list of scheduled callbacks */
static struct nscallback *schedule_list = NULL;
@@ -66,7 +60,7 @@ static nserror schedule_remove(void (*callback)(void *p), void *p)
return NSERROR_OK;
}
- SRLOG("removing %p, %p", callback, p);
+ NSLOG(schedule, DEBUG, "removing %p, %p", callback, p);
cur_nscb = schedule_list;
prev_nscb = NULL;
@@ -76,8 +70,11 @@ static nserror schedule_remove(void (*callback)(void *p), void *p)
(cur_nscb->p == p)) {
/* item to remove */
- SRLOG("callback entry %p removing %p(%p)",
- cur_nscb, cur_nscb->callback, cur_nscb->p);
+ NSLOG(schedule, DEBUG,
+ "callback entry %p removing %p(%p)",
+ cur_nscb,
+ cur_nscb->callback,
+ cur_nscb->p);
/* remove callback */
unlnk_nscb = cur_nscb;
@@ -118,7 +115,8 @@ nserror win32_schedule(int ival, void (*callback)(void *p), void *p)
return NSERROR_NOMEM;
}
- SRLOG("adding callback %p for %p(%p) at %d cs",
+ NSLOG(schedule, DEBUG,
+ "adding callback %p for %p(%p) at %d cs",
nscb, callback, p, ival);
gettimeofday(&nscb->tv, NULL);
@@ -168,8 +166,11 @@ schedule_run(void)
prev_nscb->next = unlnk_nscb->next;
}
- SRLOG("callback entry %p running %p(%p)",
- unlnk_nscb, unlnk_nscb->callback, unlnk_nscb->p);
+ NSLOG(schedule, DEBUG,
+ "callback entry %p running %p(%p)",
+ unlnk_nscb,
+ unlnk_nscb->callback,
+ unlnk_nscb->p);
/* call callback */
unlnk_nscb->callback(unlnk_nscb->p);
@@ -201,8 +202,9 @@ schedule_run(void)
/* make returned time relative to now */
timersub(&nexttime, &tv, &rettime);
- SRLOG("returning time to next event as %ldms",
- (rettime.tv_sec * 1000) + (rettime.tv_usec / 1000));
+ NSLOG(schedule, DEBUG,
+ "returning time to next event as %ldms",
+ (rettime.tv_sec * 1000) + (rettime.tv_usec / 1000));
/* return next event time in milliseconds (24days max wait) */
return (rettime.tv_sec * 1000) + (rettime.tv_usec / 1000);
@@ -216,12 +218,16 @@ void list_schedule(void)
gettimeofday(&tv, NULL);
- LOG("schedule list at %ld:%ld", tv.tv_sec, tv.tv_usec);
+ NSLOG(netsurf, INFO, "schedule list at %ld:%ld", tv.tv_sec, tv.tv_usec);
cur_nscb = schedule_list;
while (cur_nscb != NULL) {
- LOG("Schedule %p at %ld:%ld", cur_nscb, cur_nscb->tv.tv_sec, cur_nscb->tv.tv_usec);
+ NSLOG(netsurf, INFO,
+ "Schedule %p at %ld:%ld",
+ cur_nscb,
+ cur_nscb->tv.tv_sec,
+ cur_nscb->tv.tv_usec);
cur_nscb = cur_nscb->next;
}
}
diff --git a/frontends/windows/ssl_cert.c b/frontends/windows/ssl_cert.c
index fac211c11..4db061626 100644
--- a/frontends/windows/ssl_cert.c
+++ b/frontends/windows/ssl_cert.c
@@ -191,7 +191,7 @@ nserror nsw32_cert_verify(struct nsurl *url,
return res;
}
- LOG("creating hInstance %p SSL window", hinst);
+ NSLOG(netsurf, INFO, "creating hInstance %p SSL window", hinst);
ncwin->hWnd = CreateWindowEx(0,
windowclassname_sslcert,
"SSL Certificate viewer",
@@ -208,7 +208,7 @@ nserror nsw32_cert_verify(struct nsurl *url,
hinst,
NULL);
if (ncwin->hWnd == NULL) {
- LOG("Window create failed");
+ NSLOG(netsurf, INFO, "Window create failed");
return NSERROR_NOMEM;
}
@@ -375,8 +375,11 @@ nsw32_window_ssl_cert_command(HWND hwnd,
int identifier,
HWND ctrl_window)
{
- LOG("notification_code %x identifier %x ctrl_window %p",
- notification_code, identifier, ctrl_window);
+ NSLOG(netsurf, INFO,
+ "notification_code %x identifier %x ctrl_window %p",
+ notification_code,
+ identifier,
+ ctrl_window);
switch(identifier) {
case IDC_SSLCERT_BTN_ACCEPT:
diff --git a/frontends/windows/windbg.h b/frontends/windows/windbg.h
index b2d8640f4..6cd9f97f8 100644
--- a/frontends/windows/windbg.h
+++ b/frontends/windows/windbg.h
@@ -24,11 +24,13 @@
const char *msg_num_to_name(int msg);
void win_perror(const char *lpszFunction);
-#define LOG_WIN_MSG(h, m, w, l) \
- if (((m) != WM_SETCURSOR) && \
- ((m) != WM_MOUSEMOVE) && \
- ((m) != WM_NCHITTEST) && \
- ((m) != WM_ENTERIDLE)) \
- LOG("%s, hwnd %p, w 0x%x, l 0x%Ix", msg_num_to_name(m), h, w, l);
+#define LOG_WIN_MSG(h, m, w, l) \
+ if (((m) != WM_SETCURSOR) && \
+ ((m) != WM_MOUSEMOVE) && \
+ ((m) != WM_NCHITTEST) && \
+ ((m) != WM_ENTERIDLE)) \
+ NSLOG(netsurf, INFO, \
+ "%s, hwnd %p, w 0x%x, l 0x%Ix", \
+ msg_num_to_name(m), h, w, l)
#endif
diff --git a/frontends/windows/window.c b/frontends/windows/window.c
index c72173697..90d076812 100644
--- a/frontends/windows/window.c
+++ b/frontends/windows/window.c
@@ -88,7 +88,7 @@ static int get_window_dpi(HWND hwnd)
ReleaseDC(hwnd, hdc);
- LOG("FIX DPI %d", dpi);
+ NSLOG(netsurf, INFO, "FIX DPI %d", dpi);
return dpi;
}
@@ -163,7 +163,9 @@ static HWND nsws_window_create(HINSTANCE hInstance, struct gui_window *gw)
gw->mainmenu = LoadMenu(hInstance, MAKEINTRESOURCE(IDR_MENU_MAIN));
gw->rclick = LoadMenu(hInstance, MAKEINTRESOURCE(IDR_MENU_CONTEXT));
- LOG("creating hInstance %p GUI window %p", hInstance, gw);
+ NSLOG(netsurf, INFO,
+ "creating hInstance %p GUI window %p",
+ hInstance, gw);
hwnd = CreateWindowEx(0,
windowclassname_main,
"NetSurf Browser",
@@ -181,7 +183,7 @@ static HWND nsws_window_create(HINSTANCE hInstance, struct gui_window *gw)
NULL);
if (hwnd == NULL) {
- LOG("Window create failed");
+ NSLOG(netsurf, INFO, "Window create failed");
return NULL;
}
@@ -194,9 +196,10 @@ static HWND nsws_window_create(HINSTANCE hInstance, struct gui_window *gw)
(nsoption_int(window_height) >= 100) &&
(nsoption_int(window_x) >= 0) &&
(nsoption_int(window_y) >= 0)) {
- LOG("Setting Window position %d,%d %d,%d",
- nsoption_int(window_x), nsoption_int(window_y),
- nsoption_int(window_width), nsoption_int(window_height));
+ NSLOG(netsurf, INFO,
+ "Setting Window position %d,%d %d,%d",
+ nsoption_int(window_x), nsoption_int(window_y),
+ nsoption_int(window_width), nsoption_int(window_height));
SetWindowPos(hwnd, HWND_TOP,
nsoption_int(window_x),
nsoption_int(window_y),
@@ -227,47 +230,50 @@ nsws_window_toolbar_command(struct gui_window *gw,
int identifier,
HWND ctrl_window)
{
- LOG("notification_code %d identifier %d ctrl_window %p",
- notification_code, identifier, ctrl_window);
+ NSLOG(netsurf, INFO,
+ "notification_code %d identifier %d ctrl_window %p",
+ notification_code,
+ identifier,
+ ctrl_window);
switch(identifier) {
case IDC_MAIN_URLBAR:
switch (notification_code) {
case EN_CHANGE:
- LOG("EN_CHANGE");
+ NSLOG(netsurf, INFO, "EN_CHANGE");
break;
case EN_ERRSPACE:
- LOG("EN_ERRSPACE");
+ NSLOG(netsurf, INFO, "EN_ERRSPACE");
break;
case EN_HSCROLL:
- LOG("EN_HSCROLL");
+ NSLOG(netsurf, INFO, "EN_HSCROLL");
break;
case EN_KILLFOCUS:
- LOG("EN_KILLFOCUS");
+ NSLOG(netsurf, INFO, "EN_KILLFOCUS");
break;
case EN_MAXTEXT:
- LOG("EN_MAXTEXT");
+ NSLOG(netsurf, INFO, "EN_MAXTEXT");
break;
case EN_SETFOCUS:
- LOG("EN_SETFOCUS");
+ NSLOG(netsurf, INFO, "EN_SETFOCUS");
break;
case EN_UPDATE:
- LOG("EN_UPDATE");
+ NSLOG(netsurf, INFO, "EN_UPDATE");
break;
case EN_VSCROLL:
- LOG("EN_VSCROLL");
+ NSLOG(netsurf, INFO, "EN_VSCROLL");
break;
default:
- LOG("Unknown notification_code");
+ NSLOG(netsurf, INFO, "Unknown notification_code");
break;
}
break;
@@ -421,7 +427,7 @@ nsws_window_urlbar_callback(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
case WM_DESTROY:
hFont = (HFONT)SendMessage(hwnd, WM_GETFONT, 0, 0);
if (hFont != NULL) {
- LOG("Destroyed font object");
+ NSLOG(netsurf, INFO, "Destroyed font object");
DeleteObject(hFont);
}
@@ -502,12 +508,13 @@ nsws_window_urlbar_create(HINSTANCE hInstance,
CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY,
DEFAULT_PITCH | FF_SWISS, "Arial");
if (hFont != NULL) {
- LOG("Setting font object");
+ NSLOG(netsurf, INFO, "Setting font object");
SendMessage(hwnd, WM_SETFONT, (WPARAM)hFont, 0);
}
- LOG("Created url bar hwnd:%p, x:%d, y:%d, w:%d, h:%d",
- hwnd, urlx, urly, urlwidth, urlheight);
+ NSLOG(netsurf, INFO,
+ "Created url bar hwnd:%p, x:%d, y:%d, w:%d, h:%d", hwnd, urlx,
+ urly, urlwidth, urlheight);
return hwnd;
}
@@ -548,7 +555,7 @@ nsws_window_throbber_create(HINSTANCE hInstance,
NULL);
nsws_find_resource(avi, "throbber.avi", "windows/res/throbber.avi");
- LOG("setting throbber avi as %s", avi);
+ NSLOG(netsurf, INFO, "setting throbber avi as %s", avi);
Animate_Open(hwnd, avi);
if (gw->throbbing) {
Animate_Play(hwnd, 0, -1, -1);
@@ -576,7 +583,8 @@ get_imagelist(HINSTANCE hInstance, int resid, int bsize, int bcnt)
HIMAGELIST hImageList;
HBITMAP hScrBM;
- LOG("resource id %d, bzize %d, bcnt %d", resid, bsize, bcnt);
+ NSLOG(netsurf, INFO, "resource id %d, bzize %d, bcnt %d", resid,
+ bsize, bcnt);
hImageList = ImageList_Create(bsize, bsize,
ILC_COLOR24 | ILC_MASK, 0,
@@ -997,8 +1005,11 @@ nsws_window_command(HWND hwnd,
{
nserror ret;
- LOG("notification_code %x identifier %x ctrl_window %p",
- notification_code, identifier, ctrl_window);
+ NSLOG(netsurf, INFO,
+ "notification_code %x identifier %x ctrl_window %p",
+ notification_code,
+ identifier,
+ ctrl_window);
switch(identifier) {
@@ -1073,7 +1084,7 @@ nsws_window_command(HWND hwnd,
HANDLE h = GetClipboardData(CF_TEXT);
if (h != NULL) {
char *content = GlobalLock(h);
- LOG("pasting %s\n", content);
+ NSLOG(netsurf, INFO, "pasting %s\n", content);
GlobalUnlock(h);
}
CloseClipboard();
@@ -1276,7 +1287,7 @@ nsws_window_command(HWND hwnd,
int len = SendMessage(gw->urlbar, WM_GETTEXTLENGTH, 0, 0);
char addr[len + 1];
SendMessage(gw->urlbar, WM_GETTEXT, (WPARAM)(len + 1), (LPARAM)addr);
- LOG("launching %s\n", addr);
+ NSLOG(netsurf, INFO, "launching %s\n", addr);
if (nsurl_create(addr, &url) != NSERROR_OK) {
win32_warning("NoMemory", 0);
@@ -1313,7 +1324,7 @@ nsws_window_command(HWND hwnd,
*/
static bool win32_window_get_scroll(struct gui_window *gw, int *sx, int *sy)
{
- LOG("get scroll");
+ NSLOG(netsurf, INFO, "get scroll");
if (gw == NULL)
return false;
@@ -1410,7 +1421,8 @@ nsws_window_event_callback(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
gw = nsws_get_gui_window(hwnd);
if (gw == NULL) {
- LOG("Unable to find gui window structure for hwnd %p", hwnd);
+ NSLOG(netsurf, INFO,
+ "Unable to find gui window structure for hwnd %p", hwnd);
return DefWindowProc(hwnd, msg, wparam, lparam);
}
@@ -1463,7 +1475,7 @@ win32_window_create(struct browser_window *bw,
{
struct gui_window *gw;
- LOG("Creating gui window for browser window %p", bw);
+ NSLOG(netsurf, INFO, "Creating gui window for browser window %p", bw);
gw = calloc(1, sizeof(struct gui_window));
if (gw == NULL) {
@@ -1484,7 +1496,7 @@ win32_window_create(struct browser_window *bw,
gw->mouse = malloc(sizeof(struct browser_mouse));
if (gw->mouse == NULL) {
free(gw);
- LOG("Unable to allocate mouse state");
+ NSLOG(netsurf, INFO, "Unable to allocate mouse state");
return NULL;
}
gw->mouse->gui = gw;
@@ -1504,8 +1516,12 @@ win32_window_create(struct browser_window *bw,
gw->statusbar = nsws_window_create_statusbar(hinst, gw->main, gw);
gw->drawingarea = nsws_window_create_drawable(hinst, gw->main, gw);
- LOG("new window: main:%p toolbar:%p statusbar %p drawingarea %p",
- gw->main, gw->toolbar, gw->statusbar, gw->drawingarea);
+ NSLOG(netsurf, INFO,
+ "new window: main:%p toolbar:%p statusbar %p drawingarea %p",
+ gw->main,
+ gw->toolbar,
+ gw->statusbar,
+ gw->drawingarea);
font_hwnd = gw->drawingarea;
open_windows++;
@@ -1556,7 +1572,7 @@ win32_window_get_dimensions(struct gui_window *gw,
*width = gw->width;
*height = gw->height;
- LOG("gw:%p w=%d h=%d", gw, *width, *height);
+ NSLOG(netsurf, INFO, "gw:%p w=%d h=%d", gw, *width, *height);
return NSERROR_OK;
}
@@ -1588,7 +1604,7 @@ static void win32_window_set_title(struct gui_window *w, const char *title)
return;
}
- LOG("%p, title %s", w, title);
+ NSLOG(netsurf, INFO, "%p, title %s", w, title);
fulltitle = malloc(strlen(title) + SLEN(" - NetSurf") + 1);
if (fulltitle == NULL) {
win32_warning("NoMemory", 0);
@@ -1865,7 +1881,9 @@ nserror win32_window_set_scroll(struct gui_window *gw, const struct rect *rect)
gw->requestscrolly = rect->y0 - gw->scrolly;
}
- /*LOG("requestscroll x,y:%d,%d", w->requestscrollx, w->requestscrolly);*/
+ NSLOG(netsurf, DEEPDEBUG,
+ "requestscroll x,y:%d,%d",
+ gw->requestscrollx, gw->requestscrolly);
/* set the vertical scroll offset */
si.cbSize = sizeof(si);
@@ -1876,7 +1894,9 @@ nserror win32_window_set_scroll(struct gui_window *gw, const struct rect *rect)
si.nPos = max(gw->scrolly + gw->requestscrolly, 0);
si.nPos = min(si.nPos, height - gw->height);
SetScrollInfo(gw->drawingarea, SB_VERT, &si, TRUE);
- /*LOG("SetScrollInfo VERT min:%d max:%d page:%d pos:%d", si.nMin, si.nMax, si.nPage, si.nPos);*/
+ NSLOG(netsurf, DEEPDEBUG,
+ "SetScrollInfo VERT min:%d max:%d page:%d pos:%d",
+ si.nMin, si.nMax, si.nPage, si.nPos);
/* set the horizontal scroll offset */
si.cbSize = sizeof(si);
@@ -1887,7 +1907,9 @@ nserror win32_window_set_scroll(struct gui_window *gw, const struct rect *rect)
si.nPos = max(gw->scrollx + gw->requestscrollx, 0);
si.nPos = min(si.nPos, width - gw->width);
SetScrollInfo(gw->drawingarea, SB_HORZ, &si, TRUE);
- /*LOG("SetScrollInfo HORZ min:%d max:%d page:%d pos:%d", si.nMin, si.nMax, si.nPage, si.nPos);*/
+ NSLOG(netsurf, DEEPDEBUG,
+ "SetScrollInfo HORZ min:%d max:%d page:%d pos:%d",
+ si.nMin, si.nMax, si.nPage, si.nPos);
/* Set caret position */
GetCaretPos(&p);
@@ -1900,8 +1922,19 @@ nserror win32_window_set_scroll(struct gui_window *gw, const struct rect *rect)
r.bottom = gw->height + 1;
r.left = 0;
r.right = gw->width + 1;
- ScrollWindowEx(gw->drawingarea, - gw->requestscrollx, - gw->requestscrolly, &r, NULL, NULL, &redraw, SW_INVALIDATE);
- /*LOG("ScrollWindowEx %d, %d", - w->requestscrollx, - w->requestscrolly);*/
+ ScrollWindowEx(gw->drawingarea,
+ - gw->requestscrollx,
+ - gw->requestscrolly,
+ &r,
+ NULL,
+ NULL,
+ &redraw,
+ SW_INVALIDATE);
+ NSLOG(netsurf, DEEPDEBUG,
+ "ScrollWindowEx %d, %d",
+ - gw->requestscrollx,
+ - gw->requestscrolly);
+
gw->scrolly += gw->requestscrolly;
gw->scrollx += gw->requestscrollx;
gw->requestscrollx = 0;
diff --git a/include/netsurf/bitmap.h b/include/netsurf/bitmap.h
index e54bdff85..a85efce99 100644
--- a/include/netsurf/bitmap.h
+++ b/include/netsurf/bitmap.h
@@ -154,7 +154,7 @@ struct gui_bitmap_table {
*
* \param bitmap The bitmap to save
* \param path The path to save the bitmap to.
- * \param flags Flags affectin the save.
+ * \param flags Flags affecting the save.
*/
bool (*save)(void *bitmap, const char *path, unsigned flags);
diff --git a/include/netsurf/browser_window.h b/include/netsurf/browser_window.h
index 567e314c5..6c44e161f 100644
--- a/include/netsurf/browser_window.h
+++ b/include/netsurf/browser_window.h
@@ -116,7 +116,10 @@ enum browser_window_nav_flags {
* A transaction is unverifiable if the user does not
* have that option.
*/
- BW_NAVIGATE_UNVERIFIABLE = (1 << 2)
+ BW_NAVIGATE_UNVERIFIABLE = (1 << 2),
+
+ /** suppress initial history updates (used by back/fwd/etc) */
+ BW_NAVIGATE_NO_TERMINAL_HISTORY_UPDATE = (1 << 3)
};
/**
diff --git a/include/netsurf/url_db.h b/include/netsurf/url_db.h
index be2c656ff..217cf8fcd 100644
--- a/include/netsurf/url_db.h
+++ b/include/netsurf/url_db.h
@@ -96,15 +96,6 @@ void urldb_iterate_entries(bool (*callback)(struct nsurl *url, const struct url_
/**
- * Retrieve thumbnail data for given URL
- *
- * \param url Absolute URL to search for
- * \return Pointer to thumbnail data, or NULL if not found.
- */
-struct bitmap *urldb_get_thumbnail(struct nsurl *url);
-
-
-/**
* Find data for an URL.
*
* \param url Absolute URL to look for
diff --git a/render/box.c b/render/box.c
index 77cc15bc3..8b9c89ee6 100644
--- a/render/box.c
+++ b/render/box.c
@@ -1155,7 +1155,7 @@ bool box_handle_scrollbars(struct content *c, struct box *box,
if (box->scroll_y == NULL) {
data = malloc(sizeof(struct html_scrollbar_data));
if (data == NULL) {
- LOG("malloc failed");
+ NSLOG(netsurf, INFO, "malloc failed");
guit->misc->warning("NoMemory", 0);
return false;
}
@@ -1176,7 +1176,7 @@ bool box_handle_scrollbars(struct content *c, struct box *box,
if (box->scroll_x == NULL) {
data = malloc(sizeof(struct html_scrollbar_data));
if (data == NULL) {
- LOG("malloc failed");
+ NSLOG(netsurf, INFO, "malloc failed");
guit->misc->warning("NoMemory", 0);
return false;
}
diff --git a/render/box_construct.c b/render/box_construct.c
index d0ffd9d83..1982622f9 100644
--- a/render/box_construct.c
+++ b/render/box_construct.c
@@ -46,6 +46,7 @@
#include "content/content_protected.h"
#include "css/hints.h"
#include "css/select.h"
+#include "css/utils.h"
#include "desktop/gui_internal.h"
#include "render/box.h"
@@ -612,7 +613,7 @@ static void box_construct_generate(dom_node *n, html_content *content,
}
/* create box for this element */
- computed_display = css_computed_display(style, box_is_root(n));
+ computed_display = ns_computed_display(style, box_is_root(n));
if (computed_display == CSS_DISPLAY_BLOCK ||
computed_display == CSS_DISPLAY_TABLE) {
/* currently only support block level boxes */
@@ -625,7 +626,7 @@ static void box_construct_generate(dom_node *n, html_content *content,
}
/* set box type from computed display */
- gen->type = box_map[css_computed_display(
+ gen->type = box_map[ns_computed_display(
style, box_is_root(n))];
box_add_child(box, gen);
@@ -831,11 +832,11 @@ bool box_construct_element(struct box_construct_ctx *ctx,
if ((css_computed_position(box->style) == CSS_POSITION_ABSOLUTE ||
css_computed_position(box->style) ==
CSS_POSITION_FIXED) &&
- (css_computed_display_static(box->style) ==
+ (ns_computed_display_static(box->style) ==
CSS_DISPLAY_INLINE ||
- css_computed_display_static(box->style) ==
+ ns_computed_display_static(box->style) ==
CSS_DISPLAY_INLINE_BLOCK ||
- css_computed_display_static(box->style) ==
+ ns_computed_display_static(box->style) ==
CSS_DISPLAY_INLINE_TABLE)) {
/* Special case for absolute positioning: make absolute inlines
* into inline block so that the boxes are constructed in an
@@ -848,7 +849,7 @@ bool box_construct_element(struct box_construct_ctx *ctx,
box->type = BOX_BLOCK;
} else {
/* Normal mapping */
- box->type = box_map[css_computed_display(box->style,
+ box->type = box_map[ns_computed_display(box->style,
props.node_is_root)];
}
@@ -876,7 +877,7 @@ bool box_construct_element(struct box_construct_ctx *ctx,
box->styles->styles[CSS_PSEUDO_ELEMENT_BEFORE]);
}
- if (box->type == BOX_NONE || (css_computed_display(box->style,
+ if (box->type == BOX_NONE || (ns_computed_display(box->style,
props.node_is_root) == CSS_DISPLAY_NONE &&
props.node_is_root == false)) {
css_select_results_destroy(styles);
@@ -968,7 +969,7 @@ bool box_construct_element(struct box_construct_ctx *ctx,
box_add_child(props.inline_container, box);
} else {
- if (css_computed_display(box->style, props.node_is_root) ==
+ if (ns_computed_display(box->style, props.node_is_root) ==
CSS_DISPLAY_LIST_ITEM) {
/* List item: compute marker */
if (box_construct_marker(box, props.title, ctx,
@@ -1559,7 +1560,7 @@ bool box_image(BOX_SPECIAL_PARAMS)
css_unit wunit = CSS_UNIT_PX;
css_unit hunit = CSS_UNIT_PX;
- if (box->style && css_computed_display(box->style,
+ if (box->style && ns_computed_display(box->style,
box_is_root(n)) == CSS_DISPLAY_NONE)
return true;
@@ -1666,7 +1667,7 @@ bool box_object(BOX_SPECIAL_PARAMS)
dom_node *c;
dom_exception err;
- if (box->style && css_computed_display(box->style,
+ if (box->style && ns_computed_display(box->style,
box_is_root(n)) == CSS_DISPLAY_NONE)
return true;
@@ -1900,7 +1901,7 @@ bool box_frameset(BOX_SPECIAL_PARAMS)
bool ok;
if (content->frameset) {
- LOG("Error: multiple framesets in document.");
+ NSLOG(netsurf, INFO, "Error: multiple framesets in document.");
/* Don't convert children */
if (convert_children)
*convert_children = false;
@@ -2316,7 +2317,7 @@ bool box_iframe(BOX_SPECIAL_PARAMS)
struct content_html_iframe *iframe;
int i;
- if (box->style && css_computed_display(box->style,
+ if (box->style && ns_computed_display(box->style,
box_is_root(n)) == CSS_DISPLAY_NONE)
return true;
@@ -2551,7 +2552,7 @@ bool box_input(BOX_SPECIAL_PARAMS)
corestring_lwc_image)) {
gadget->type = GADGET_IMAGE;
- if (box->style && css_computed_display(box->style,
+ if (box->style && ns_computed_display(box->style,
box_is_root(n)) != CSS_DISPLAY_NONE &&
nsoption_bool(foreground_images) == true) {
dom_string *s;
@@ -2887,7 +2888,7 @@ bool box_embed(BOX_SPECIAL_PARAMS)
dom_string *src;
dom_exception err;
- if (box->style && css_computed_display(box->style,
+ if (box->style && ns_computed_display(box->style,
box_is_root(n)) == CSS_DISPLAY_NONE)
return true;
diff --git a/render/box_normalise.c b/render/box_normalise.c
index 5d36b99d7..9f78f75ac 100644
--- a/render/box_normalise.c
+++ b/render/box_normalise.c
@@ -111,7 +111,7 @@ bool box_normalise_block(struct box *block, html_content *c)
assert(block != NULL);
#ifdef BOX_NORMALISE_DEBUG
- LOG("block %p, block->type %u", block, block->type);
+ NSLOG(netsurf, INFO, "block %p, block->type %u", block, block->type);
#endif
assert(block->type == BOX_BLOCK || block->type == BOX_INLINE_BLOCK ||
@@ -119,7 +119,8 @@ bool box_normalise_block(struct box *block, html_content *c)
for (child = block->children; child != NULL; child = next_child) {
#ifdef BOX_NORMALISE_DEBUG
- LOG("child %p, child->type = %d", child, child->type);
+ NSLOG(netsurf, INFO, "child %p, child->type = %d", child,
+ child->type);
#endif
next_child = child->next; /* child may be destroyed */
@@ -223,7 +224,7 @@ bool box_normalise_table(struct box *table, html_content * c)
assert(table->type == BOX_TABLE);
#ifdef BOX_NORMALISE_DEBUG
- LOG("table %p", table);
+ NSLOG(netsurf, INFO, "table %p", table);
#endif
col_info.num_columns = 1;
@@ -337,7 +338,8 @@ bool box_normalise_table(struct box *table, html_content * c)
struct box *row;
#ifdef BOX_NORMALISE_DEBUG
- LOG("table->children == 0, creating implied row");
+ NSLOG(netsurf, INFO,
+ "table->children == 0, creating implied row");
#endif
assert(table->style != NULL);
@@ -399,7 +401,7 @@ bool box_normalise_table(struct box *table, html_content * c)
return false;
#ifdef BOX_NORMALISE_DEBUG
- LOG("table %p done", table);
+ NSLOG(netsurf, INFO, "table %p done", table);
#endif
return true;
@@ -585,7 +587,7 @@ bool box_normalise_table_row_group(struct box *row_group,
assert(row_group->type == BOX_TABLE_ROW_GROUP);
#ifdef BOX_NORMALISE_DEBUG
- LOG("row_group %p", row_group);
+ NSLOG(netsurf, INFO, "row_group %p", row_group);
#endif
for (child = row_group->children; child != NULL; child = next_child) {
@@ -677,7 +679,8 @@ bool box_normalise_table_row_group(struct box *row_group,
if (row_group->children == NULL) {
#ifdef BOX_NORMALISE_DEBUG
- LOG("row_group->children == 0, inserting implied row");
+ NSLOG(netsurf, INFO,
+ "row_group->children == 0, inserting implied row");
#endif
assert(row_group->style != NULL);
@@ -712,7 +715,7 @@ bool box_normalise_table_row_group(struct box *row_group,
row_group->rows = group_row_count;
#ifdef BOX_NORMALISE_DEBUG
- LOG("row_group %p done", row_group);
+ NSLOG(netsurf, INFO, "row_group %p done", row_group);
#endif
return true;
@@ -734,7 +737,7 @@ bool box_normalise_table_row(struct box *row,
assert(row->type == BOX_TABLE_ROW);
#ifdef BOX_NORMALISE_DEBUG
- LOG("row %p", row);
+ NSLOG(netsurf, INFO, "row %p", row);
#endif
for (child = row->children; child != NULL; child = next_child) {
@@ -843,7 +846,7 @@ bool box_normalise_table_row(struct box *row,
col_info->num_rows++;
#ifdef BOX_NORMALISE_DEBUG
- LOG("row %p done", row);
+ NSLOG(netsurf, INFO, "row %p done", row);
#endif
return true;
@@ -934,7 +937,7 @@ bool box_normalise_inline_container(struct box *cont, html_content * c)
assert(cont->type == BOX_INLINE_CONTAINER);
#ifdef BOX_NORMALISE_DEBUG
- LOG("cont %p", cont);
+ NSLOG(netsurf, INFO, "cont %p", cont);
#endif
for (child = cont->children; child != NULL; child = next_child) {
@@ -997,7 +1000,7 @@ bool box_normalise_inline_container(struct box *cont, html_content * c)
}
#ifdef BOX_NORMALISE_DEBUG
- LOG("cont %p done", cont);
+ NSLOG(netsurf, INFO, "cont %p done", cont);
#endif
return true;
diff --git a/render/box_textarea.c b/render/box_textarea.c
index 1586d71c4..3b1e7750c 100644
--- a/render/box_textarea.c
+++ b/render/box_textarea.c
@@ -149,7 +149,9 @@ static void box_textarea_callback(void *data, struct textarea_msg *msg)
break;
default:
- LOG("Drag type %d not handled.", msg->data.drag);
+ NSLOG(netsurf, INFO,
+ "Drag type %d not handled.",
+ msg->data.drag);
/* This is a logic faliure in the
* front end code so abort.
*/
diff --git a/render/form.c b/render/form.c
index a8b96fefb..904272d3a 100644
--- a/render/form.c
+++ b/render/form.c
@@ -218,7 +218,8 @@ void form_free_control(struct form_control *control)
struct form_control *c;
assert(control != NULL);
- LOG("Control:%p name:%p value:%p initial:%p", control, control->name, control->value, control->initial_value);
+ NSLOG(netsurf, INFO, "Control:%p name:%p value:%p initial:%p",
+ control, control->name, control->value, control->initial_value);
free(control->name);
free(control->value);
free(control->initial_value);
@@ -229,7 +230,9 @@ void form_free_control(struct form_control *control)
for (option = control->data.select.items; option;
option = next) {
next = option->next;
- LOG("select option:%p text:%p value:%p", option, option->text, option->value);
+ NSLOG(netsurf, INFO,
+ "select option:%p text:%p value:%p", option,
+ option->text, option->value);
free(option->text);
free(option->value);
free(option);
@@ -348,7 +351,7 @@ bool form_successful_controls_dom(struct form *_form,
/** \todo Replace this call with something DOMish */
charset = form_acceptable_charset(_form);
if (charset == NULL) {
- LOG("failed to find charset");
+ NSLOG(netsurf, INFO, "failed to find charset");
return false;
}
@@ -362,7 +365,7 @@ bool form_successful_controls_dom(struct form *_form,
err = dom_html_form_element_get_elements(form, &form_elements);
if (err != DOM_NO_ERR) {
- LOG("Could not get form elements");
+ NSLOG(netsurf, INFO, "Could not get form elements");
goto dom_no_memory;
}
@@ -370,7 +373,7 @@ bool form_successful_controls_dom(struct form *_form,
err = dom_html_collection_get_length(form_elements, &element_count);
if (err != DOM_NO_ERR) {
- LOG("Could not get form element count");
+ NSLOG(netsurf, INFO, "Could not get form element count");
goto dom_no_memory;
}
@@ -402,7 +405,8 @@ bool form_successful_controls_dom(struct form *_form,
err = dom_html_collection_item(form_elements,
index, &form_element);
if (err != DOM_NO_ERR) {
- LOG("Could not retrieve form element %d", index);
+ NSLOG(netsurf, INFO,
+ "Could not retrieve form element %d", index);
goto dom_no_memory;
}
@@ -414,7 +418,7 @@ bool form_successful_controls_dom(struct form *_form,
*/
err = dom_node_get_node_name(form_element, &nodename);
if (err != DOM_NO_ERR) {
- LOG("Could not get node name");
+ NSLOG(netsurf, INFO, "Could not get node name");
goto dom_no_memory;
}
@@ -423,14 +427,16 @@ bool form_successful_controls_dom(struct form *_form,
(dom_html_text_area_element *)form_element,
&element_disabled);
if (err != DOM_NO_ERR) {
- LOG("Could not get text area disabled property");
+ NSLOG(netsurf, INFO,
+ "Could not get text area disabled property");
goto dom_no_memory;
}
err = dom_html_text_area_element_get_name(
(dom_html_text_area_element *)form_element,
&inputname);
if (err != DOM_NO_ERR) {
- LOG("Could not get text area name property");
+ NSLOG(netsurf, INFO,
+ "Could not get text area name property");
goto dom_no_memory;
}
} else if (dom_string_isequal(nodename, corestring_dom_SELECT)) {
@@ -438,14 +444,16 @@ bool form_successful_controls_dom(struct form *_form,
(dom_html_select_element *)form_element,
&element_disabled);
if (err != DOM_NO_ERR) {
- LOG("Could not get select disabled property");
+ NSLOG(netsurf, INFO,
+ "Could not get select disabled property");
goto dom_no_memory;
}
err = dom_html_select_element_get_name(
(dom_html_select_element *)form_element,
&inputname);
if (err != DOM_NO_ERR) {
- LOG("Could not get select name property");
+ NSLOG(netsurf, INFO,
+ "Could not get select name property");
goto dom_no_memory;
}
} else if (dom_string_isequal(nodename, corestring_dom_INPUT)) {
@@ -453,14 +461,16 @@ bool form_successful_controls_dom(struct form *_form,
(dom_html_input_element *)form_element,
&element_disabled);
if (err != DOM_NO_ERR) {
- LOG("Could not get input disabled property");
+ NSLOG(netsurf, INFO,
+ "Could not get input disabled property");
goto dom_no_memory;
}
err = dom_html_input_element_get_name(
(dom_html_input_element *)form_element,
&inputname);
if (err != DOM_NO_ERR) {
- LOG("Could not get input name property");
+ NSLOG(netsurf, INFO,
+ "Could not get input name property");
goto dom_no_memory;
}
} else if (dom_string_isequal(nodename, corestring_dom_BUTTON)) {
@@ -468,21 +478,23 @@ bool form_successful_controls_dom(struct form *_form,
(dom_html_button_element *)form_element,
&element_disabled);
if (err != DOM_NO_ERR) {
- LOG("Could not get button disabled property");
+ NSLOG(netsurf, INFO,
+ "Could not get button disabled property");
goto dom_no_memory;
}
err = dom_html_button_element_get_name(
(dom_html_button_element *)form_element,
&inputname);
if (err != DOM_NO_ERR) {
- LOG("Could not get button name property");
+ NSLOG(netsurf, INFO,
+ "Could not get button name property");
goto dom_no_memory;
}
} else {
/* Unknown element type came through! */
- LOG("Unknown element type: %*s",
- (int)dom_string_byte_length(nodename),
- dom_string_data(nodename));
+ NSLOG(netsurf, INFO, "Unknown element type: %*s",
+ (int)dom_string_byte_length(nodename),
+ dom_string_data(nodename));
goto dom_no_memory;
}
if (element_disabled)
@@ -495,7 +507,8 @@ bool form_successful_controls_dom(struct form *_form,
(dom_html_text_area_element *)form_element,
&inputvalue);
if (err != DOM_NO_ERR) {
- LOG("Could not get text area content");
+ NSLOG(netsurf, INFO,
+ "Could not get text area content");
goto dom_no_memory;
}
} else if (dom_string_isequal(nodename, corestring_dom_SELECT)) {
@@ -504,13 +517,15 @@ bool form_successful_controls_dom(struct form *_form,
(dom_html_select_element *)form_element,
&options);
if (err != DOM_NO_ERR) {
- LOG("Could not get select options collection");
+ NSLOG(netsurf, INFO,
+ "Could not get select options collection");
goto dom_no_memory;
}
err = dom_html_options_collection_get_length(
options, &options_count);
if (err != DOM_NO_ERR) {
- LOG("Could not get select options collection length");
+ NSLOG(netsurf, INFO,
+ "Could not get select options collection length");
goto dom_no_memory;
}
for(option_index = 0; option_index < options_count;
@@ -527,14 +542,17 @@ bool form_successful_controls_dom(struct form *_form,
err = dom_html_options_collection_item(
options, option_index, &option_element);
if (err != DOM_NO_ERR) {
- LOG("Could not get options item %d", option_index);
+ NSLOG(netsurf, INFO,
+ "Could not get options item %d",
+ option_index);
goto dom_no_memory;
}
err = dom_html_option_element_get_selected(
(dom_html_option_element *)option_element,
&selected);
if (err != DOM_NO_ERR) {
- LOG("Could not get option selected property");
+ NSLOG(netsurf, INFO,
+ "Could not get option selected property");
goto dom_no_memory;
}
if (!selected)
@@ -543,13 +561,15 @@ bool form_successful_controls_dom(struct form *_form,
(dom_html_option_element *)option_element,
&inputvalue);
if (err != DOM_NO_ERR) {
- LOG("Could not get option value");
+ NSLOG(netsurf, INFO,
+ "Could not get option value");
goto dom_no_memory;
}
success_new = calloc(1, sizeof(*success_new));
if (success_new == NULL) {
- LOG("Could not allocate data for option");
+ NSLOG(netsurf, INFO,
+ "Could not allocate data for option");
goto dom_no_memory;
}
@@ -558,12 +578,14 @@ bool form_successful_controls_dom(struct form *_form,
success_new->name = ENCODE_ITEM(inputname);
if (success_new->name == NULL) {
- LOG("Could not encode name for option");
+ NSLOG(netsurf, INFO,
+ "Could not encode name for option");
goto dom_no_memory;
}
success_new->value = ENCODE_ITEM(inputvalue);
if (success_new->value == NULL) {
- LOG("Could not encode value for option");
+ NSLOG(netsurf, INFO,
+ "Could not encode value for option");
goto dom_no_memory;
}
}
@@ -573,7 +595,8 @@ bool form_successful_controls_dom(struct form *_form,
(dom_html_button_element *) form_element,
&inputtype);
if (err != DOM_NO_ERR) {
- LOG("Could not get button element type");
+ NSLOG(netsurf, INFO,
+ "Could not get button element type");
goto dom_no_memory;
}
if (dom_string_caseless_isequal(
@@ -593,7 +616,8 @@ bool form_successful_controls_dom(struct form *_form,
(dom_html_button_element *)form_element,
&inputvalue);
if (err != DOM_NO_ERR) {
- LOG("Could not get submit button value");
+ NSLOG(netsurf, INFO,
+ "Could not get submit button value");
goto dom_no_memory;
}
/* Drop through to report successful button */
@@ -610,7 +634,8 @@ bool form_successful_controls_dom(struct form *_form,
(dom_html_input_element *) form_element,
&inputtype);
if (err != DOM_NO_ERR) {
- LOG("Could not get input element type");
+ NSLOG(netsurf, INFO,
+ "Could not get input element type");
goto dom_no_memory;
}
if (dom_string_caseless_isequal(
@@ -630,7 +655,8 @@ bool form_successful_controls_dom(struct form *_form,
(dom_html_input_element *)form_element,
&inputvalue);
if (err != DOM_NO_ERR) {
- LOG("Could not get submit button value");
+ NSLOG(netsurf, INFO,
+ "Could not get submit button value");
goto dom_no_memory;
}
/* Drop through to report the successful button */
@@ -648,11 +674,13 @@ bool form_successful_controls_dom(struct form *_form,
corestring_dom___ns_key_image_coords_node_data,
&coords);
if (err != DOM_NO_ERR) {
- LOG("Could not get image XY data");
+ NSLOG(netsurf, INFO,
+ "Could not get image XY data");
goto dom_no_memory;
}
if (coords == NULL) {
- LOG("No XY data on the image input");
+ NSLOG(netsurf, INFO,
+ "No XY data on the image input");
goto dom_no_memory;
}
@@ -661,7 +689,8 @@ bool form_successful_controls_dom(struct form *_form,
success_new = calloc(1, sizeof(*success_new));
if (success_new == NULL) {
free(basename);
- LOG("Could not allocate data for image.x");
+ NSLOG(netsurf, INFO,
+ "Could not allocate data for image.x");
goto dom_no_memory;
}
@@ -671,13 +700,15 @@ bool form_successful_controls_dom(struct form *_form,
success_new->name = malloc(strlen(basename) + 3);
if (success_new->name == NULL) {
free(basename);
- LOG("Could not allocate name for image.x");
+ NSLOG(netsurf, INFO,
+ "Could not allocate name for image.x");
goto dom_no_memory;
}
success_new->value = malloc(20);
if (success_new->value == NULL) {
free(basename);
- LOG("Could not allocate value for image.x");
+ NSLOG(netsurf, INFO,
+ "Could not allocate value for image.x");
goto dom_no_memory;
}
sprintf(success_new->name, "%s.x", basename);
@@ -686,7 +717,8 @@ bool form_successful_controls_dom(struct form *_form,
success_new = calloc(1, sizeof(*success_new));
if (success_new == NULL) {
free(basename);
- LOG("Could not allocate data for image.y");
+ NSLOG(netsurf, INFO,
+ "Could not allocate data for image.y");
goto dom_no_memory;
}
@@ -696,13 +728,15 @@ bool form_successful_controls_dom(struct form *_form,
success_new->name = malloc(strlen(basename) + 3);
if (success_new->name == NULL) {
free(basename);
- LOG("Could not allocate name for image.y");
+ NSLOG(netsurf, INFO,
+ "Could not allocate name for image.y");
goto dom_no_memory;
}
success_new->value = malloc(20);
if (success_new->value == NULL) {
free(basename);
- LOG("Could not allocate value for image.y");
+ NSLOG(netsurf, INFO,
+ "Could not allocate value for image.y");
goto dom_no_memory;
}
sprintf(success_new->name, "%s.y", basename);
@@ -717,7 +751,8 @@ bool form_successful_controls_dom(struct form *_form,
(dom_html_input_element *)form_element,
&checked);
if (err != DOM_NO_ERR) {
- LOG("Could not get input element checked");
+ NSLOG(netsurf, INFO,
+ "Could not get input element checked");
goto dom_no_memory;
}
if (!checked)
@@ -726,7 +761,8 @@ bool form_successful_controls_dom(struct form *_form,
(dom_html_input_element *)form_element,
&inputvalue);
if (err != DOM_NO_ERR) {
- LOG("Could not get input element value");
+ NSLOG(netsurf, INFO,
+ "Could not get input element value");
goto dom_no_memory;
}
if (inputvalue == NULL) {
@@ -741,7 +777,8 @@ bool form_successful_controls_dom(struct form *_form,
(dom_html_input_element *)form_element,
&inputvalue);
if (err != DOM_NO_ERR) {
- LOG("Could not get file value");
+ NSLOG(netsurf, INFO,
+ "Could not get file value");
goto dom_no_memory;
}
err = dom_node_get_user_data(
@@ -749,14 +786,16 @@ bool form_successful_controls_dom(struct form *_form,
corestring_dom___ns_key_file_name_node_data,
&rawfile_temp);
if (err != DOM_NO_ERR) {
- LOG("Could not get file rawname");
+ NSLOG(netsurf, INFO,
+ "Could not get file rawname");
goto dom_no_memory;
}
rawfile_temp = strdup(rawfile_temp != NULL ?
rawfile_temp :
"");
if (rawfile_temp == NULL) {
- LOG("Could not copy file rawname");
+ NSLOG(netsurf, INFO,
+ "Could not copy file rawname");
goto dom_no_memory;
}
/* Fall out to the allocation */
@@ -765,7 +804,8 @@ bool form_successful_controls_dom(struct form *_form,
dom_string_caseless_isequal(
inputtype, corestring_dom_button)) {
/* Skip these */
- LOG("Skipping RESET and BUTTON");
+ NSLOG(netsurf, INFO,
+ "Skipping RESET and BUTTON");
continue;
} else {
/* Everything else is treated as text values */
@@ -773,7 +813,8 @@ bool form_successful_controls_dom(struct form *_form,
(dom_html_input_element *)form_element,
&inputvalue);
if (err != DOM_NO_ERR) {
- LOG("Could not get input value");
+ NSLOG(netsurf, INFO,
+ "Could not get input value");
goto dom_no_memory;
}
/* Fall out to the allocation */
@@ -782,7 +823,8 @@ bool form_successful_controls_dom(struct form *_form,
success_new = calloc(1, sizeof(*success_new));
if (success_new == NULL) {
- LOG("Could not allocate data for generic");
+ NSLOG(netsurf, INFO,
+ "Could not allocate data for generic");
goto dom_no_memory;
}
@@ -791,12 +833,14 @@ bool form_successful_controls_dom(struct form *_form,
success_new->name = ENCODE_ITEM(inputname);
if (success_new->name == NULL) {
- LOG("Could not encode name for generic");
+ NSLOG(netsurf, INFO,
+ "Could not encode name for generic");
goto dom_no_memory;
}
success_new->value = ENCODE_ITEM(inputvalue);
if (success_new->value == NULL) {
- LOG("Could not encode value for generic");
+ NSLOG(netsurf, INFO,
+ "Could not encode value for generic");
goto dom_no_memory;
}
if (rawfile_temp != NULL) {
diff --git a/render/html.c b/render/html.c
index a573ef5f5..3cfc5e236 100644
--- a/render/html.c
+++ b/render/html.c
@@ -89,8 +89,8 @@ bool fire_dom_event(dom_string *type, dom_node *target,
dom_event_unref(evt);
return false;
}
- LOG("Dispatching '%*s' against %p",
- dom_string_length(type), dom_string_data(type), target);
+ NSLOG(netsurf, INFO, "Dispatching '%*s' against %p",
+ dom_string_length(type), dom_string_data(type), target);
exc = dom_event_target_dispatch_event(target, evt, &result);
if (exc != DOM_NO_ERR) {
result = false;
@@ -111,7 +111,7 @@ static void html_box_convert_done(html_content *c, bool success)
dom_exception exc; /* returned by libdom functions */
dom_node *html;
- LOG("Done XML to box (%p)", c);
+ NSLOG(netsurf, INFO, "Done XML to box (%p)", c);
/* Clean up and report error if unsuccessful or aborted */
if ((success == false) || (c->aborted)) {
@@ -141,7 +141,7 @@ static void html_box_convert_done(html_content *c, bool success)
/** @todo should this call html_object_free_objects(c);
* like the other error paths
*/
- LOG("error retrieving html element from dom");
+ NSLOG(netsurf, INFO, "error retrieving html element from dom");
content_broadcast_errorcode(&c->base, NSERROR_DOM);
content_set_error(&c->base);
return;
@@ -150,7 +150,7 @@ static void html_box_convert_done(html_content *c, bool success)
/* extract image maps - can't do this sensibly in dom_to_box */
err = imagemap_extract(c);
if (err != NSERROR_OK) {
- LOG("imagemap extraction failed");
+ NSLOG(netsurf, INFO, "imagemap extraction failed");
html_object_free_objects(c);
content_broadcast_errorcode(&c->base, err);
content_set_error(&c->base);
@@ -443,7 +443,7 @@ static nserror html_meta_refresh_process_element(html_content *c, dom_node *n)
c->base.refresh = nsurl_ref(
content_get_url(&c->base));
- content_broadcast(&c->base, CONTENT_MSG_REFRESH, msg_data);
+ content_broadcast(&c->base, CONTENT_MSG_REFRESH, &msg_data);
return NSERROR_OK;
}
@@ -522,7 +522,8 @@ static nserror html_meta_refresh_process_element(html_content *c, dom_node *n)
c->base.refresh = nsurl;
- content_broadcast(&c->base, CONTENT_MSG_REFRESH, msg_data);
+ content_broadcast(&c->base, CONTENT_MSG_REFRESH,
+ &msg_data);
c->refresh = true;
}
@@ -600,14 +601,14 @@ void html_finish_conversion(html_content *htmlc)
}
/* convert dom tree to box tree */
- LOG("DOM to box (%p)", htmlc);
+ NSLOG(netsurf, INFO, "DOM to box (%p)", htmlc);
content_set_status(&htmlc->base, messages_get("Processing"));
msg_data.explicit_status_text = NULL;
- content_broadcast(&htmlc->base, CONTENT_MSG_STATUS, msg_data);
+ content_broadcast(&htmlc->base, CONTENT_MSG_STATUS, &msg_data);
exc = dom_document_get_document_element(htmlc->document, (void *) &html);
if ((exc != DOM_NO_ERR) || (html == NULL)) {
- LOG("error retrieving html element from dom");
+ NSLOG(netsurf, INFO, "error retrieving html element from dom");
content_broadcast_errorcode(&htmlc->base, NSERROR_DOM);
content_set_error(&htmlc->base);
return;
@@ -615,7 +616,7 @@ void html_finish_conversion(html_content *htmlc)
error = dom_to_box(html, htmlc, html_box_convert_done);
if (error != NSERROR_OK) {
- LOG("box conversion failed");
+ NSLOG(netsurf, INFO, "box conversion failed");
dom_node_unref(html);
html_object_free_objects(htmlc);
content_broadcast_errorcode(&htmlc->base, error);
@@ -685,10 +686,11 @@ dom_default_action_DOMNodeInserted_cb(struct dom_event *evt, void *pw)
msg_data.jscontext = &htmlc->jscontext;
content_broadcast(&htmlc->base,
CONTENT_MSG_GETCTX,
- msg_data);
- LOG("javascript context: %p (htmlc: %p)",
- htmlc->jscontext,
- htmlc);
+ &msg_data);
+ NSLOG(netsurf, INFO,
+ "javascript context: %p (htmlc: %p)",
+ htmlc->jscontext,
+ htmlc);
}
if (htmlc->jscontext != NULL) {
js_handle_new_element(htmlc->jscontext,
@@ -767,7 +769,7 @@ dom_event_fetcher(dom_string *type,
dom_default_action_phase phase,
void **pw)
{
- //LOG("type:%s", dom_string_data(type));
+ NSLOG(netsurf, DEEPDEBUG, "type:%s", dom_string_data(type));
if (phase == DOM_DEFAULT_ACTION_END) {
if (dom_string_isequal(type, corestring_dom_DOMNodeInserted)) {
@@ -794,22 +796,22 @@ html_document_user_data_handler(dom_node_operation operation,
switch (operation) {
case DOM_NODE_CLONED:
- LOG("Cloned");
+ NSLOG(netsurf, INFO, "Cloned");
break;
case DOM_NODE_RENAMED:
- LOG("Renamed");
+ NSLOG(netsurf, INFO, "Renamed");
break;
case DOM_NODE_IMPORTED:
- LOG("imported");
+ NSLOG(netsurf, INFO, "imported");
break;
case DOM_NODE_ADOPTED:
- LOG("Adopted");
+ NSLOG(netsurf, INFO, "Adopted");
break;
case DOM_NODE_DELETED:
/* This is the only path I expect */
break;
default:
- LOG("User data operation not handled.");
+ NSLOG(netsurf, INFO, "User data operation not handled.");
assert(0);
}
}
@@ -934,7 +936,7 @@ html_create_html_data(html_content *c, const http_parameter *params)
lwc_string_unref(c->universal);
c->universal = NULL;
- LOG("Unable to set user data.");
+ NSLOG(netsurf, INFO, "Unable to set user data.");
return NSERROR_DOM;
}
@@ -1141,11 +1143,11 @@ static bool html_convert(struct content *c)
exc = dom_document_get_quirks_mode(htmlc->document, &htmlc->quirks);
if (exc == DOM_NO_ERR) {
html_css_quirks_stylesheets(htmlc);
- LOG("quirks set to %d", htmlc->quirks);
+ NSLOG(netsurf, INFO, "quirks set to %d", htmlc->quirks);
}
htmlc->base.active--; /* the html fetch is no longer active */
- LOG("%d fetches active (%p)", htmlc->base.active, c);
+ NSLOG(netsurf, INFO, "%d fetches active (%p)", htmlc->base.active, c);
/* The parse cannot be completed here because it may be paused
* untill all the resources being fetched have completed.
@@ -1198,11 +1200,11 @@ html_begin_conversion(html_content *htmlc)
* complete to avoid repeating the completion pointlessly.
*/
if (htmlc->parse_completed == false) {
- LOG("Completing parse (%p)", htmlc);
+ NSLOG(netsurf, INFO, "Completing parse (%p)", htmlc);
/* complete parsing */
error = dom_hubbub_parser_completed(htmlc->parser);
if (error != DOM_HUBBUB_OK) {
- LOG("Parsing failed");
+ NSLOG(netsurf, INFO, "Parsing failed");
content_broadcast_errorcode(&htmlc->base,
libdom_hubbub_error_to_nserror(error));
@@ -1213,15 +1215,15 @@ html_begin_conversion(html_content *htmlc)
}
if (html_can_begin_conversion(htmlc) == false) {
- LOG("Can't begin conversion (%p)", htmlc);
+ NSLOG(netsurf, INFO, "Can't begin conversion (%p)", htmlc);
/* We can't proceed (see commentary above) */
return true;
}
/* Give up processing if we've been aborted */
if (htmlc->aborted) {
- LOG("Conversion aborted (%p) (active: %u)", htmlc,
- htmlc->base.active);
+ NSLOG(netsurf, INFO, "Conversion aborted (%p) (active: %u)",
+ htmlc, htmlc->base.active);
content_set_error(&htmlc->base);
content_broadcast_errorcode(&htmlc->base, NSERROR_STOPPED);
return false;
@@ -1257,7 +1259,7 @@ html_begin_conversion(html_content *htmlc)
/* locate root element and ensure it is html */
exc = dom_document_get_document_element(htmlc->document, (void *) &html);
if ((exc != DOM_NO_ERR) || (html == NULL)) {
- LOG("error retrieving html element from dom");
+ NSLOG(netsurf, INFO, "error retrieving html element from dom");
content_broadcast_errorcode(&htmlc->base, NSERROR_DOM);
return false;
}
@@ -1267,7 +1269,7 @@ html_begin_conversion(html_content *htmlc)
(node_name == NULL) ||
(!dom_string_caseless_lwc_isequal(node_name,
corestring_lwc_html))) {
- LOG("root element not html");
+ NSLOG(netsurf, INFO, "root element not html");
content_broadcast_errorcode(&htmlc->base, NSERROR_DOM);
dom_node_unref(html);
return false;
@@ -1373,7 +1375,8 @@ static void html_stop(struct content *c)
break;
default:
- LOG("Unexpected status %d (%p)", c->status, c);
+ NSLOG(netsurf, INFO, "Unexpected status %d (%p)", c->status,
+ c);
assert(0);
}
}
@@ -1530,7 +1533,7 @@ static void html_destroy(struct content *c)
html_content *html = (html_content *) c;
struct form *f, *g;
- LOG("content %p", c);
+ NSLOG(netsurf, INFO, "content %p", c);
/* Destroy forms */
for (f = html->forms; f != NULL; f = g) {
@@ -1919,7 +1922,7 @@ static void html__dom_user_data_handler(dom_node_operation operation,
free(data);
break;
default:
- LOG("User data operation not handled.");
+ NSLOG(netsurf, INFO, "User data operation not handled.");
assert(0);
}
}
@@ -1935,7 +1938,8 @@ static void html__set_file_gadget_filename(struct content *c,
ret = guit->utf8->local_to_utf8(fn, 0, &utf8_fn);
if (ret != NSERROR_OK) {
assert(ret != NSERROR_BAD_ENCODING);
- LOG("utf8 to local encoding conversion failed");
+ NSLOG(netsurf, INFO,
+ "utf8 to local encoding conversion failed");
/* Load was for us - just no memory */
return;
}
@@ -2087,7 +2091,7 @@ static bool html_drop_file_at_point(struct content *c, int x, int y, char *file)
if (ret != NSERROR_OK) {
/* bad encoding shouldn't happen */
assert(ret != NSERROR_BAD_ENCODING);
- LOG("local to utf8 encoding failed");
+ NSLOG(netsurf, INFO, "local to utf8 encoding failed");
free(buffer);
guit->misc->warning("NoMemory", NULL);
return true;
@@ -2153,19 +2157,19 @@ html_debug_dump(struct content *c, FILE *f, enum content_debug op)
ret = NSERROR_OK;
} else {
if (htmlc->document == NULL) {
- LOG("No document to dump");
+ NSLOG(netsurf, INFO, "No document to dump");
return NSERROR_DOM;
}
exc = dom_document_get_document_element(htmlc->document, (void *) &html);
if ((exc != DOM_NO_ERR) || (html == NULL)) {
- LOG("Unable to obtain root node");
+ NSLOG(netsurf, INFO, "Unable to obtain root node");
return NSERROR_DOM;
}
ret = libdom_dump_structure(html, f, 0);
- LOG("DOM structure dump returning %d", ret);
+ NSLOG(netsurf, INFO, "DOM structure dump returning %d", ret);
dom_node_unref(html);
}
diff --git a/render/html_css.c b/render/html_css.c
index 4d5469361..45bc16f56 100644
--- a/render/html_css.c
+++ b/render/html_css.c
@@ -103,17 +103,23 @@ html_convert_css_callback(hlcache_handle *css,
switch (event->type) {
case CONTENT_MSG_DONE:
- LOG("done stylesheet slot %d '%s'", i, nsurl_access(hlcache_handle_get_url(css)));
+ NSLOG(netsurf, INFO, "done stylesheet slot %d '%s'", i,
+ nsurl_access(hlcache_handle_get_url(css)));
parent->base.active--;
- LOG("%d fetches active", parent->base.active);
+ NSLOG(netsurf, INFO, "%d fetches active", parent->base.active);
break;
case CONTENT_MSG_ERROR:
- LOG("stylesheet %s failed: %s", nsurl_access(hlcache_handle_get_url(css)), event->data.error);
+ NSLOG(netsurf, INFO, "stylesheet %s failed: %s",
+ nsurl_access(hlcache_handle_get_url(css)),
+ event->data.error);
+ /* fall through */
+
+ case CONTENT_MSG_ERRORCODE:
hlcache_handle_release(css);
s->sheet = NULL;
parent->base.active--;
- LOG("%d fetches active", parent->base.active);
+ NSLOG(netsurf, INFO, "%d fetches active", parent->base.active);
content_add_error(&parent->base, "?", 0);
break;
@@ -150,7 +156,7 @@ html_stylesheet_from_domnode(html_content *c,
exc = dom_node_get_text_content(node, &style);
if ((exc != DOM_NO_ERR) || (style == NULL)) {
- LOG("No text content");
+ NSLOG(netsurf, INFO, "No text content");
return NSERROR_OK;
}
@@ -181,7 +187,7 @@ html_stylesheet_from_domnode(html_content *c,
nsurl_unref(url);
c->base.active++;
- LOG("%d fetches active", c->base.active);
+ NSLOG(netsurf, INFO, "%d fetches active", c->base.active);
return NSERROR_OK;
}
@@ -253,13 +259,14 @@ static bool html_css_process_modified_style(html_content *c,
error = html_stylesheet_from_domnode(c, s->node, &sheet);
if (error != NSERROR_OK) {
- LOG("Failed to update sheet");
+ NSLOG(netsurf, INFO, "Failed to update sheet");
content_broadcast_errorcode(&c->base, error);
return false;
}
if (sheet != NULL) {
- LOG("Updating sheet %p with %p", s->sheet, sheet);
+ NSLOG(netsurf, INFO, "Updating sheet %p with %p", s->sheet,
+ sheet);
if (s->sheet != NULL) {
switch (content_get_status(s->sheet)) {
@@ -268,7 +275,8 @@ static bool html_css_process_modified_style(html_content *c,
default:
hlcache_handle_abort(s->sheet);
c->base.active--;
- LOG("%d fetches active", c->base.active);
+ NSLOG(netsurf, INFO, "%d fetches active",
+ c->base.active);
}
hlcache_handle_release(s->sheet);
}
@@ -313,7 +321,9 @@ bool html_css_update_style(html_content *c, dom_node *style)
s = html_create_style_element(c, style);
}
if (s == NULL) {
- LOG("Could not find or create inline stylesheet for %p", style);
+ NSLOG(netsurf, INFO,
+ "Could not find or create inline stylesheet for %p",
+ style);
return false;
}
@@ -417,7 +427,8 @@ bool html_css_process_link(html_content *htmlc, dom_node *node)
}
dom_string_unref(href);
- LOG("linked stylesheet %i '%s'", htmlc->stylesheet_count, nsurl_access(joined));
+ NSLOG(netsurf, INFO, "linked stylesheet %i '%s'",
+ htmlc->stylesheet_count, nsurl_access(joined));
/* extend stylesheets array to allow for new sheet */
stylesheets = realloc(htmlc->stylesheets,
@@ -452,7 +463,7 @@ bool html_css_process_link(html_content *htmlc, dom_node *node)
htmlc->stylesheet_count++;
htmlc->base.active++;
- LOG("%d fetches active", htmlc->base.active);
+ NSLOG(netsurf, INFO, "%d fetches active", htmlc->base.active);
return true;
@@ -517,7 +528,7 @@ nserror html_css_quirks_stylesheets(html_content *c)
}
c->base.active++;
- LOG("%d fetches active", c->base.active);
+ NSLOG(netsurf, INFO, "%d fetches active", c->base.active);
}
return ns_error;
@@ -561,7 +572,7 @@ nserror html_css_new_stylesheets(html_content *c)
}
c->base.active++;
- LOG("%d fetches active", c->base.active);
+ NSLOG(netsurf, INFO, "%d fetches active", c->base.active);
if (nsoption_bool(block_advertisements)) {
@@ -575,7 +586,7 @@ nserror html_css_new_stylesheets(html_content *c)
}
c->base.active++;
- LOG("%d fetches active", c->base.active);
+ NSLOG(netsurf, INFO, "%d fetches active", c->base.active);
}
@@ -588,7 +599,7 @@ nserror html_css_new_stylesheets(html_content *c)
}
c->base.active++;
- LOG("%d fetches active", c->base.active);
+ NSLOG(netsurf, INFO, "%d fetches active", c->base.active);
return ns_error;
}
diff --git a/render/html_css_fetcher.c b/render/html_css_fetcher.c
index 9eda6aeb7..0f8809a42 100644
--- a/render/html_css_fetcher.c
+++ b/render/html_css_fetcher.c
@@ -61,13 +61,15 @@ static html_css_fetcher_context *ring = NULL;
static bool html_css_fetcher_initialise(lwc_string *scheme)
{
- LOG("html_css_fetcher_initialise called for %s", lwc_string_data(scheme));
+ NSLOG(netsurf, INFO, "html_css_fetcher_initialise called for %s",
+ lwc_string_data(scheme));
return true;
}
static void html_css_fetcher_finalise(lwc_string *scheme)
{
- LOG("html_css_fetcher_finalise called for %s", lwc_string_data(scheme));
+ NSLOG(netsurf, INFO, "html_css_fetcher_finalise called for %s",
+ lwc_string_data(scheme));
}
static bool html_css_fetcher_can_fetch(const nsurl *url)
@@ -251,7 +253,8 @@ static void html_css_fetcher_poll(lwc_string *scheme)
html_css_fetcher_send_callback(&msg, c);
}
} else {
- LOG("Processing of %s failed!", nsurl_access(c->url));
+ NSLOG(netsurf, INFO, "Processing of %s failed!",
+ nsurl_access(c->url));
/* Ensure that we're unlocked here. If we aren't,
* then html_css_fetcher_process() is broken.
@@ -290,7 +293,7 @@ nserror html_css_fetcher_register(void)
if (lwc_intern_string("x-ns-css", SLEN("x-ns-css"),
&scheme) != lwc_error_ok) {
- LOG("could not intern \"x-ns-css\".");
+ NSLOG(netsurf, INFO, "could not intern \"x-ns-css\".");
return NSERROR_INIT_FAILED;
}
diff --git a/render/html_interaction.c b/render/html_interaction.c
index e727a9ffc..30adaa080 100644
--- a/render/html_interaction.c
+++ b/render/html_interaction.c
@@ -289,7 +289,7 @@ html__image_coords_dom_user_data_handler(dom_node_operation operation,
break;
default:
- LOG("User data operation not handled.");
+ NSLOG(netsurf, INFO, "User data operation not handled.");
assert(0);
}
}
@@ -368,7 +368,7 @@ void html_mouse_action(struct content *c, struct browser_window *bw,
mouse, x - box_x, y - box_y);
if (status != NULL) {
msg_data.explicit_status_text = status;
- content_broadcast(c, CONTENT_MSG_STATUS, msg_data);
+ content_broadcast(c, CONTENT_MSG_STATUS, &msg_data);
} else {
int width, height;
form_select_get_dimensions(html->visible_select_menu,
@@ -459,7 +459,7 @@ void html_mouse_action(struct content *c, struct browser_window *bw,
}
msg_data.explicit_status_text = status;
- content_broadcast(c, CONTENT_MSG_STATUS, msg_data);
+ content_broadcast(c, CONTENT_MSG_STATUS, &msg_data);
return;
}
@@ -678,7 +678,7 @@ void html_mouse_action(struct content *c, struct browser_window *bw,
} else if (mouse & BROWSER_MOUSE_CLICK_1) {
msg_data.select_menu.gadget = gadget;
content_broadcast(c, CONTENT_MSG_SELECTMENU,
- msg_data);
+ &msg_data);
}
break;
case GADGET_CHECKBOX:
@@ -697,6 +697,7 @@ void html_mouse_action(struct content *c, struct browser_window *bw,
form_radio_set(gadget);
break;
case GADGET_IMAGE:
+ /* This falls through to SUBMIT */
if (mouse & BROWSER_MOUSE_CLICK_1) {
struct image_input_coords *coords, *oldcoords;
/** \todo Find a way to not ignore errors */
@@ -714,7 +715,7 @@ void html_mouse_action(struct content *c, struct browser_window *bw,
return;
free(oldcoords);
}
- /* drop through */
+ /* Fall through */
case GADGET_SUBMIT:
if (gadget->form) {
snprintf(status_buffer, sizeof status_buffer,
@@ -768,7 +769,8 @@ void html_mouse_action(struct content *c, struct browser_window *bw,
status = messages_get("FormFile");
if (mouse & BROWSER_MOUSE_CLICK_1) {
msg_data.gadget_click.gadget = gadget;
- content_broadcast(c, CONTENT_MSG_GADGETCLICK, msg_data);
+ content_broadcast(c, CONTENT_MSG_GADGETCLICK,
+ &msg_data);
}
break;
case GADGET_BUTTON:
@@ -782,12 +784,12 @@ void html_mouse_action(struct content *c, struct browser_window *bw,
if (mouse & BROWSER_MOUSE_DRAG_2) {
msg_data.dragsave.type = CONTENT_SAVE_NATIVE;
msg_data.dragsave.content = object;
- content_broadcast(c, CONTENT_MSG_DRAGSAVE, msg_data);
+ content_broadcast(c, CONTENT_MSG_DRAGSAVE, &msg_data);
} else if (mouse & BROWSER_MOUSE_DRAG_1) {
msg_data.dragsave.type = CONTENT_SAVE_ORIG;
msg_data.dragsave.content = object;
- content_broadcast(c, CONTENT_MSG_DRAGSAVE, msg_data);
+ content_broadcast(c, CONTENT_MSG_DRAGSAVE, &msg_data);
}
/* \todo should have a drag-saving object msg */
@@ -869,7 +871,7 @@ void html_mouse_action(struct content *c, struct browser_window *bw,
mouse & BROWSER_MOUSE_MOD_1) {
msg_data.savelink.url = url;
msg_data.savelink.title = title;
- content_broadcast(c, CONTENT_MSG_SAVELINK, msg_data);
+ content_broadcast(c, CONTENT_MSG_SAVELINK, &msg_data);
} else if (mouse & (BROWSER_MOUSE_CLICK_1 |
BROWSER_MOUSE_CLICK_2))
@@ -968,7 +970,7 @@ void html_mouse_action(struct content *c, struct browser_window *bw,
msg_data.dragsave.content = NULL;
content_broadcast(c,
CONTENT_MSG_DRAGSAVE,
- msg_data);
+ &msg_data);
} else {
if (drag_candidate == NULL) {
browser_window_page_drag_start(
@@ -988,7 +990,7 @@ void html_mouse_action(struct content *c, struct browser_window *bw,
msg_data.dragsave.content = NULL;
content_broadcast(c,
CONTENT_MSG_DRAGSAVE,
- msg_data);
+ &msg_data);
} else {
if (drag_candidate == NULL) {
browser_window_page_drag_start(
@@ -1013,10 +1015,10 @@ void html_mouse_action(struct content *c, struct browser_window *bw,
if (!iframe && !html_object_box) {
msg_data.explicit_status_text = status;
- content_broadcast(c, CONTENT_MSG_STATUS, msg_data);
+ content_broadcast(c, CONTENT_MSG_STATUS, &msg_data);
msg_data.pointer = pointer;
- content_broadcast(c, CONTENT_MSG_POINTER, msg_data);
+ content_broadcast(c, CONTENT_MSG_POINTER, &msg_data);
}
/* fire dom click event */
@@ -1217,7 +1219,7 @@ void html_overflow_scroll_callback(void *client_data,
html_set_drag_type(html, drag_type, drag_owner, NULL);
msg_data.pointer = BROWSER_POINTER_AUTO;
- content_broadcast(data->c, CONTENT_MSG_POINTER, msg_data);
+ content_broadcast(data->c, CONTENT_MSG_POINTER, &msg_data);
break;
}
}
@@ -1292,7 +1294,7 @@ void html_set_drag_type(html_content *html, html_drag_type drag_type,
msg_data.drag.rect = rect;
/* Inform of the content's drag status change */
- content_broadcast((struct content *)html, CONTENT_MSG_DRAG, msg_data);
+ content_broadcast((struct content *)html, CONTENT_MSG_DRAG, &msg_data);
}
/* Documented in html_internal.h */
@@ -1350,7 +1352,7 @@ void html_set_focus(html_content *html, html_focus_type focus_type,
}
/* Inform of the content's drag status change */
- content_broadcast((struct content *)html, CONTENT_MSG_CARET, msg_data);
+ content_broadcast((struct content *)html, CONTENT_MSG_CARET, &msg_data);
}
/* Documented in html_internal.h */
@@ -1426,5 +1428,5 @@ void html_set_selection(html_content *html, html_selection_type selection_type,
/* Inform of the content's selection status change */
content_broadcast((struct content *)html, CONTENT_MSG_SELECTION,
- msg_data);
+ &msg_data);
}
diff --git a/render/html_object.c b/render/html_object.c
index e20cd6d63..e98bdba0b 100644
--- a/render/html_object.c
+++ b/render/html_object.c
@@ -125,7 +125,9 @@ html_object_callback(hlcache_handle *object,
struct box *box;
box = o->box;
- if (box == NULL && event->type != CONTENT_MSG_ERROR) {
+ if (box == NULL &&
+ event->type != CONTENT_MSG_ERROR &&
+ event->type != CONTENT_MSG_ERRORCODE) {
return NSERROR_OK;
}
@@ -158,7 +160,7 @@ html_object_callback(hlcache_handle *object,
case CONTENT_MSG_DONE:
c->base.active--;
- LOG("%d fetches active", c->base.active);
+ NSLOG(netsurf, INFO, "%d fetches active", c->base.active);
html_object_done(box, object, o->background);
@@ -177,10 +179,11 @@ html_object_callback(hlcache_handle *object,
data.redraw.height = box->height;
data.redraw.full_redraw = true;
- content_broadcast(&c->base, CONTENT_MSG_REDRAW, data);
+ content_broadcast(&c->base, CONTENT_MSG_REDRAW, &data);
}
break;
+ case CONTENT_MSG_ERRORCODE:
case CONTENT_MSG_ERROR:
hlcache_handle_release(object);
@@ -188,7 +191,8 @@ html_object_callback(hlcache_handle *object,
if (box != NULL) {
c->base.active--;
- LOG("%d fetches active", c->base.active);
+ NSLOG(netsurf, INFO, "%d fetches active",
+ c->base.active);
content_add_error(&c->base, "?", 0);
html_object_failed(box, c, o->background);
@@ -276,7 +280,7 @@ html_object_callback(hlcache_handle *object,
data.redraw.object_y += y;
content_broadcast(&c->base,
- CONTENT_MSG_REDRAW, data);
+ CONTENT_MSG_REDRAW, &data);
break;
} else {
@@ -315,7 +319,7 @@ html_object_callback(hlcache_handle *object,
data.redraw.object_y += y + box->padding[TOP];
}
- content_broadcast(&c->base, CONTENT_MSG_REDRAW, data);
+ content_broadcast(&c->base, CONTENT_MSG_REDRAW, &data);
}
break;
@@ -354,7 +358,7 @@ html_object_callback(hlcache_handle *object,
msg_data.dragsave.content =
event->data.dragsave.content;
- content_broadcast(&c->base, CONTENT_MSG_DRAGSAVE, msg_data);
+ content_broadcast(&c->base, CONTENT_MSG_DRAGSAVE, &msg_data);
}
break;
@@ -364,7 +368,7 @@ html_object_callback(hlcache_handle *object,
case CONTENT_MSG_GADGETCLICK:
/* These messages are for browser window layer.
* we're not interested, so pass them on. */
- content_broadcast(&c->base, event->type, event->data);
+ content_broadcast(&c->base, event->type, &event->data);
break;
case CONTENT_MSG_CARET:
@@ -437,7 +441,8 @@ html_object_callback(hlcache_handle *object,
c->base.active == 0 &&
(event->type == CONTENT_MSG_LOADING ||
event->type == CONTENT_MSG_DONE ||
- event->type == CONTENT_MSG_ERROR)) {
+ event->type == CONTENT_MSG_ERROR ||
+ event->type == CONTENT_MSG_ERRORCODE)) {
/* all objects have arrived */
content__reformat(&c->base, false, c->base.available_width,
c->base.height);
@@ -499,7 +504,8 @@ static bool html_replace_object(struct content_html_object *object, nsurl *url)
/* remove existing object */
if (content_get_status(object->content) != CONTENT_STATUS_DONE) {
c->base.active--;
- LOG("%d fetches active", c->base.active);
+ NSLOG(netsurf, INFO, "%d fetches active",
+ c->base.active);
}
hlcache_handle_release(object->content);
@@ -520,7 +526,7 @@ static bool html_replace_object(struct content_html_object *object, nsurl *url)
for (page = c; page != NULL; page = page->page) {
page->base.active++;
- LOG("%d fetches active", c->base.active);
+ NSLOG(netsurf, INFO, "%d fetches active", c->base.active);
page->base.status = CONTENT_STATUS_READY;
}
@@ -603,7 +609,8 @@ nserror html_object_abort_objects(html_content *htmlc)
object->content = NULL;
if (object->box != NULL) {
htmlc->base.active--;
- LOG("%d fetches active", htmlc->base.active);
+ NSLOG(netsurf, INFO, "%d fetches active",
+ htmlc->base.active);
}
break;
@@ -641,7 +648,7 @@ nserror html_object_free_objects(html_content *html)
struct content_html_object *victim = html->object_list;
if (victim->content != NULL) {
- LOG("object %p", victim->content);
+ NSLOG(netsurf, INFO, "object %p", victim->content);
if (content_get_type(victim->content) == CONTENT_HTML) {
guit->misc->schedule(-1, html_object_refresh, victim);
@@ -703,7 +710,7 @@ bool html_fetch_object(html_content *c, nsurl *url, struct box *box,
c->num_objects++;
if (box != NULL) {
c->base.active++;
- LOG("%d fetches active", c->base.active);
+ NSLOG(netsurf, INFO, "%d fetches active", c->base.active);
}
return true;
diff --git a/render/html_script.c b/render/html_script.c
index 37b0564d7..c73a4806d 100644
--- a/render/html_script.c
+++ b/render/html_script.c
@@ -96,7 +96,7 @@ nserror html_script_exec(html_content *c)
s->already_started = true;
- }
+ }
}
}
@@ -105,8 +105,8 @@ nserror html_script_exec(html_content *c)
/* create new html script entry */
static struct html_script *
-html_process_new_script(html_content *c,
- dom_string *mimetype,
+html_process_new_script(html_content *c,
+ dom_string *mimetype,
enum html_script_type type)
{
struct html_script *nscript;
@@ -165,18 +165,24 @@ convert_script_async_cb(hlcache_handle *script,
break;
case CONTENT_MSG_DONE:
- LOG("script %d done '%s'", i, nsurl_access(hlcache_handle_get_url(script)));
+ NSLOG(netsurf, INFO, "script %d done '%s'", i,
+ nsurl_access(hlcache_handle_get_url(script)));
parent->base.active--;
- LOG("%d fetches active", parent->base.active);
+ NSLOG(netsurf, INFO, "%d fetches active", parent->base.active);
break;
case CONTENT_MSG_ERROR:
- LOG("script %s failed: %s", nsurl_access(hlcache_handle_get_url(script)), event->data.error);
+ NSLOG(netsurf, INFO, "script %s failed: %s",
+ nsurl_access(hlcache_handle_get_url(script)),
+ event->data.error);
+ /* fall through */
+
+ case CONTENT_MSG_ERRORCODE:
hlcache_handle_release(script);
s->data.handle = NULL;
parent->base.active--;
- LOG("%d fetches active", parent->base.active);
+ NSLOG(netsurf, INFO, "%d fetches active", parent->base.active);
content_add_error(&parent->base, "?", 0);
break;
@@ -218,18 +224,24 @@ convert_script_defer_cb(hlcache_handle *script,
switch (event->type) {
case CONTENT_MSG_DONE:
- LOG("script %d done '%s'", i, nsurl_access(hlcache_handle_get_url(script)));
+ NSLOG(netsurf, INFO, "script %d done '%s'", i,
+ nsurl_access(hlcache_handle_get_url(script)));
parent->base.active--;
- LOG("%d fetches active", parent->base.active);
+ NSLOG(netsurf, INFO, "%d fetches active", parent->base.active);
break;
case CONTENT_MSG_ERROR:
- LOG("script %s failed: %s", nsurl_access(hlcache_handle_get_url(script)), event->data.error);
+ NSLOG(netsurf, INFO, "script %s failed: %s",
+ nsurl_access(hlcache_handle_get_url(script)),
+ event->data.error);
+ /* fall through */
+
+ case CONTENT_MSG_ERRORCODE:
hlcache_handle_release(script);
s->data.handle = NULL;
parent->base.active--;
- LOG("%d fetches active", parent->base.active);
+ NSLOG(netsurf, INFO, "%d fetches active", parent->base.active);
content_add_error(&parent->base, "?", 0);
break;
@@ -272,9 +284,10 @@ convert_script_sync_cb(hlcache_handle *script,
switch (event->type) {
case CONTENT_MSG_DONE:
- LOG("script %d done '%s'", i, nsurl_access(hlcache_handle_get_url(script)));
+ NSLOG(netsurf, INFO, "script %d done '%s'", i,
+ nsurl_access(hlcache_handle_get_url(script)));
parent->base.active--;
- LOG("%d fetches active", parent->base.active);
+ NSLOG(netsurf, INFO, "%d fetches active", parent->base.active);
s->already_started = true;
@@ -291,19 +304,23 @@ convert_script_sync_cb(hlcache_handle *script,
/* continue parse */
err = dom_hubbub_parser_pause(parent->parser, false);
if (err != DOM_HUBBUB_OK) {
- LOG("unpause returned 0x%x", err);
- }
+ NSLOG(netsurf, INFO, "unpause returned 0x%x", err);
+ }
break;
case CONTENT_MSG_ERROR:
- LOG("script %s failed: %s", nsurl_access(hlcache_handle_get_url(script)), event->data.error);
+ NSLOG(netsurf, INFO, "script %s failed: %s",
+ nsurl_access(hlcache_handle_get_url(script)),
+ event->data.error);
+ /* fall through */
+ case CONTENT_MSG_ERRORCODE:
hlcache_handle_release(script);
s->data.handle = NULL;
parent->base.active--;
- LOG("%d fetches active", parent->base.active);
+ NSLOG(netsurf, INFO, "%d fetches active", parent->base.active);
content_add_error(&parent->base, "?", 0);
s->already_started = true;
@@ -311,8 +328,8 @@ convert_script_sync_cb(hlcache_handle *script,
/* continue parse */
err = dom_hubbub_parser_pause(parent->parser, false);
if (err != DOM_HUBBUB_OK) {
- LOG("unpause returned 0x%x", err);
- }
+ NSLOG(netsurf, INFO, "unpause returned 0x%x", err);
+ }
break;
@@ -343,7 +360,6 @@ exec_src_script(html_content *c,
nsurl *joined;
hlcache_child_context child;
struct html_script *nscript;
- union content_msg_data msg_data;
bool async;
bool defer;
enum html_script_type script_type;
@@ -354,21 +370,21 @@ exec_src_script(html_content *c,
/* src url */
ns_error = nsurl_join(c->base_url, dom_string_data(src), &joined);
if (ns_error != NSERROR_OK) {
- msg_data.error = messages_get("NoMemory");
- content_broadcast(&c->base, CONTENT_MSG_ERROR, msg_data);
+ content_broadcast_errorcode(&c->base, NSERROR_NOMEM);
return DOM_HUBBUB_NOMEM;
}
- LOG("script %i '%s'", c->scripts_count, nsurl_access(joined));
+ NSLOG(netsurf, INFO, "script %i '%s'", c->scripts_count,
+ nsurl_access(joined));
/* there are three ways to process the script tag at this point:
*
* Syncronously pause the parent parse and continue after
* the script has downloaded and executed. (default)
- * Async Start the script downloading and execute it when it
- * becomes available.
- * Defered Start the script downloading and execute it when
- * the page has completed parsing, may be set along
+ * Async Start the script downloading and execute it when it
+ * becomes available.
+ * Defered Start the script downloading and execute it when
+ * the page has completed parsing, may be set along
* with async where it is ignored.
*/
@@ -377,7 +393,7 @@ exec_src_script(html_content *c,
* value or the attribute name itself are valid. However
* various browsers interpret this in various ways the most
* compatible approach is to be liberal and accept any
- * value. Note setting the values to "false" still makes them true!
+ * value. Note setting the values to "false" still makes them true!
*/
exc = dom_element_has_attribute(node, corestring_dom_async, &async);
if (exc != DOM_NO_ERR) {
@@ -390,7 +406,7 @@ exec_src_script(html_content *c,
script_cb = convert_script_async_cb;
} else {
- exc = dom_element_has_attribute(node,
+ exc = dom_element_has_attribute(node,
corestring_dom_defer, &defer);
if (exc != DOM_NO_ERR) {
return DOM_HUBBUB_OK; /* dom error */
@@ -410,8 +426,7 @@ exec_src_script(html_content *c,
nscript = html_process_new_script(c, mimetype, script_type);
if (nscript == NULL) {
nsurl_unref(joined);
- msg_data.error = messages_get("NoMemory");
- content_broadcast(&c->base, CONTENT_MSG_ERROR, msg_data);
+ content_broadcast_errorcode(&c->base, NSERROR_NOMEM);
return DOM_HUBBUB_NOMEM;
}
@@ -434,15 +449,15 @@ exec_src_script(html_content *c,
if (ns_error != NSERROR_OK) {
/* @todo Deal with fetch error better. currently assume
- * fetch never became active
+ * fetch never became active
*/
/* mark duff script fetch as already started */
- nscript->already_started = true;
- LOG("Fetch failed with error %d", ns_error);
+ nscript->already_started = true;
+ NSLOG(netsurf, INFO, "Fetch failed with error %d", ns_error);
} else {
/* update base content active fetch count */
- c->base.active++;
- LOG("%d fetches active", c->base.active);
+ c->base.active++;
+ NSLOG(netsurf, INFO, "%d fetches active", c->base.active);
switch (script_type) {
case HTML_SCRIPT_SYNC:
@@ -465,7 +480,6 @@ exec_src_script(html_content *c,
static dom_hubbub_error
exec_inline_script(html_content *c, dom_node *node, dom_string *mimetype)
{
- union content_msg_data msg_data;
dom_string *script;
dom_exception exc; /* returned by libdom functions */
struct lwc_string_s *lwcmimetype;
@@ -482,8 +496,7 @@ exec_inline_script(html_content *c, dom_node *node, dom_string *mimetype)
if (nscript == NULL) {
dom_string_unref(script);
- msg_data.error = messages_get("NoMemory");
- content_broadcast(&c->base, CONTENT_MSG_ERROR, msg_data);
+ content_broadcast_errorcode(&c->base, NSERROR_NOMEM);
return DOM_HUBBUB_NOMEM;
}
@@ -526,15 +539,16 @@ html_process_script(void *ctx, dom_node *node)
union content_msg_data msg_data;
msg_data.jscontext = &c->jscontext;
- content_broadcast(&c->base, CONTENT_MSG_GETCTX, msg_data);
- LOG("javascript context %p ", c->jscontext);
+ content_broadcast(&c->base, CONTENT_MSG_GETCTX, &msg_data);
+ NSLOG(netsurf, INFO, "javascript context %p ", c->jscontext);
if (c->jscontext == NULL) {
/* no context and it could not be created, abort */
return DOM_HUBBUB_OK;
}
}
- LOG("content %p parser %p node %p", c, c->parser, node);
+ NSLOG(netsurf, INFO, "content %p parser %p node %p", c, c->parser,
+ node);
exc = dom_element_get_attribute(node, corestring_dom_type, &mimetype);
if (exc != DOM_NO_ERR || mimetype == NULL) {
diff --git a/render/imagemap.c b/render/imagemap.c
index 6e2504bdc..0d3b42a1b 100644
--- a/render/imagemap.c
+++ b/render/imagemap.c
@@ -241,21 +241,35 @@ void imagemap_dump(html_content *c)
map = c->imagemaps[i];
while (map != NULL) {
- LOG("Imagemap: %s", map->key);
+ NSLOG(netsurf, INFO, "Imagemap: %s", map->key);
for (entry = map->list; entry; entry = entry->next) {
switch (entry->type) {
case IMAGEMAP_DEFAULT:
- LOG("\tDefault: %s", nsurl_access(entry->url));
+ NSLOG(netsurf, INFO, "\tDefault: %s",
+ nsurl_access(entry->url));
break;
case IMAGEMAP_RECT:
- LOG("\tRectangle: %s: [(%d,%d),(%d,%d)]", nsurl_access(entry->url), entry->bounds.rect.x0, entry->bounds.rect.y0, entry->bounds.rect.x1, entry->bounds.rect.y1);
+ NSLOG(netsurf, INFO,
+ "\tRectangle: %s: [(%d,%d),(%d,%d)]",
+ nsurl_access(entry->url),
+ entry->bounds.rect.x0,
+ entry->bounds.rect.y0,
+ entry->bounds.rect.x1,
+ entry->bounds.rect.y1);
break;
case IMAGEMAP_CIRCLE:
- LOG("\tCircle: %s: [(%d,%d),%d]", nsurl_access(entry->url), entry->bounds.circle.x, entry->bounds.circle.y, entry->bounds.circle.r);
+ NSLOG(netsurf, INFO,
+ "\tCircle: %s: [(%d,%d),%d]",
+ nsurl_access(entry->url),
+ entry->bounds.circle.x,
+ entry->bounds.circle.y,
+ entry->bounds.circle.r);
break;
case IMAGEMAP_POLY:
- LOG("\tPolygon: %s:", nsurl_access(entry->url));
+ NSLOG(netsurf, INFO,
+ "\tPolygon: %s:",
+ nsurl_access(entry->url));
for (j = 0; j != entry->bounds.poly.num;
j++) {
fprintf(stderr, "(%d,%d) ",
diff --git a/render/layout.c b/render/layout.c
index 6782fdfc6..7ca688fab 100644
--- a/render/layout.c
+++ b/render/layout.c
@@ -47,6 +47,7 @@
#include "utils/talloc.h"
#include "utils/utils.h"
#include "utils/nsoption.h"
+#include "netsurf/inttypes.h"
#include "netsurf/content.h"
#include "netsurf/browser_window.h"
#include "netsurf/layout.h"
@@ -62,10 +63,6 @@
#include "render/layout.h"
#include "render/table.h"
-
-/* Define to enable layout debugging */
-#undef LAYOUT_DEBUG
-
#define AUTO INT_MIN
/* Fixed point percentage (a) of an integer (b), to an integer */
@@ -342,9 +339,7 @@ layout_minmax_line(struct box *first,
b->type == BOX_BR || b->type == BOX_TEXT ||
b->type == BOX_INLINE_END);
-#ifdef LAYOUT_DEBUG
- LOG("%p: min %i, max %i", b, min, max);
-#endif
+ NSLOG(layout, DEBUG, "%p: min %i, max %i", b, min, max);
if (b->type == BOX_BR) {
b = b->next;
@@ -624,9 +619,7 @@ layout_minmax_line(struct box *first,
*line_min = min;
*line_max = max;
-#ifdef LAYOUT_DEBUG
- LOG("line_min %i, line_max %i", min, max);
-#endif
+ NSLOG(layout, DEBUG, "line_min %i, line_max %i", min, max);
assert(b != first);
assert(0 <= *line_min);
@@ -1117,7 +1110,7 @@ layout_find_dimensions(int available_width,
css_fixed value = 0;
css_unit unit = CSS_UNIT_PX;
- type = css_computed_min_width(style, &value, &unit);
+ type = ns_computed_min_width(style, &value, &unit);
if (type == CSS_MIN_WIDTH_SET) {
if (unit == CSS_UNIT_PCT) {
@@ -1164,7 +1157,7 @@ layout_find_dimensions(int available_width,
css_fixed value = 0;
css_unit unit = CSS_UNIT_PX;
- type = css_computed_min_height(style, &value, &unit);
+ type = ns_computed_min_height(style, &value, &unit);
if (type == CSS_MIN_HEIGHT_SET) {
if (unit == CSS_UNIT_PCT) {
@@ -1469,9 +1462,7 @@ find_sides(struct box *fl,
{
int fy0, fy1, fx0, fx1;
-#ifdef LAYOUT_DEBUG
- LOG("y0 %i, y1 %i, x0 %i, x1 %i", y0, y1, *x0, *x1);
-#endif
+ NSLOG(layout, DEBUG, "y0 %i, y1 %i, x0 %i, x1 %i", y0, y1, *x0, *x1);
*left = *right = 0;
for (; fl; fl = fl->next_float) {
@@ -1500,9 +1491,8 @@ find_sides(struct box *fl,
}
}
-#ifdef LAYOUT_DEBUG
- LOG("x0 %i, x1 %i, left %p, right %p", *x0, *x1, *left, *right);
-#endif
+ NSLOG(layout, DEBUG, "x0 %i, x1 %i, left %p, right %p", *x0, *x1,
+ *left, *right);
}
@@ -1964,15 +1954,22 @@ static bool layout_table(struct box *table, int available_width,
/* calculate width required by cells */
for (i = 0; i != columns; i++) {
-#ifdef LAYOUT_DEBUG
- LOG("table %p, column %u: type %s, width %i, min %i, max %i", table, i, ((const char *[]){
- "UNKNOWN",
- "FIXED",
- "AUTO",
- "PERCENT",
- "RELATIVE"
- })[col[i].type], col[i].width, col[i].min, col[i].max);
-#endif
+
+ NSLOG(layout, DEBUG,
+ "table %p, column %u: type %s, width %i, min %i, max %i",
+ table,
+ i,
+ ((const char *[]){
+ "UNKNOWN",
+ "FIXED",
+ "AUTO",
+ "PERCENT",
+ "RELATIVE",
+ })[col[i].type],
+ col[i].width,
+ col[i].min,
+ col[i].max);
+
if (col[i].positioned) {
positioned_columns++;
@@ -1990,16 +1987,14 @@ static bool layout_table(struct box *table, int available_width,
} else
required_width += col[i].min;
-#ifdef LAYOUT_DEBUG
- LOG("required_width %i", required_width);
-#endif
+ NSLOG(layout, DEBUG, "required_width %i", required_width);
}
required_width += (columns + 1 - positioned_columns) *
border_spacing_h;
-#ifdef LAYOUT_DEBUG
- LOG("width %i, min %i, max %i, auto %i, required %i", table_width, table->min_width, table->max_width, auto_width, required_width);
-#endif
+ NSLOG(layout, DEBUG,
+ "width %i, min %i, max %i, auto %i, required %i", table_width,
+ table->min_width, table->max_width, auto_width, required_width);
if (auto_width < required_width) {
/* table narrower than required width for columns:
@@ -2400,7 +2395,7 @@ static bool layout_apply_minmax_height(struct box *box, struct box *container)
}
/* min-height */
- if (css_computed_min_height(box->style, &value, &unit) ==
+ if (ns_computed_min_height(box->style, &value, &unit) ==
CSS_MIN_HEIGHT_SET) {
if (unit == CSS_UNIT_PCT) {
if (containing_block &&
@@ -2448,9 +2443,8 @@ static bool layout_block_object(struct box *block)
block->type == BOX_TABLE_CELL);
assert(block->object);
-#ifdef LAYOUT_DEBUG
- LOG("block %p, object %s, width %i", block, hlcache_handle_get_url(block->object), block->width);
-#endif
+ NSLOG(layout, DEBUG, "block %p, object %p, width %i", block,
+ hlcache_handle_get_url(block->object), block->width);
if (content_get_type(block->object) == CONTENT_HTML) {
content_reformat(block->object, false, block->width, 1);
@@ -2746,9 +2740,7 @@ layout_block_context(struct box *block,
goto advance_to_next_box;
}
-#ifdef LAYOUT_DEBUG
- LOG("box %p, cx %i, cy %i", box, cx, cy);
-#endif
+ NSLOG(layout, DEBUG, "box %p, cx %i, cy %i", box, cx, cy);
/* Layout (except tables). */
if (box->object) {
@@ -3187,9 +3179,12 @@ layout_absolute(struct box *box,
box->float_container = NULL;
/* 10.3.7 */
-#ifdef LAYOUT_DEBUG
- LOG("%i + %i + %i + %i + %i + %i + %i + %i + %i = %i", left, margin[LEFT], border[LEFT].width, padding[LEFT], width, padding[RIGHT], border[RIGHT].width, margin[RIGHT], right, containing_block->width);
-#endif
+ NSLOG(layout, DEBUG,
+ "%i + %i + %i + %i + %i + %i + %i + %i + %i = %i",
+ left, margin[LEFT], border[LEFT].width, padding[LEFT], width,
+ padding[RIGHT], border[RIGHT].width, margin[RIGHT], right,
+ containing_block->width);
+
if (left == AUTO && width == AUTO && right == AUTO) {
if (margin[LEFT] == AUTO)
@@ -3352,9 +3347,11 @@ layout_absolute(struct box *box,
}
}
-#ifdef LAYOUT_DEBUG
- LOG("%i + %i + %i + %i + %i + %i + %i + %i + %i = %i", left, margin[LEFT], border[LEFT].width, padding[LEFT], width, padding[RIGHT], border[RIGHT].width, margin[RIGHT], right, containing_block->width);
-#endif
+ NSLOG(layout, DEBUG,
+ "%i + %i + %i + %i + %i + %i + %i + %i + %i = %i",
+ left, margin[LEFT], border[LEFT].width, padding[LEFT], width,
+ padding[RIGHT], border[RIGHT].width, margin[RIGHT], right,
+ containing_block->width);
box->x = left + margin[LEFT] + border[LEFT].width - cx;
if (containing_block->type == BOX_BLOCK ||
@@ -3386,9 +3383,11 @@ layout_absolute(struct box *box,
}
/* 10.6.4 */
-#ifdef LAYOUT_DEBUG
- LOG("%i + %i + %i + %i + %i + %i + %i + %i + %i = %i", top, margin[TOP], border[TOP].width, padding[TOP], height, padding[BOTTOM], border[BOTTOM].width, margin[BOTTOM], bottom, containing_block->height);
-#endif
+ NSLOG(layout, DEBUG,
+ "%i + %i + %i + %i + %i + %i + %i + %i + %i = %i",
+ top, margin[TOP], border[TOP].width, padding[TOP], height,
+ padding[BOTTOM], border[BOTTOM].width, margin[BOTTOM], bottom,
+ containing_block->height);
if (top == AUTO && height == AUTO && bottom == AUTO) {
top = static_top;
@@ -3474,9 +3473,11 @@ layout_absolute(struct box *box,
}
}
-#ifdef LAYOUT_DEBUG
- LOG("%i + %i + %i + %i + %i + %i + %i + %i + %i = %i", top, margin[TOP], border[TOP].width, padding[TOP], height, padding[BOTTOM], border[BOTTOM].width, margin[BOTTOM], bottom, containing_block->height);
-#endif
+ NSLOG(layout, DEBUG,
+ "%i + %i + %i + %i + %i + %i + %i + %i + %i = %i",
+ top, margin[TOP], border[TOP].width, padding[TOP], height,
+ padding[BOTTOM], border[BOTTOM].width, margin[BOTTOM], bottom,
+ containing_block->height);
box->y = top + margin[TOP] + border[TOP].width - cy;
if (containing_block->type == BOX_BLOCK ||
@@ -3624,9 +3625,8 @@ static void layout_compute_relative_offset(struct box *box, int *x, int *y)
bottom = -top;
}
-#ifdef LAYOUT_DEBUG
- LOG("left %i, right %i, top %i, bottom %i", left, right, top, bottom);
-#endif
+ NSLOG(layout, DEBUG, "left %i, right %i, top %i, bottom %i", left,
+ right, top, bottom);
*x = left;
*y = top;
@@ -3887,10 +3887,20 @@ layout_text_box_split(html_content *content,
c2->next->prev = c2;
else
c2->parent->last = c2;
-#ifdef LAYOUT_DEBUG
- LOG("split_box %p len: %u \"%.*s\"", split_box, split_box->length, split_box->length, split_box->text);
- LOG(" new_box %p len: %u \"%.*s\"", c2, c2->length, c2->length, c2->text);
-#endif
+
+ NSLOG(layout, DEBUG,
+ "split_box %p len: %" PRIsizet " \"%.*s\"",
+ split_box,
+ split_box->length,
+ (int)split_box->length,
+ split_box->text);
+ NSLOG(layout, DEBUG,
+ " new_box %p len: %" PRIsizet " \"%.*s\"",
+ c2,
+ c2->length,
+ (int)c2->length,
+ c2->text);
+
return true;
}
@@ -4079,9 +4089,9 @@ place_float_below(struct box *c, int width, int cx, int y, struct box *cont)
yy = y > cont->cached_place_below_level ?
y : cont->cached_place_below_level;
-#ifdef LAYOUT_DEBUG
- LOG("c %p, width %i, cx %i, y %i, cont %p", c, width, cx, y, cont);
-#endif
+ NSLOG(layout, DEBUG,
+ "c %p, width %i, cx %i, y %i, cont %p", c,
+ width, cx, y, cont);
do {
y = yy;
@@ -4158,9 +4168,15 @@ layout_line(struct box *first,
const struct gui_layout_table *font_func = content->font_func;
plot_font_style_t fstyle;
-#ifdef LAYOUT_DEBUG
- LOG("first %p, first->text '%.*s', width %i, y %i, cx %i, cy %i", first, (int)first->length, first->text, *width, *y, cx, cy);
-#endif
+ NSLOG(layout, DEBUG,
+ "first %p, first->text '%.*s', width %i, y %i, cx %i, cy %i",
+ first,
+ (int)first->length,
+ first->text,
+ *width,
+ *y,
+ cx,
+ cy);
/* find sides at top of line */
x0 += cx;
@@ -4189,9 +4205,9 @@ layout_line(struct box *first,
/* pass 1: find height of line assuming sides at top of line: loop
* body executed at least once
* keep in sync with the loop in layout_minmax_line() */
-#ifdef LAYOUT_DEBUG
- LOG("x0 %i, x1 %i, x1 - x0 %i", x0, x1, x1 - x0);
-#endif
+
+ NSLOG(layout, DEBUG, "x0 %i, x1 %i, x1 - x0 %i", x0, x1, x1 - x0);
+
for (x = 0, b = first; x <= x1 - x0 && b != 0; b = b->next) {
int min_width, max_width, min_height, max_height;
@@ -4202,9 +4218,9 @@ layout_line(struct box *first,
b->type == BOX_BR || b->type == BOX_TEXT ||
b->type == BOX_INLINE_END);
-#ifdef LAYOUT_DEBUG
- LOG("pass 1: b %p, x %i", b, x);
-#endif
+
+ NSLOG(layout, DEBUG, "pass 1: b %p, x %i", b, x);
+
if (b->type == BOX_BR)
break;
@@ -4413,14 +4429,12 @@ layout_line(struct box *first,
space_after = space_before = 0;
/* pass 2: place boxes in line: loop body executed at least once */
-#ifdef LAYOUT_DEBUG
- LOG("x0 %i, x1 %i, x1 - x0 %i", x0, x1, x1 - x0);
-#endif
+
+ NSLOG(layout, DEBUG, "x0 %i, x1 %i, x1 - x0 %i", x0, x1, x1 - x0);
for (x = x_previous = 0, b = first; x <= x1 - x0 && b; b = b->next) {
-#ifdef LAYOUT_DEBUG
- LOG("pass 2: b %p, x %i", b, x);
-#endif
+
+ NSLOG(layout, DEBUG, "pass 2: b %p, x %i", b, x);
if (b->type == BOX_INLINE_BLOCK &&
(css_computed_position(b->style) ==
@@ -4488,9 +4502,7 @@ layout_line(struct box *first,
} else {
/* float */
-#ifdef LAYOUT_DEBUG
- LOG("float %p", b);
-#endif
+ NSLOG(layout, DEBUG, "float %p", b);
d = b->children;
d->float_children = 0;
@@ -4500,9 +4512,11 @@ layout_line(struct box *first,
if (!layout_float(d, *width, content))
return false;
-#ifdef LAYOUT_DEBUG
- LOG("%p : %d %d", d, d->margin[TOP], d->border[TOP].width);
-#endif
+ NSLOG(layout, DEBUG,
+ "%p : %d %d",
+ d,
+ d->margin[TOP],
+ d->border[TOP].width);
d->x = d->margin[LEFT] + d->border[LEFT].width;
d->y = d->margin[TOP] + d->border[TOP].width;
@@ -4633,9 +4647,18 @@ layout_line(struct box *first,
if (split == 0)
w = split_box->width;
-#ifdef LAYOUT_DEBUG
- LOG("splitting: split_box %p \"%.*s\", spilt %zu, w %i, ""left %p, right %p, inline_count %u", split_box, (int)split_box->length, split_box->text, split, w, left, right, inline_count);
-#endif
+
+ NSLOG(layout, DEBUG,
+ "splitting: split_box %p \"%.*s\", spilt %zu, w %i, "
+ "left %p, right %p, inline_count %u",
+ split_box,
+ (int)split_box->length,
+ split_box->text,
+ split,
+ w,
+ left,
+ right,
+ inline_count);
if ((split == 0 || x1 - x0 <= x + space_before + w) &&
!left && !right && inline_count == 1) {
@@ -4653,9 +4676,9 @@ layout_line(struct box *first,
b = split_box->next;
}
x += space_before + w;
-#ifdef LAYOUT_DEBUG
- LOG("forcing");
-#endif
+
+ NSLOG(layout, DEBUG, "forcing");
+
} else if ((split == 0 || x1 - x0 <= x + space_before + w) &&
inline_count == 1) {
/* first word of first box doesn't fit, but a float is
@@ -4663,13 +4686,18 @@ layout_line(struct box *first,
assert(left || right);
used_height = 0;
if (left) {
-#ifdef LAYOUT_DEBUG
- LOG("cy %i, left->y %i, left->height %i", cy, left->y, left->height);
-#endif
+
+ NSLOG(layout, DEBUG,
+ "cy %i, left->y %i, left->height %i",
+ cy,
+ left->y,
+ left->height);
+
used_height = left->y + left->height - cy + 1;
-#ifdef LAYOUT_DEBUG
- LOG("used_height %i", used_height);
-#endif
+
+ NSLOG(layout, DEBUG, "used_height %i",
+ used_height);
+
}
if (right && used_height <
right->y + right->height - cy + 1)
@@ -4679,22 +4707,24 @@ layout_line(struct box *first,
used_height = 0;
b = split_box;
-#ifdef LAYOUT_DEBUG
- LOG("moving below float");
-#endif
+
+ NSLOG(layout, DEBUG, "moving below float");
+
} else if (split == 0 || x1 - x0 <= x + space_before + w) {
/* first word of box doesn't fit so leave box for next
* line */
b = split_box;
-#ifdef LAYOUT_DEBUG
- LOG("leaving for next line");
-#endif
+
+ NSLOG(layout, DEBUG, "leaving for next line");
+
} else {
/* fit as many words as possible */
assert(split != 0);
-#ifdef LAYOUT_DEBUG
- LOG("'%.*s' %i %zu %i", (int)split_box->length, split_box->text, x1 - x0, split, w);
-#endif
+
+ NSLOG(layout, DEBUG, "'%.*s' %i %zu %i",
+ (int)split_box->length, split_box->text,
+ x1 - x0, split, w);
+
if (split != split_box->length) {
if (!layout_text_box_split(content, &fstyle,
split_box, split, w))
@@ -4702,9 +4732,9 @@ layout_line(struct box *first,
b = split_box->next;
}
x += space_before + w;
-#ifdef LAYOUT_DEBUG
- LOG("fitting words");
-#endif
+
+ NSLOG(layout, DEBUG, "fitting words");
+
}
move_y = true;
}
@@ -4842,9 +4872,14 @@ bool layout_inline_container(struct box *inline_container, int width,
assert(inline_container->type == BOX_INLINE_CONTAINER);
-#ifdef LAYOUT_DEBUG
- LOG("inline_container %p, width %i, cont %p, cx %i, cy %i", inline_container, width, cont, cx, cy);
-#endif
+ NSLOG(layout, DEBUG,
+ "inline_container %p, width %i, cont %p, cx %i, cy %i",
+ inline_container,
+ width,
+ cont,
+ cx,
+ cy);
+
has_text_children = false;
for (c = inline_container->children; c; c = c->next) {
@@ -4872,9 +4907,9 @@ bool layout_inline_container(struct box *inline_container, int width,
* curwidth = width and have the multiword lines wrap to the min width)
*/
for (c = inline_container->children; c; ) {
-#ifdef LAYOUT_DEBUG
- LOG("c %p", c);
-#endif
+
+ NSLOG(layout, DEBUG, "c %p", c);
+
curwidth = inline_container->width;
if (!layout_line(c, &curwidth, &y, cx, cy + y, cont, first_line,
has_text_children, content, &next))
diff --git a/render/search.c b/render/search.c
index 4af6706a0..8f21d8758 100644
--- a/render/search.c
+++ b/render/search.c
@@ -538,7 +538,7 @@ static void search_text(const char *string, int string_len,
msg_data.scroll.y0 = bounds.y0;
msg_data.scroll.x1 = bounds.x1;
msg_data.scroll.y1 = bounds.y1;
- content_broadcast(context->c, CONTENT_MSG_SCROLL, msg_data);
+ content_broadcast(context->c, CONTENT_MSG_SCROLL, &msg_data);
}
@@ -571,7 +571,7 @@ void search_step(struct search_context *context, search_flags_t flags,
msg_data.scroll.area = false;
msg_data.scroll.x0 = 0;
msg_data.scroll.y0 = 0;
- content_broadcast(context->c, CONTENT_MSG_SCROLL, msg_data);
+ content_broadcast(context->c, CONTENT_MSG_SCROLL, &msg_data);
return;
}
search_text(string, string_len, context, flags);
diff --git a/render/table.c b/render/table.c
index acf00c70e..c41b9130e 100644
--- a/render/table.c
+++ b/render/table.c
@@ -219,13 +219,14 @@ bool table_calculate_column_types(struct box *table)
#ifdef TABLE_DEBUG
for (i = 0; i != table->columns; i++)
- LOG("table %p, column %u: type %s, width %i", table, i, ((const char *[]){
+ NSLOG(netsurf, INFO,
+ "table %p, column %u: type %s, width %i", table, i, ((const char *[]){
"UNKNOWN",
"FIXED",
"AUTO",
"PERCENT",
- "RELATIVE"
- })[col[i].type], col[i].width);
+ "RELATIVE",
+ })[col[i].type], col[i].width);
#endif
return true;
@@ -740,27 +741,27 @@ bool table_border_is_more_eyecatching(const struct border *a,
/* 3b -- sort by style */
switch (a->style) {
- case CSS_BORDER_STYLE_DOUBLE: impact++;
- case CSS_BORDER_STYLE_SOLID: impact++;
- case CSS_BORDER_STYLE_DASHED: impact++;
- case CSS_BORDER_STYLE_DOTTED: impact++;
- case CSS_BORDER_STYLE_RIDGE: impact++;
- case CSS_BORDER_STYLE_OUTSET: impact++;
- case CSS_BORDER_STYLE_GROOVE: impact++;
- case CSS_BORDER_STYLE_INSET: impact++;
+ case CSS_BORDER_STYLE_DOUBLE: impact++; /* Fall through */
+ case CSS_BORDER_STYLE_SOLID: impact++; /* Fall through */
+ case CSS_BORDER_STYLE_DASHED: impact++; /* Fall through */
+ case CSS_BORDER_STYLE_DOTTED: impact++; /* Fall through */
+ case CSS_BORDER_STYLE_RIDGE: impact++; /* Fall through */
+ case CSS_BORDER_STYLE_OUTSET: impact++; /* Fall through */
+ case CSS_BORDER_STYLE_GROOVE: impact++; /* Fall through */
+ case CSS_BORDER_STYLE_INSET: impact++; /* Fall through */
default:
break;
}
switch (b->style) {
- case CSS_BORDER_STYLE_DOUBLE: impact--;
- case CSS_BORDER_STYLE_SOLID: impact--;
- case CSS_BORDER_STYLE_DASHED: impact--;
- case CSS_BORDER_STYLE_DOTTED: impact--;
- case CSS_BORDER_STYLE_RIDGE: impact--;
- case CSS_BORDER_STYLE_OUTSET: impact--;
- case CSS_BORDER_STYLE_GROOVE: impact--;
- case CSS_BORDER_STYLE_INSET: impact--;
+ case CSS_BORDER_STYLE_DOUBLE: impact--; /* Fall through */
+ case CSS_BORDER_STYLE_SOLID: impact--; /* Fall through */
+ case CSS_BORDER_STYLE_DASHED: impact--; /* Fall through */
+ case CSS_BORDER_STYLE_DOTTED: impact--; /* Fall through */
+ case CSS_BORDER_STYLE_RIDGE: impact--; /* Fall through */
+ case CSS_BORDER_STYLE_OUTSET: impact--; /* Fall through */
+ case CSS_BORDER_STYLE_GROOVE: impact--; /* Fall through */
+ case CSS_BORDER_STYLE_INSET: impact--; /* Fall through */
default:
break;
}
@@ -773,22 +774,22 @@ bool table_border_is_more_eyecatching(const struct border *a,
/* 4a -- sort by origin */
impact = 0;
- switch (a_src) {
- case BOX_TABLE_CELL: impact++;
- case BOX_TABLE_ROW: impact++;
- case BOX_TABLE_ROW_GROUP: impact++;
/** \todo COL/COL_GROUP */
- case BOX_TABLE: impact++;
+ switch (a_src) {
+ case BOX_TABLE_CELL: impact++; /* Fall through */
+ case BOX_TABLE_ROW: impact++; /* Fall through */
+ case BOX_TABLE_ROW_GROUP: impact++; /* Fall through */
+ case BOX_TABLE: impact++; /* Fall through */
default:
break;
}
- switch (b_src) {
- case BOX_TABLE_CELL: impact--;
- case BOX_TABLE_ROW: impact--;
- case BOX_TABLE_ROW_GROUP: impact--;
/** \todo COL/COL_GROUP */
- case BOX_TABLE: impact--;
+ switch (b_src) {
+ case BOX_TABLE_CELL: impact--; /* Fall through */
+ case BOX_TABLE_ROW: impact--; /* Fall through */
+ case BOX_TABLE_ROW_GROUP: impact--; /* Fall through */
+ case BOX_TABLE: impact--; /* Fall through */
default:
break;
}
diff --git a/render/textplain.c b/render/textplain.c
index 5d28d9c54..ab2d55955 100644
--- a/render/textplain.c
+++ b/render/textplain.c
@@ -150,7 +150,6 @@ textplain_create_internal(textplain_content *c, lwc_string *encoding)
char *utf8_data;
parserutils_inputstream *stream;
parserutils_error error;
- union content_msg_data msg_data;
textplain_style.size = (nsoption_int(font_size) * FONT_SIZE_SCALE) / 10;
@@ -185,8 +184,7 @@ textplain_create_internal(textplain_content *c, lwc_string *encoding)
return NSERROR_OK;
no_memory:
- msg_data.error = messages_get("NoMemory");
- content_broadcast(&c->base, CONTENT_MSG_ERROR, msg_data);
+ content_broadcast_errorcode(&c->base, NSERROR_NOMEM);
return NSERROR_NOMEM;
}
@@ -347,7 +345,6 @@ textplain_process_data(struct content *c, const char *data, unsigned int size)
{
textplain_content *text = (textplain_content *) c;
parserutils_inputstream *stream = text->inputstream;
- union content_msg_data msg_data;
parserutils_error error;
error = parserutils_inputstream_append(stream,
@@ -362,8 +359,7 @@ textplain_process_data(struct content *c, const char *data, unsigned int size)
return true;
no_memory:
- msg_data.error = messages_get("NoMemory");
- content_broadcast(c, CONTENT_MSG_ERROR, msg_data);
+ content_broadcast_errorcode(c, NSERROR_NOMEM);
return false;
}
@@ -427,7 +423,7 @@ static void textplain_reformat(struct content *c, int width, int height)
size_t line_start;
nserror res;
- LOG("content %p w:%d h:%d", c, width, height);
+ NSLOG(netsurf, INFO, "content %p w:%d h:%d", c, width, height);
/* compute available columns (assuming monospaced font) - use 8
* characters for better accuracy
@@ -526,7 +522,7 @@ static void textplain_reformat(struct content *c, int width, int height)
return;
no_memory:
- LOG("out of memory (line_count %lu)", line_count);
+ NSLOG(netsurf, INFO, "out of memory (line_count %lu)", line_count);
return;
}
@@ -647,10 +643,10 @@ textplain_mouse_action(struct content *c,
}
msg_data.explicit_status_text = status;
- content_broadcast(c, CONTENT_MSG_STATUS, msg_data);
+ content_broadcast(c, CONTENT_MSG_STATUS, &msg_data);
msg_data.pointer = pointer;
- content_broadcast(c, CONTENT_MSG_POINTER, msg_data);
+ content_broadcast(c, CONTENT_MSG_POINTER, &msg_data);
}
diff --git a/resources/FatMessages b/resources/FatMessages
index 99189dbe5..f9a96c68c 100644
--- a/resources/FatMessages
+++ b/resources/FatMessages
@@ -37,6 +37,7 @@
en.all.NetSurf:NetSurf
en.all.NetSurfCopyright:© 2003-2017 The NetSurf Developers
+de.all.NetSurfCopyright:© 2003-2017 die NetSurf Entwickler
nl.all.NetSurfCopyright:© 2003-2017 De NetSurf-ontwikkelaars
it.all.NetSurfCopyright:© 2003-2017 A cura degli sviluppatori di NetSurf
@@ -50,6 +51,7 @@ it.all.NetSurfCopyright:© 2003-2017 A cura degli sviluppatori di NetSurf
# Iconbar menu
#
en.all.Info:Info
+de.all.Info:Information
fr.all.Info:Information
nl.all.Info:Informatie
en.ro.AppHelpNoShortcut:Help...
@@ -1453,32 +1455,32 @@ fr.all.DateYesterday:Hier
it.all.DateYesterday:Ieri
nl.all.DateYesterday:Gisteren
en.all.Date2Days:Two days ago
-de.all.Date2Days:2 days ago
+de.all.Date2Days:vor 2 Tagen
fr.all.Date2Days:Il y a deux jours
it.all.Date2Days:2 giorni fa
nl.all.Date2Days:2 dagen geleden
en.all.Date3Days:Three days ago
-de.all.Date3Days:3 days ago
+de.all.Date3Days:vor 3 Tagen
fr.all.Date3Days:Il y a trois jours
it.all.Date3Days:3 giorni fa
nl.all.Date3Days:3 dagen geleden
en.all.Date4Days:Four days ago
-de.all.Date4Days:4 days ago
+de.all.Date4Days:vor 4 Tagen
fr.all.Date4Days:Il y a quatre jours
it.all.Date4Days:4 giorni fa
nl.all.Date4Days:4 dagen geleden
en.all.Date5Days:Five days ago
-de.all.Date5Days:5 days ago
+de.all.Date5Days:vor 5 Tagen
fr.all.Date5Days:Il y a cinq jours
it.all.Date5Days:5 giorni fa
nl.all.Date5Days:5 dagen geleden
en.all.Date6Days:Six days ago
-de.all.Date6Days:6 days ago
+de.all.Date6Days:vor 6 Tagen
fr.all.Date6Days:Il y a six jours
it.all.Date6Days:6 giorni fa
nl.all.Date6Days:6 dagen geleden
en.all.Date1Week:A week ago
-de.all.Date1Week:A week ago
+de.all.Date1Week:vor einer Woche
fr.all.Date1Week:Il y a une semaine
it.all.Date1Week:1 settimana fa
nl.all.Date1Week:Een week geleden
@@ -1743,17 +1745,17 @@ fr.gtk.gtkplainSave:Enregistrer sans mise en forme
it.gtk.gtkplainSave:Salva come testo
nl.gtk.gtkplainSave:Als tekst bewaren
en.gtk.gtkcompleteSave:Save webpage complete - select an empty directory
-de.gtk.gtkcompleteSave:Save webpage complete - select an empty directory
+de.gtk.gtkcompleteSave:Seite komplett speichern - ein leeres Verzeichnis wählen
fr.gtk.gtkcompleteSave:Enregistrer page web complète - sélectioner un dossier vide
it.gtk.gtkcompleteSave:Salva l'intera pagina web - seleziona una directory vuota
nl.gtk.gtkcompleteSave:Complete webpagina bewaren - selecteer een lege map
en.gtk.gtkSaveConfirm:File saved
-de.gtk.gtkSaveConfirm:File saved
+de.gtk.gtkSaveConfirm:Datei gespeichert
fr.gtk.gtkSaveConfirm:Fichier enregistré
it.gtk.gtkSaveConfirm:File salvato
nl.gtk.gtkSaveConfirm:Bestand bewaard
en.gtk.gtkSaveCancelled:File not saved
-de.gtk.gtkSaveCancelled:File not saved
+de.gtk.gtkSaveCancelled:Datei nicht gespeichert
fr.gtk.gtkSaveCancelled:Fichier pas enregistré
it.gtk.gtkSaveCancelled:File non salvato
nl.gtk.gtkSaveCancelled:Bestand is niet bewaard
@@ -2040,7 +2042,7 @@ fr.gtk.gtkFullScreenAccel:F11
it.gtk.gtkFullScreenAccel:F11
nl.gtk.gtkFullScreenAccel:F11
en.gtk.gtkPageSource:Page S_ource
-de.gtk.gtkPageSource: Q_uelltext Anzeigen
+de.gtk.gtkPageSource: Q_uelltext anzeigen
fr.gtk.gtkPageSource:Code s_ource de la page
it.gtk.gtkPageSource:Mostra s_orgente
nl.gtk.gtkPageSource:Pagina_bron
@@ -2196,7 +2198,7 @@ fr.gtk.gtkShowBookMarksAccel:F6
it.gtk.gtkShowBookMarksAccel:F6
nl.gtk.gtkShowBookMarksAccel:F6
en.gtk.gtkShowCookies:Show _Cookies…
-de.gtk.gtkShowCookies:Show _Cookies..
+de.gtk.gtkShowCookies:Zeige _Cookies…
fr.gtk.gtkShowCookies:Afficher _cookies...
it.gtk.gtkShowCookies:Mostra _cookie...
nl.gtk.gtkShowCookies:_Cookies beheren...
@@ -2227,7 +2229,7 @@ fr.gtk.gtkNextTabAccel:<ctrl>Droit
it.gtk.gtkNextTabAccel:<ctrl>Destra
nl.gtk.gtkNextTabAccel:<ctrl>Rechterpijltoets
en.gtk.gtkPrevTab:_Previous tab
-de.gtk.gtkPrevTab:_Vorheriger tab
+de.gtk.gtkPrevTab:_Vorheriger Tab
fr.gtk.gtkPrevTab:Onglet _précédent
it.gtk.gtkPrevTab:Scheda _precedente
nl.gtk.gtkPrevTab:Vo_rige tabblad
@@ -2270,7 +2272,7 @@ nl.gtk.gtkAbout:_Programma-informatie...
en.gtk.gtkCustomize:Customise…
-de.gtk.gtkCustomize:Customise..
+de.gtk.gtkCustomize:Anpassen…
fr.gtk.gtkCustomize:Personnaliser...
it.gtk.gtkCustomize:Personalizza...
nl.gtk.gtkCustomize:Aanpassen...
@@ -2290,12 +2292,12 @@ fr.gtk.gtkSavelink:Enregistrer li_en
it.gtk.gtkSavelink:Salva Lin_k
nl.gtk.gtkSavelink:_Koppeling opslaan als...
en.gtk.gtkBookmarklink:Bookmark _Link
-de.gtk.gtkBookmarklink:Bookmark _Link
+de.gtk.gtkBookmarklink:_Link als Bookmark
fr.gtk.gtkBookmarklink:Marquer _Lien
it.gtk.gtkBookmarklink:A_ggiungi ai segnalibri
nl.gtk.gtkBookmarklink:B_ladwijzer voor de koppeling maken
en.gtk.gtkCopylink:Copy link loc_ation
-de.gtk.gtkCopylink:Copy link loc_ation
+de.gtk.gtkCopylink:Link_adresse kopieren
fr.gtk.gtkCopylink:_Copier le lien
it.gtk.gtkCopylink:Copia in_dirizzo link
nl.gtk.gtkCopylink:Koppelingsloc_atie kopiëren
@@ -2336,376 +2338,496 @@ nl.gtk.gtkThemeAdd:Thema is succesvol toegevoegd
# GTK preferences dialog
en.gtk.preferencesTitle:Netsurf Preferences
+de.gtk.preferencesTitle:Netsurf Einstellungen
fr.gtk.preferencesTitle:Préférences de Netsurf
nl.gtk.preferencesTitle:Netsurf-voorkeuren
# Main tab
en.gtk.preferencesMainTabtitle:Main
+de.gtk.preferencesMainTabtitle:Allgemein
fr.gtk.preferencesMainTabtitle:Accueil/Principal
nl.gtk.preferencesMainTabtitle:Algemeen
en.gtk.preferencesStartup:<b>Startup</b>
+de.gtk.preferencesStartup:<b>Starten</b>
fr.gtk.preferencesStartup:<b>Démarrage</b>
nl.gtk.preferencesStartup:<b>Opstarten</b>
en.gtk.preferencesStartupPage:Page:
+de.gtk.preferencesStartupPage:Seite:
fr.gtk.preferencesStartupPage:Page:
nl.gtk.preferencesStartupPage:Pagina:
en.gtk.preferencesStartupPageTooltip:The default startup page
+de.gtk.preferencesStartupPageTooltip:Die Standard Startseite
fr.gtk.preferencesStartupPageTooltip:La page de démarrage par défaut
nl.gtk.preferencesStartupPageTooltip:De standaard startpagina
en.gtk.preferencesStartupPageDefault:Use Default Page
+de.gtk.preferencesStartupPageDefault:Standard Seite nutzen
fr.gtk.preferencesStartupPageDefault:Utiliser la page par défaut
nl.gtk.preferencesStartupPageDefault:Standaard herstellen
en.gtk.preferencesStartupPageCurrent:Use Current Page
+de.gtk.preferencesStartupPageCurrent:aktuelle Seite nehmen
fr.gtk.preferencesStartupPageCurrent:Utiliser la page en cours
nl.gtk.preferencesStartupPageCurrent:Huidige pagina gebruiken
en.gtk.preferencesSearch:<b>Search</b>
+de.gtk.preferencesSearch:<b>Suchen</b>
fr.gtk.preferencesSearch:<b>Recherche</b>
nl.gtk.preferencesSearch:<b>Zoeken</b>
en.gtk.preferencesSearchURLBar:Search from URL bar
+de.gtk.preferencesSearchURLBar:Adressleiste zum Suchen
fr.gtk.preferencesSearchURLBar:Recherche depuis la barre d'URL
nl.gtk.preferencesSearchURLBar:Standaardzoekmachine
en.gtk.preferencesSearchProvider:Provider:
+de.gtk.preferencesSearchProvider:Anbieter:
fr.gtk.preferencesSearchProvider:Fournisseur :
nl.gtk.preferencesSearchProvider:Zoeken met:
en.gtk.preferencesSearchProviderTooltip:The default web search provider
+de.gtk.preferencesSearchProviderTooltip:Voreingestellter Suchanbieter
fr.gtk.preferencesSearchProviderTooltip:Le fournisseur de recherche sur le web par défaut
nl.gtk.preferencesSearchProviderTooltip:Kies de standaardzoekmachine. NetSurf gebruikt deze in de zoekbalk.
en.gtk.preferencesDownloads:<b>Downloads</b>
+de.gtk.preferencesDownloads:<b>Downloads</b>
fr.gtk.preferencesDownloads:<b>Téléchargements</b>
nl.gtk.preferencesDownloads:<b>Downloads</b>
en.gtk.preferencesDownloadsRemove:Remove download from list when complete
+de.gtk.preferencesDownloadsRemove:abgeschlossene Downloads auslisten
fr.gtk.preferencesDownloadsRemove:Retirer le téléchargement de la liste une fois terminé
nl.gtk.preferencesDownloadsRemove:Downloadvermeldingen verwijderen
en.gtk.preferencesDownloadsConfirm:Confirm before overwriting files
+de.gtk.preferencesDownloadsConfirm:Überschreiben bestätigen
fr.gtk.preferencesDownloadsConfirm:Confirmer avant d'écraser des fichiers
nl.gtk.preferencesDownloadsConfirm:Overschrijven van bestand bevestigen
en.gtk.preferencesDownloadsLocation:Location:
+de.gtk.preferencesDownloadsLocation:Zielort:
fr.gtk.preferencesDownloadsLocation:Emplacement :
nl.gtk.preferencesDownloadsLocation:Bestanden opslaan in:
en.gtk.preferencesDownloadsLocationTooltip:The default location downloaded files are put
+de.gtk.preferencesDownloadsLocationTooltip:Speicherort für Downloads
fr.gtk.preferencesDownloadsLocationTooltip:L'emplacement par défaut des fichiers téléchargés sont mis
nl.gtk.preferencesDownloadsLocationTooltip:De standaardplaats waar gedownloade bestanden worden opgeslagen
# Appearance tab
en.gtk.preferencesAppearanceTabtitle:Appearance
+de.gtk.preferencesAppearanceTabtitle:Aussehen
fr.gtk.preferencesAppearanceTabtitle:Apparence
nl.gtk.preferencesAppearanceTabtitle:Vormgeving
en.gtk.preferencesThemes:<b>Themes</b>
+de.gtk.preferencesThemes:<b>Themen</b>
fr.gtk.preferencesThemes:<b>Thèmes</b>
nl.gtk.preferencesThemes:<b>Thema's</b>
en.gtk.preferencesThemesAdd:Add Theme...
+de.gtk.preferencesThemesAdd:Thema hinzu...
fr.gtk.preferencesThemesAdd:Ajouter thème...
nl.gtk.preferencesThemesAdd:Thema toevoegen...
en.gtk.preferencesTabs:<b>Tabs</b>
+de.gtk.preferencesTabs:<b>Tabs</b>
fr.gtk.preferencesTabs:<b>Onglets</b>
nl.gtk.preferencesTabs:<b>Tabbladen</b>
en.gtk.preferencesTabsAlways:Always show tab bar
+de.gtk.preferencesTabsAlways:Tableiste immer anzeigen
fr.gtk.preferencesTabsAlways:Toujours afficher la barre d'onglet
nl.gtk.preferencesTabsAlways:De tabbladenwerkbalk verbergen wanneer slechts één tabblad is geopend
en.gtk.preferencesTabsSwitch:Switch to newly opened tabs immediately
+de.gtk.preferencesTabsSwitch:neue Tabs sofort in Vordergrund
fr.gtk.preferencesTabsSwitch:Passer à l'onglet nouvellement ouvert immédiatement
nl.gtk.preferencesTabsSwitch:Naar vanuit koppeling geopende nieuwe tabbladen schakelen
en.gtk.preferencesTabsNewly:Newly opened tabs are blank
+de.gtk.preferencesTabsNewly:neue Tabs als leere Seite
fr.gtk.preferencesTabsNewly:Onglet récemment ouvert est vièrge
nl.gtk.preferencesTabsNewly:Geopende nieuwe tabbladen zijn leeg inplaats van de startpagina
en.gtk.preferencesTabsPosition:Position:
+de.gtk.preferencesTabsPosition:Position:
fr.gtk.preferencesTabsPosition:Position :
nl.gtk.preferencesTabsPosition:Positie in venster:
en.gtk.preferencesTools:<b>Tools</b>
+de.gtk.preferencesTools:<b>Tools</b>
fr.gtk.preferencesTools:<b>Outils</b>
nl.gtk.preferencesTools:<b>Ontwikkelaarshulpmiddelen</b>
en.gtk.preferencesDeveloperView:Open developer views in a
+de.gtk.preferencesDeveloperView:Entwickleransicht öffnen in
fr.gtk.preferencesDeveloperView:Vues de développement s'ouvrent dans
nl.gtk.preferencesDeveloperView:Informatie voor ontwikkelaars openen in
en.gtk.preferencesDeveloperViewWindow:Window
+de.gtk.preferencesDeveloperViewWindow:Fenster
fr.gtk.preferencesDeveloperViewWindow:un fenêtre
nl.gtk.preferencesDeveloperViewWindow:Venster
en.gtk.preferencesDeveloperViewTab:Tab
+de.gtk.preferencesDeveloperViewTab:Tab
fr.gtk.preferencesDeveloperViewTab:un onglet
nl.gtk.preferencesDeveloperViewTab:Tabblad
en.gtk.preferencesDeveloperViewEditor:Editor
+de.gtk.preferencesDeveloperViewEditor:Editor
fr.gtk.preferencesDeveloperViewEditor:Éditeur
nl.gtk.preferencesDeveloperViewEditor:Tekst-editor
en.gtk.preferencesURLbar:<b>URLbar</b>
+de.gtk.preferencesURLbar:<b>Adressleiste</b>
fr.gtk.preferencesURLbar:<b>Barre URL</b>
nl.gtk.preferencesURLbar:<b>Locatiebalk</b>
en.gtk.preferencesURLbarDisplay:Display recently visited URLs as you type
+de.gtk.preferencesURLbarDisplay:benutzte URLs während Eingabe zeigen
fr.gtk.preferencesURLbarDisplay:Afficher les URL visités récemment lorsque vous tapez
nl.gtk.preferencesURLbarDisplay:Automatisch aanvullen vanuit de browsergeschiedenis tijdens het typen
en.gtk.preferencesToolbar:<b>Toolbar</b>
+de.gtk.preferencesToolbar:<b>Knopfleiste</b>
fr.gtk.preferencesToolbar:<b>Barre d'outils</b>
nl.gtk.preferencesToolbar:<b>Werkbalk</b>
en.gtk.preferencesToolbarButtons:Buttons:
+de.gtk.preferencesToolbarButtons:Gestalt:
fr.gtk.preferencesToolbarButtons:Boutons :
nl.gtk.preferencesToolbarButtons:Knoppen:
# Theme list
en.gtk.preferencesThemeTypeDefault:Default
+de.gtk.preferencesThemeTypeDefault:Standard
fr.gtk.preferencesThemeTypeDefault:Défaut
nl.gtk.preferencesThemeTypeDefault:Standaard
# Tab position list
en.gtk.preferencesTabLocTop:Top
+de.gtk.preferencesTabLocTop:Oben
fr.gtk.preferencesTabLocTop:Haut
nl.gtk.preferencesTabLocTop:Bovenaan
en.gtk.preferencesTabLocLeft:Left
+de.gtk.preferencesTabLocLeft:Links
fr.gtk.preferencesTabLocLeft:Gauche
nl.gtk.preferencesTabLocLeft:Links
en.gtk.preferencesTabLocBottom:Bottom
+de.gtk.preferencesTabLocBottom:Unten
fr.gtk.preferencesTabLocBottom:Bas
nl.gtk.preferencesTabLocBottom:Onderaan
en.gtk.preferencesTabLocRight:Right
+de.gtk.preferencesTabLocRight:Rechts
fr.gtk.preferencesTabLocRight:Droite
nl.gtk.preferencesTabLocRight:Rechts
# button list
en.gtk.preferencesButtonTypeSmall:Small Icons
+de.gtk.preferencesButtonTypeSmall:Kleine Icons
fr.gtk.preferencesButtonTypeSmall:Petites icônes
nl.gtk.preferencesButtonTypeSmall:Kleine pictogrammen
en.gtk.preferencesButtonTypeLarge:Large Icons
+de.gtk.preferencesButtonTypeLarge:Große Icons
fr.gtk.preferencesButtonTypeLarge:Grandes icônes
nl.gtk.preferencesButtonTypeLarge:Grote pictogrammen
en.gtk.preferencesButtonTypeLargeText:Large Icons and Text
+de.gtk.preferencesButtonTypeLargeText:Große Icons mit Text
fr.gtk.preferencesButtonTypeLargeText:Grandes icônes et texte
nl.gtk.preferencesButtonTypeLargeText:Grote pictogrammen en tekst
en.gtk.preferencesButtonTypeText:Text only
+de.gtk.preferencesButtonTypeText:Text ohne Icons
fr.gtk.preferencesButtonTypeText:Texte uniquement
nl.gtk.preferencesButtonTypeText:Alleen tekst
# content tab
en.gtk.preferencesContentTabtitle:Content
+de.gtk.preferencesContentTabtitle:Inhalte
fr.gtk.preferencesContentTabtitle:Contenu
nl.gtk.preferencesContentTabtitle:Inhoud
en.gtk.preferencesControl:<b>Control</b>
+de.gtk.preferencesControl:<b>Steuerung</b>
fr.gtk.preferencesControl:<b>Contrôle</b>
nl.gtk.preferencesControl:<b>Opties</b>
en.gtk.preferencesControlPrevent:Prevent pop-up windows
+de.gtk.preferencesControlPrevent:Pop-Up Fenster blocken
fr.gtk.preferencesControlPrevent:Empêcher fenêtres pop-up
nl.gtk.preferencesControlPrevent:Pop-upvensters blokkeren
en.gtk.preferencesControlHide:Hide Adverts
+de.gtk.preferencesControlHide:Werbung unterdrücken
fr.gtk.preferencesControlHide:Cacher les publicités
nl.gtk.preferencesControlHide:Advertenties verbergen
en.gtk.preferencesControlEnable:Enable JavaScript
+de.gtk.preferencesControlEnable:JavaScript einschalten
fr.gtk.preferencesControlEnable:Activer JavaScript
nl.gtk.preferencesControlEnable:JavaScript inschakelen
en.gtk.preferencesControlDisable:Disable plug-ins
+de.gtk.preferencesControlDisable:Plug-Ins abschalten
fr.gtk.preferencesControlDisable:Désactiver modules externes
nl.gtk.preferencesControlDisable:Plug-ins uitschakelen
en.gtk.preferencesControlHigh:High quality image scaling
+de.gtk.preferencesControlHigh:Bildskalierung hoher Qualität
fr.gtk.preferencesControlHigh:Haute qualité d'image redimensionnée
nl.gtk.preferencesControlHigh:Schalen op hoge beeldkwaliteit
en.gtk.preferencesControlLoad:Load and display
+de.gtk.preferencesControlLoad:laden und anzeigen
fr.gtk.preferencesControlLoad:Charger et visualiser
nl.gtk.preferencesControlLoad:Laad en toon
en.gtk.preferencesAnimation:<b>Animation</b>
+de.gtk.preferencesAnimation:<b>Animation</b>
fr.gtk.preferencesAnimation:<b>Animation</b>
nl.gtk.preferencesAnimation:<b>Animaties</b>
en.gtk.preferencesAnimationEnable:Enable
+de.gtk.preferencesAnimationEnable:zulassen
fr.gtk.preferencesAnimationEnable:Activer
nl.gtk.preferencesAnimationEnable:Ingeschakeld
en.gtk.preferencesAnimationMinimum:Minimum time between frames:
+de.gtk.preferencesAnimationMinimum:minimale Zeit zwischen Frames:
fr.gtk.preferencesAnimationMinimum:Temps minimal entre cadres/frames/images/photo :
nl.gtk.preferencesAnimationMinimum:Minimum tijd tussen opeenvolgende animatiebeelden:
en.gtk.preferencesAnimationMinimumTooltip:Do not update animations any more often than this.
+de.gtk.preferencesAnimationMinimumTooltip:Animation nicht öfter als so aktualisieren
fr.gtk.preferencesAnimationMinimumTooltip:Ne pas mettre à jour les animations plus souvent que cela.
nl.gtk.preferencesAnimationMinimumTooltip:Animaties niet vaker actualiseren dan dit.
en.gtk.preferencesFonts:<b>Fonts</b>
+de.gtk.preferencesFonts:<b>Fonts</b>
fr.gtk.preferencesFonts:<b>Fontes/Polices</b>
nl.gtk.preferencesFonts:<b>Lettertypen</b>
en.gtk.preferencesFontsDefault:Default
+de.gtk.preferencesFontsDefault:Standard
fr.gtk.preferencesFontsDefault:Défaut
nl.gtk.preferencesFontsDefault:Standaard
en.gtk.preferencesFontsSize:Size
+de.gtk.preferencesFontsSize:Größe
fr.gtk.preferencesFontsSize:Taille
nl.gtk.preferencesFontsSize:Grootte
en.gtk.preferencesFontsSizeTooltip:The base-line font size to use.
+de.gtk.preferencesFontsSizeTooltip:Die Standardgröße für Basisschriften.
fr.gtk.preferencesFontsSizeTooltip:La taille de la fonte/police de base à utiliser.
nl.gtk.preferencesFontsSizeTooltip:Het standaardlettertype te gebruiken voor webpagina's.
en.gtk.preferencesFontsPreview:_Preview
+de.gtk.preferencesFontsPreview:Vorschau
fr.gtk.preferencesFontsPreview:A_perçu
nl.gtk.preferencesFontsPreview:_Voorbeeld
en.gtk.preferencesLanguage:<b>Language</b>
+de.gtk.preferencesLanguage:<b>Sprache</b>
fr.gtk.preferencesLanguage:<b>Langue</b>
nl.gtk.preferencesLanguage:<b>Talen</b>
en.gtk.preferencesLanguagePreferred:Preferred language:
+de.gtk.preferencesLanguagePreferred:bevorzugte Sprache:
fr.gtk.preferencesLanguagePreferred:Langue préférée :
nl.gtk.preferencesLanguagePreferred:Voorkeurtaal:
en.gtk.preferencesLanguagePreferredTooltip:The preferred language for web pages
+de.gtk.preferencesLanguagePreferredTooltip:Die gewünschte Sprache für Webseiten
fr.gtk.preferencesLanguagePreferredTooltip:La langue préférée pour les pages Web
nl.gtk.preferencesLanguagePreferredTooltip:De voorkeurtaal voor webpagina's
# Image loading list
en.gtk.preferencesImageLoadBoth:foreground and background images
+de.gtk.preferencesImageLoadBoth:Vorder- und Hintergrundbilder
fr.gtk.preferencesImageLoadBoth:Images d'avant-plan et d'arrière-plan
nl.gtk.preferencesImageLoadBoth:voorgrond- en achtergrondafbeeldingen
en.gtk.preferencesImageLoadFore:foreground images
+de.gtk.preferencesImageLoadFore:Vordergrundbilder
fr.gtk.preferencesImageLoadFore:Images d'avant-plan
nl.gtk.preferencesImageLoadFore:voorgrondafbeeldingen
en.gtk.preferencesImageLoadBack:background images
+de.gtk.preferencesImageLoadBack:Hintergrundbilder
fr.gtk.preferencesImageLoadBack:Images d'arrière-plan
nl.gtk.preferencesImageLoadBack:achtergrondafbeeldingen
en.gtk.preferencesImageLoadNone:no images
+de.gtk.preferencesImageLoadNone:Keine Bidlder
fr.gtk.preferencesImageLoadNone:pas d'images
nl.gtk.preferencesImageLoadNone:geen afbeeldingen
# font type list
en.gtk.preferencesFonttypeSans:Sans-serif
+de.gtk.preferencesFonttypeSans:Sans-serif
fr.gtk.preferencesFonttypeSans:Sans-serif
nl.gtk.preferencesFonttypeSans:Schreefloos
en.gtk.preferencesFonttypeSerif:Serif
+de.gtk.preferencesFonttypeSerif:Serif
fr.gtk.preferencesFonttypeSerif:Serif
nl.gtk.preferencesFonttypeSerif:Met schreef
en.gtk.preferencesFonttypeMonospace:Monospace
+de.gtk.preferencesFonttypeMonospace:Monospace
fr.gtk.preferencesFonttypeMonospace:Monospace
nl.gtk.preferencesFonttypeMonospace:Monospace
en.gtk.preferencesFonttypeCursive:Cursive
+de.gtk.preferencesFonttypeCursive:Kursiv
fr.gtk.preferencesFonttypeCursive:Cursive
nl.gtk.preferencesFonttypeCursive:Cursief
en.gtk.preferencesFonttypeFantasy:Fantasy
+de.gtk.preferencesFonttypeFantasy:Fantasy
fr.gtk.preferencesFonttypeFantasy:Fantasy
nl.gtk.preferencesFonttypeFantasy:Fantasie
en.gtk.preferencesPrivacyTabtitle:Privacy
+de.gtk.preferencesPrivacyTabtitle:Privates
fr.gtk.preferencesPrivacyTabtitle:Confidentialité
nl.gtk.preferencesPrivacyTabtitle:Privacy
en.gtk.preferencesGeneral:<b>General</b>
+de.gtk.preferencesGeneral:<b>Generelles</b>
fr.gtk.preferencesGeneral:<b>Général</b>
nl.gtk.preferencesGeneral:<b>Algemeen</b>
en.gtk.preferencesGeneralReferral:Enable referral submission
+de.gtk.preferencesGeneralReferral:Referenzen erlauben
fr.gtk.preferencesGeneralReferral:Permettre l'envoi du referer en entête
nl.gtk.preferencesGeneralReferral:Referentie versturen inschakelen
en.gtk.preferencesGeneralDNT:Enable sending "Do Not Track" request
+de.gtk.preferencesGeneralDNT:Webseiten sollen nicht nachverfolgen dürfen
fr.gtk.preferencesGeneralDNT:Activer l'envoi d'une requête "Ne pas suivre à la trace"
nl.gtk.preferencesGeneralDNT:Websites laten weten dat gebruiker niet gevolgd wil worden
en.gtk.preferencesHistory:<b>History</b>
+de.gtk.preferencesHistory:<b>History</b>
fr.gtk.preferencesHistory:<b>Historque</b>
nl.gtk.preferencesHistory:<b>Geschiedenis</b>
en.gtk.preferencesHistoryShow:Local history shows URL in tooltip
+de.gtk.preferencesHistoryShow:History (lokal) zeigt die URL in der Hilfe an
fr.gtk.preferencesHistoryShow:Historique local dans une infobulle
nl.gtk.preferencesHistoryShow:Venstergeschiedenis toont webadres in een tipkader
en.gtk.preferencesHistoryRemember:Remember browsing history for up to
+de.gtk.preferencesHistoryRemember:History merken für bis zu
fr.gtk.preferencesHistoryRemember:Conserver l'historique de navigation pendant
nl.gtk.preferencesHistoryRemember:Browsergeschiedenis onthouden voor
en.gtk.preferencesHistoryDays:days
+de.gtk.preferencesHistoryDays:Tage(n)
fr.gtk.preferencesHistoryDays:jours
nl.gtk.preferencesHistoryDays:dag(en)
en.gtk.preferencesCache:<b>Cache</b>
+de.gtk.preferencesCache:<b>Cache</b>
fr.gtk.preferencesCache:<b>Cache</b>
nl.gtk.preferencesCache:<b>Buffer</b>
en.gtk.preferencesCacheMemory:Memory cache size
+de.gtk.preferencesCacheMemory:RAM Cache
fr.gtk.preferencesCacheMemory:Taille du cache mémoire
nl.gtk.preferencesCacheMemory:Grootte geheugenbuffer
en.gtk.preferencesCacheDisc:Disc cache size
+de.gtk.preferencesCacheDisc:Festplatten Cache
fr.gtk.preferencesCacheDisc:Taille du cache disque
nl.gtk.preferencesCacheDisc:Grootte schijfbuffer
en.gtk.preferencesCacheExpire:Expire cache entries after
+de.gtk.preferencesCacheExpire:Einträge verfallen nach
fr.gtk.preferencesCacheExpire:Les entrées du cache expirent après un délai de
nl.gtk.preferencesCacheExpire:Buffergegevens vervallen na
en.gtk.preferencesCacheMaintenance:Maintenance
+de.gtk.preferencesCacheMaintenance:Aufräumen
fr.gtk.preferencesCacheMaintenance:Maintenance
nl.gtk.preferencesCacheMaintenance:Onderhoud
en.gtk.preferencesCacheDays:days
+de.gtk.preferencesCacheDays:Tage(n)
fr.gtk.preferencesCacheDays:jours
nl.gtk.preferencesCacheDays:dag(en)
en.gtk.preferencesNetworkTabtitle:Network
+de.gtk.preferencesNetworkTabtitle:Netzwerk
fr.gtk.preferencesNetworkTabtitle:Réseau
nl.gtk.preferencesNetworkTabtitle:Netwerk
en.gtk.preferencesProxy:<b>HTTP Proxy</b>
+de.gtk.preferencesProxy:<b>HTTP Proxy</b>
fr.gtk.preferencesProxy:<b>Proxy HTTP</b>
nl.gtk.preferencesProxy:<b>HTTP-proxy</b>
en.gtk.preferencesProxyType:Proxy type
+de.gtk.preferencesProxyType:Proxytyp
fr.gtk.preferencesProxyType:Type de Proxy
nl.gtk.preferencesProxyType:Proxy-type
en.gtk.preferencesProxyHost:Host
+de.gtk.preferencesProxyHost:Host
fr.gtk.preferencesProxyHost:Hôte
nl.gtk.preferencesProxyHost:Proxy-server
en.gtk.preferencesProxyUsername:Username
+de.gtk.preferencesProxyUsername:Benutzer
fr.gtk.preferencesProxyUsername:Nom d'utilisateur
nl.gtk.preferencesProxyUsername:Gebruikersnaam
en.gtk.preferencesProxyPassword:Password
+de.gtk.preferencesProxyPassword:Passwort
fr.gtk.preferencesProxyPassword:Mot de passe
nl.gtk.preferencesProxyPassword:Wachtwoord
en.gtk.preferencesProxyNoproxy:No Proxy For
+de.gtk.preferencesProxyNoproxy:Kein Proxy für
fr.gtk.preferencesProxyNoproxy:Pas de proxy pour
nl.gtk.preferencesProxyNoproxy:Geen proxy voor
en.gtk.preferencesProxyTypeTooltip:The type of HTTP proxy server.
+de.gtk.preferencesProxyTypeTooltip:Der Type des HTTP Proxy-Servers.
fr.gtk.preferencesProxyTypeTooltip:Le type de serveur proxy HTTP.
nl.gtk.preferencesProxyTypeTooltip:Het type van de HTTP-proxy-server.
en.gtk.preferencesProxyHostTooltip:Host name of your proxy server.
+de.gtk.preferencesProxyHostTooltip:Hostname des Proxy-Servers.
fr.gtk.preferencesProxyHostTooltip:Nom d'hôte du serveur proxy.
nl.gtk.preferencesProxyHostTooltip:Adres van de proxy-server.
en.gtk.preferencesProxyPortTooltip:Port number to connect to on proxy server.
+de.gtk.preferencesProxyPortTooltip:Portnummer für die Verbindung zum Proxy.
fr.gtk.preferencesProxyPortTooltip:Le numéro de port pour se connecter au serveur proxy.
nl.gtk.preferencesProxyPortTooltip:Poortnummer om te verbinden met de proxy-server.
en.gtk.preferencesProxyUsernameTooltip:Username to access the proxy.
+de.gtk.preferencesProxyUsernameTooltip:Username für die Verbindung zum Proxy.
fr.gtk.preferencesProxyUsernameTooltip:Nom d'utilisateur pour accéder au proxy.
nl.gtk.preferencesProxyUsernameTooltip:Gebruikersnaam voor toegang tot de proxy.
en.gtk.preferencesProxyNoproxyTooltip:Comma separated list of host names that should not be proxied.
+de.gtk.preferencesProxyNoproxyTooltip:Liste von Hosts, die kein Proxy sein sollen. Komma trennt Einträge.
fr.gtk.preferencesProxyNoproxyTooltip:Liste des noms d'hôtes séparés par des virgules qui ne devraient pas être traitées par le proxy.
nl.gtk.preferencesProxyNoproxyTooltip:Lijst van ip-adressen of servernamen die niet via de proxy mogen lopen, gescheiden door komma's.
en.gtk.preferencesFetching:<b>Fetching</b>
+de.gtk.preferencesFetching:<b>Daten holen (Fetch)</b>
fr.gtk.preferencesFetching:<b>Connexions</b>
nl.gtk.preferencesFetching:<b>Verbindingen</b>
en.gtk.preferencesFetchingMax:Maximum fetchers
+de.gtk.preferencesFetchingMax:Verbindungen maximal
fr.gtk.preferencesFetchingMax:Nombre maximum de connexions
nl.gtk.preferencesFetchingMax:Maximum aantal
en.gtk.preferencesFetchingPerhost:Fetches per host
+de.gtk.preferencesFetchingPerhost:Verbindungen pro Host
fr.gtk.preferencesFetchingPerhost:Nombre de connexions par hôte
nl.gtk.preferencesFetchingPerhost:Aantal verbindingen per server
en.gtk.preferencesFetchingCached:Cached connections
+de.gtk.preferencesFetchingCached:gepufferte Verbindungen
fr.gtk.preferencesFetchingCached:Connexions en cache
nl.gtk.preferencesFetchingCached:Gebufferde verbindingen
en.gtk.preferencesFetchingMaxTooltip:Maximum number of concurrent items to fetch at once.
+de.gtk.preferencesFetchingMaxTooltip:Maximale Anzahl paralleler Verbindungen.
fr.gtk.preferencesFetchingMaxTooltip:Nombre maximum d'éléments simultanés à récupérer
nl.gtk.preferencesFetchingMaxTooltip:Maximum aantal verbindingen die simultaan items ophalen.
en.gtk.preferencesFetchingPerhostTooltip:Maximum number of item fetches per web server.
+de.gtk.preferencesFetchingPerhostTooltip:Maximale Zahl je Webserver.
fr.gtk.preferencesFetchingPerhostTooltip:Nombre maximum d'élément à extrair pour chaque serveur Web.
nl.gtk.preferencesFetchingPerhostTooltip:Maximum aantal verbinden per webserver.
en.gtk.preferencesFetchingCachedTooltip:Number of connections to keep in case they are needed again.
+de.gtk.preferencesFetchingCachedTooltip:Zahl offengehaltener Verbindungen für den Fall, daß sie nochmal benötigt werden.
fr.gtk.preferencesFetchingCachedTooltip:Nombre de connexions à maintenir dans le cas où elles seront nécessaires à nouveau.
nl.gtk.preferencesFetchingCachedTooltip:Aantal verbindingen te bufferen voor het geval ze zijn weer nodig.
# Proxy type list
en.gtk.preferencesProxyTypeDirect:Direct connection
+de.gtk.preferencesProxyTypeDirect:Direktverbindung
fr.gtk.preferencesProxyTypeDirect:Connexion directe
nl.gtk.preferencesProxyTypeDirect:Directe verbinding
en.gtk.preferencesProxyTypeManual:Manual with no authentication
+de.gtk.preferencesProxyTypeManual:Manuell ohne Authentifizierung
fr.gtk.preferencesProxyTypeManual:Manuel sans authentification
nl.gtk.preferencesProxyTypeManual:Handmatig zonder authenticatie
en.gtk.preferencesProxyTypeBasic:Manual with basic authentication
+de.gtk.preferencesProxyTypeBasic:Manuell mit einfacher Prüfung
fr.gtk.preferencesProxyTypeBasic:Manuel avec authentification basique
nl.gtk.preferencesProxyTypeBasic:Handmatig met basisauthenticatie
en.gtk.preferencesProxyTypeNLTM:Manual with - authentication
+de.gtk.preferencesProxyTypeNLTM:Manuell mit - Authentifizierung
fr.gtk.preferencesProxyTypeNLTM:Manuel avec l'authentification NTLM
nl.gtk.preferencesProxyTypeNLTM:Handmatig via NTLM-authenticatie
en.gtk.preferencesProxyTypeSystem:System settings
+de.gtk.preferencesProxyTypeSystem:System
fr.gtk.preferencesProxyTypeSystem:Paramètres du système
nl.gtk.preferencesProxyTypeSystem:Systeeminstellingen
en.gtk.preferencesPDFTabtitle:PDF
+de.gtk.preferencesPDFTabtitle:PDF (Dokumente)
fr.gtk.preferencesPDFTabtitle:PDF
nl.gtk.preferencesPDFTabtitle:PDF-uitvoer
en.gtk.preferencesAppearance:<b>Appearance</b>
+de.gtk.preferencesAppearance:<b>Aussehen</b>
fr.gtk.preferencesAppearance:<b>Apparence</b>
nl.gtk.preferencesAppearance:<b>Opmaak</b>
en.gtk.preferencesAppearanceImages:No images in output
+de.gtk.preferencesAppearanceImages:Bilder unterdrücken
fr.gtk.preferencesAppearanceImages:Aucune image de rendu/restituée
nl.gtk.preferencesAppearanceImages:Geen afbeeldingen in uitvoer
en.gtk.preferencesAppearanceBackground:No background images in output
+de.gtk.preferencesAppearanceBackground:keine Hintergrundbilder
fr.gtk.preferencesAppearanceBackground:Aucune image d'arrière-plan de rendu/restituée
nl.gtk.preferencesAppearanceBackground:Geen achtergrondafbeeldingen in uitvoer
en.gtk.preferencesAppearanceScalefit:Scale output to fit page
+de.gtk.preferencesAppearanceScalefit:Ausgabe auf Seitengröße skalieren
fr.gtk.preferencesAppearanceScalefit:Adapter à la page
nl.gtk.preferencesAppearanceScalefit:Uitvoer passend maken aan pagina
en.gtk.preferencesAppearanceScale:Scale output
+de.gtk.preferencesAppearanceScale:Skalierung
fr.gtk.preferencesAppearanceScale:Adapter
nl.gtk.preferencesAppearanceScale:Schaal
en.gtk.preferencesMargins:<b>Margins</b>
+de.gtk.preferencesMargins:<b>Ränder</b>
fr.gtk.preferencesMargins:<b>Marges</b>
nl.gtk.preferencesMargins:<b>Marges</b>
en.gtk.preferencesMarginsMeasurements:measurements in mm
+de.gtk.preferencesMarginsMeasurements:Messen in mm
fr.gtk.preferencesMarginsMeasurements:Mesures en mm
nl.gtk.preferencesMarginsMeasurements:eenheden in millimeters
en.gtk.preferencesGeneration:<b>Generation</b>
+de.gtk.preferencesGeneration:<b>Erstellung</b>
fr.gtk.preferencesGeneration:<b>Generation</b>
nl.gtk.preferencesGeneration:<b>Genereren</b>
en.gtk.preferencesGenerationCompressed:Output is compressed
+de.gtk.preferencesGenerationCompressed:Ausgabe komprimieren
fr.gtk.preferencesGenerationCompressed:La restitution est compressée
nl.gtk.preferencesGenerationCompressed:Uitvoer wordt gecomprimeerd
en.gtk.preferencesGenerationPassword:Output has a password
+de.gtk.preferencesGenerationPassword:Dokument hat Passwort
fr.gtk.preferencesGenerationPassword:La restitution possède un mot de passe
nl.gtk.preferencesGenerationPassword:Uitvoer wordt met wachtwoord beveiligd
@@ -3323,6 +3445,7 @@ it.all.DirectoryError:La directory '%s' è già esistente
nl.all.DirectoryError:map '%s' bestaat reeds
en.ro.SprIsNull:Unable to convert image to sprite
+de.ro.SprIsNull:Bild nicht in Sprite konvertierbar
nl.ro.SprIsNull:Afbeelding kan niet worden omgezet in een sprite.
# Error messages for Amiga version only
@@ -3332,22 +3455,22 @@ fr.ami.CompError:Unable to open
it.ami.CompError:Impossibile aprire
nl.ami.CompError:Niet te openen
en.ami.BMConvErr:NetSurf requires guigfx.library to display images in this mode
-de.ami.BMConvErr:NetSurf requires guigfx.library to display images in this mode
+de.ami.BMConvErr:NetSurf benötigt die guigfx.library für Bilder in diesem Mode
fr.ami.BMConvErr:NetSurf requires guigfx.library to display images in this mode
it.ami.BMConvErr:NetSurf richiede guigfx.library per la visualizzazione delle immagini in questa modalità
nl.ami.BMConvErr:NetSurf requires guigfx.library to display images in this mode
en.ami.MultiTabClose:Are you sure you want to close multiple tabs?
-de.ami.MultiTabClose:Are you sure you want to close multiple tabs?
+de.ami.MultiTabClose:Wirklich mehrere Tabs schließen?
fr.ami.MultiTabClose:Are you sure you want to close multiple tabs?
it.ami.MultiTabClose:Sono rimaste aperte più schede, sei sicuro di voler uscire da NetSurf?
nl.ami.MultiTabClose:Er zijn meerdere tabbladen geopend. Tabbladen allemaal sluiten?
en.ami.TCPIPShutdown:The TCP/IP stack has signalled that it is about to shutdown and NetSurf must exit. NetSurf will quit in 5 seconds unless this shutdown is aborted.
-de.ami.TCPIPShutdown:The TCP/IP stack has signalled that it is about to shutdown and NetSurf must exit. NetSurf will quit in 5 seconds unless this shutdown is aborted.
+de.ami.TCPIPShutdown:Der TCP/IP Stack geht grad' zur Hölle und reißt Netsurf mit sich. In genau 5 Sekunden - es sei denn, der Shutdown wird abgebrochen.
fr.ami.TCPIPShutdown:The TCP/IP stack has signalled that it is about to shutdown and NetSurf must exit. NetSurf will quit in 5 seconds unless this shutdown is aborted.
it.ami.TCPIPShutdown:Lo stack TCP/IP ha dato segnale di essere in procinto di arresto, NetSurf verrà chiuso. NetSurf si chiuderà entro 5 secondi a meno che lo shutdown non venga interrotto.
nl.ami.TCPIPShutdown:De TCP/IP-stack meldt dat deze wordt afgesloten waardoor NetSurf gestopt moet worden. NetSurf zal stoppen in 5 seconden, tenzij het afsluiten wordt afgebroken.
en.ami.AbortShutdown:Abort shutdown
-de.ami.AbortShutdown:Abort shutdown
+de.ami.AbortShutdown:Shutdown abbrechen
fr.ami.AbortShutdown:Abort shutdown
it.ami.AbortShutdown:Interrompi lo shutdown
nl.ami.AbortShutdown:Afsluiten afbreken
@@ -3375,7 +3498,7 @@ fr.all.OverwriteFile:Un fichier portant ce nom existe déjà et serait perdu.
it.all.OverwriteFile:Un file con questo nome è già esistente, continuare comporterà la sovrascrittura del file originale.
nl.all.OverwriteFile:Een bestand met deze naam bestaat al en zal door deze actie overschreven worden.
en.all.RemoveHotlist:Are you sure you wish to remove this address from the hotlist?
-de.all.RemoveHotlist:Are you sure you wish to remove this address from the hotlist?
+de.all.RemoveHotlist:Adresse wirklich aus der Hotlist entfernen?
fr.all.RemoveHotlist:Êtes-vous sûr de vouloir supprimer l'adresse de la liste critique?
it.all.RemoveHotlist:Sei sicuro di voler rimuovere questo indirizzo dai segnalibri?
nl.all.RemoveHotlist:Zeker weten dat dit adres uit de favorietenlijst verwijderd moet worden?
@@ -3415,12 +3538,12 @@ fr.all.Redirecting:Redirection en cours...
it.all.Redirecting:redirezione in corso...
nl.all.Redirecting:doorverwijzen...
en.all.Loading:Loading
-de.all.Loading:Loading
+de.all.Loading:Laden
fr.all.Loading:Chargement
it.all.Loading:Caricamento della pagina...
nl.all.Loading:laden
en.all.Fetching:Fetching data
-de.all.Fetching:Ladevorgänge
+de.all.Fetching:Daten holen
fr.all.Fetching:Récupération des données
it.all.Fetching:Ricezione
nl.all.Fetching:ophalen
@@ -3440,7 +3563,7 @@ fr.all.Done:Terminé
it.all.Done:Completato
nl.all.Done:klaar
en.all.Stopped:Stopped
-de.all.Stopped:Stopped
+de.all.Stopped:Angehalten
fr.all.Stopped:Arrêté
it.all.Stopped:Interrotto
nl.all.Stopped:gestopt
@@ -3483,6 +3606,7 @@ fr.all.ParsingFail:L'analyse syntaxique du document a échoué.
it.all.ParsingFail:Analisi del documento fallita.
nl.all.ParsingFail:fout bij ontleden van dit document.
en.all.CSSGeneric:Error processing CSS
+de.all.CSSGeneric:CSS Auswertung klappt nicht
fr.all.CSSGeneric:Erreur lors du traitement CSS
nl.all.CSSGeneric:fout bij het verwerken van de CSS
it.all.CSSGeneric:Errore nell'elaborazione del CSS
@@ -3927,12 +4051,12 @@ fr.all.DontReplace:Ne pas remplacer le fichier
it.all.DontReplace:Non sostituire
nl.all.DontReplace:Annuleer bewaaractie
en.all.Remove:Remove address
-de.all.Remove:Remove address
+de.all.Remove:Adresse entfernen
fr.all.Remove:Enlever/retirer une adresse
it.all.Remove:Rimuovi indirizzo
nl.all.Remove:Verwijder adres
en.all.DontRemove:Don't remove
-de.all.DontRemove:Don't remove
+de.all.DontRemove:Behalten
fr.all.DontRemove:Ne pas enlever/retirer
it.all.DontRemove:Non rimuovere
nl.all.DontRemove:Niet verwijderen
@@ -3962,7 +4086,7 @@ fr.all.OK:OK
it.all.OK:OK
nl.all.OK:OK
en.ami.More:More
-de.ami.More:More
+de.ami.More:Mehr
fr.ami.More:More
it.ami.More:Di più
nl.ami.More:Meer
@@ -5598,12 +5722,12 @@ fr.ro.HelpInterfaceConfig13:\Ssauver ces réglages et fermer la fenêtre.|M\Asau
it.ro.HelpInterfaceConfig13:\Ssave these settings and close the \w.|M\Asave these settings without closing the \w.
nl.ro.HelpInterfaceConfig13:Klik met KIES om de gemaakte wijzigingen te bewaren en dit venster te sluiten.|MKlikken met PASAAN heeft hetzelfde effect, alleen wordt het huidige venster dan niet gesloten.
en.ro.HelpInterfaceConfig16:This indicates whether NetSurf will use an external hotlist client if available, in preference to the internal hotlist.
-de.ro.HelpInterfaceConfig16:This indicates whether NetSurf will use an external hotlist client if available, in preference to the internal hotlist.
+de.ro.HelpInterfaceConfig16:Erlaubt das Benutzen eines externen Programmes zur Verwaltung der Hotlist.
fr.ro.HelpInterfaceConfig16:This indicates whether NetSurf will use an external hotlist client if available, in preference to the internal hotlist.
it.ro.HelpInterfaceConfig16:This indicates whether NetSurf will use an external hotlist client if available, in preference to the internal hotlist.
nl.ro.HelpInterfaceConfig16:Deze optie geeft aan of de favorietenlijst via een extern programma (indien beschikbaar) beheerd mogen worden.
en.ro.HelpInterfaceConfig18:\Tthe path to a hotlist application which will be used to display the hotlist.
-de.ro.HelpInterfaceConfig18:\Tthe path to a hotlist application which will be used to display the hotlist.
+de.ro.HelpInterfaceConfig18:\Tder Pfad zu einer Anwendung, die die Hotlist verwalten kann.
fr.ro.HelpInterfaceConfig18:\Tthe path to a hotlist application which will be used to display the hotlist.
it.ro.HelpInterfaceConfig18:\Tthe path to a hotlist application which will be used to display the hotlist.
nl.ro.HelpInterfaceConfig18:Voer in dit invoerveld het pad in van een extern programma dat de favorietenlijst mag beheren.
@@ -5614,7 +5738,7 @@ fr.ro.HelpLanguageConfig:\Tfenêtre de configuration de langue.
it.ro.HelpLanguageConfig:\Tconfigurazione della lingua \w
nl.ro.HelpLanguageConfig:Diverse taalinstellingen kunnen in dit venster gewijzigd worden.
en.ro.HelpLanguageConfig3:\Tcurrently selected interface language.|MThe interface language is the language used for NetSurf's messages and dialogue boxes.
-de.ro.HelpLanguageConfig3:Das ist die aktuell eingestellte Sprache für die Bedienoberfläche.|MDiese Sprache wird genutzt, um NetSurf's Meldungen und die Texte der Dialogboxen und Menüs darzustellen.
+de.ro.HelpLanguageConfig3:Das ist die aktuell eingestellte Sprache für die Bedienoberfläche.|MDiese Sprache wird genutzt, um NetSurf's Meldungen, Texte der Dialogboxen, Menüs darzustellen.
fr.ro.HelpLanguageConfig3:\Tla langue d'interface sélectionnée actuellement.|MLa langue d'interface est la langue utilisée pour les messages et les boîtes de dialogue de Netsurf.
it.ro.HelpLanguageConfig3:\Tcurrently selected interface language.|MThe interface language is the language used for NetSurf's messages and dialogue boxes.
nl.ro.HelpLanguageConfig3:Dit is momenteel de geselecteerde gebruikersinterfacetaal.|MDe interfacetaal is de taal voor de melding- en dialoogvensters.
@@ -5741,7 +5865,7 @@ fr.ami.HelpToolbarReload:Reload\nLMB: Reloads the page\nShift+LMB: Reloads the p
it.ami.HelpToolbarReload:Ricarica
nl.ami.HelpToolbarReload:Herlaad\nLMB: Herlaad de pagina\nShift+LMB: Herlaad de pagina inclusief alle objecten
en.ami.HelpToolbarHome:Home\nLMB: Goes to the homepage
-de.ami.HelpToolbarHome:Home\nLMB: Goes to the homepage
+de.ami.HelpToolbarHome:Home\nLMB: Homepage ansteuern
fr.ami.HelpToolbarHome:Home\nLMB: Goes to the homepage
it.ami.HelpToolbarHome:Pagina iniziale
nl.ami.HelpToolbarHome:Startpagina\nLMB: Opent de ingestelde startpagina
@@ -5909,7 +6033,7 @@ fr.all.Scripting:Scripts
it.all.Scripting:Scripting
nl.all.Scripting:Scripts
en.all.EnableJS:Enable JavaScript
-de.all.EnableJS:Enable JavaScript
+de.all.EnableJS:JavaScript benutzen
fr.all.EnableJS:Activer le JavaScript
it.all.EnableJS:Attiva JavaScript
nl.all.EnableJS:JavaScript ingeschakeld
@@ -5929,7 +6053,7 @@ fr.all.SendReferer:Permettre l'envoi du referer en entête
it.all.SendReferer:Invia informazioni sul referral del sito
nl.all.SendReferer:Zend websitereferentie
en.ami.DoNotTrack:Send header to tell websites not to track
-de.ami.DoNotTrack:Send header to tell websites not to track
+de.ami.DoNotTrack:Webseiten das Tracking verbieten - Wunsch
fr.ami.DoNotTrack:Activer l'envoi d'une requête "Ne pas suivre à la trace"
it.ami.DoNotTrack:Invia header al sito per la richiesta di non tracciamento
nl.ami.DoNotTrack:Websites laten weten dat gebruiker niet gevolgd wil worden
@@ -6041,7 +6165,7 @@ fr.all.ScaleQuality:Graduation de qualité supérieur
it.all.ScaleQuality:Massima qualità di visualizzazione
nl.all.ScaleQuality:Hogere schaalkwaliteit
en.ami.DitherQuality:Dither quality
-de.ami.DitherQuality:Dither quality
+de.ami.DitherQuality:Dithern
fr.ami.DitherQuality:Qualité de tramage
it.ami.DitherQuality:Qualità dither
nl.ami.DitherQuality:Kwaliteit kleurbenadering
@@ -6147,7 +6271,7 @@ fr.all.FontFantasy:Fantaisie
it.all.FontFantasy:Fantasia
nl.all.FontFantasy:Fantasie
en.ami.FontFallback:Preferred fallback
-de.ami.FontFallback:Preferred fallback
+de.ami.FontFallback:wenns nicht klappt
fr.ami.FontFallback:Police de caractères de secour préférée
it.ami.FontFallback:Fallback preferito
nl.ami.FontFallback:Favoriete reserve lettertype
@@ -6172,24 +6296,24 @@ fr.all.Pt:pt
it.all.Pt:pt
nl.all.Pt:pt
en.ami.FontAntialiasing:Use anti-aliasing (when possible)
-de.ami.FontAntialiasing:Use anti-aliasing (when possible)
+de.ami.FontAntialiasing:Anti-aliasing nutzen (wenn möglich)
fr.ami.FontAntialiasing:Utiliser l'anticrénelage (si possible)
it.ami.FontAntialiasing:Usa anti-aliasing (quando possibile)
nl.ami.FontAntialiasing:Anti-aliasing (indien mogelijk) gebruiken
en.ami.FontBitmap:Allow bitmap fonts
-de.ami.FontBitmap:Allow bitmap fonts
+de.ami.FontBitmap:Bitmap Fonts zulassen
fr.ami.FontBitmap:Allow bitmap fonts
it.ami.FontBitmap:Permetti font bitmap
nl.ami.FontBitmap:Allow bitmap fonts
# Font scanning
en.ami.FontScanning:Scanning fonts...
-de.ami.FontScanning:Scanning fonts...
+de.ami.FontScanning:Lese Fonts ein...
fr.ami.FontScanning:Balayage de polices de caractères...
it.ami.FontScanning:Scansione dei font in corso...
nl.ami.FontScanning:Scannen lettertypen...
en.ami.FontGlyphs:%ld unique glyphs found
-de.ami.FontGlyphs:%ld unique glyphs found
+de.ami.FontGlyphs:%ld eigenständige Glyphen gefunden
fr.ami.FontGlyphs:%ld glyphe(s) unique(s) trouvé
it.ami.FontGlyphs:%ld glifi unici trovati
nl.ami.FontGlyphs:%ld unieke tekens gevonden
@@ -6243,17 +6367,17 @@ fr.all.TabMiddle:Bouton du milieu de la souris ouvre un onglet
it.all.TabMiddle:Usa tasto centrale del mouse per aprire le schede
nl.all.TabMiddle:Middelste muisknop opent een nieuw tabblad
en.all.TabLast:Open new tabs after all existing tabs
-de.all.TabLast:Open new tabs after all existing tabs
+de.all.TabLast:Neue Tabs hinter letztem öffnen
fr.all.TabLast:Ouvrir de nouveaux onglets après tous les onglets existants
it.all.TabLast:Apri le nuove schede dopo quella corrente
nl.all.TabLast:Open nieuw tabblad na alle bestaande tabbladen
en.ami.TabClose:Warn when closing multiple tabs
-de.ami.TabClose:Warn when closing multiple tabs
+de.ami.TabClose:Warnen beim Schließen vieler Tabs
fr.ami.TabClose:Avertir lors de la fermeture de plusieurs onglets
it.ami.TabClose:Avvisa quando si chiudono più schede
nl.ami.TabClose:Waarschuwen wanneer meerdere tabbladen tegelijkertijd worden gesloten
en.ami.TabAlways:Always show tabs
-de.ami.TabAlways:Always show tabs
+de.ami.TabAlways:Tabs immer zeigen
fr.ami.TabAlways:Toujours afficher les onglets
it.ami.TabAlways:Mostra sempre la barra delle schede
nl.ami.TabAlways:Tabbladen altijd tonen
@@ -6262,6 +6386,7 @@ nl.ami.TabAlways:Tabbladen altijd tonen
#
en.all.Downloads:Downloads
+de.all.Downloads:Downloads
it.all.Downloads:Trasferimenti
nl.all.Downloads:Opgehaalde items
@@ -6344,7 +6469,7 @@ it.all.OptionNoWindow:Non aprire la finestra all'avvio (avvio da AmiDock)
nl.all.OptionNoWindow:Geen venster openen na starten programma
en.all.OptionNoQuit:Do not quit when last window closed
-de.all.OptionNoQuit:Nicht beenden beim Schließen des letzten Fensters
+de.all.OptionNoQuit:Nicht Beenden beim Schließen des letzten Fensters
fr.all.OptionNoQuit:Ne pas quitter lorsque la dernière fenêtre se trouve fermée
it.all.OptionNoQuit:Iconifica su AmiDock alla chiusura di NetSurf
nl.all.OptionNoQuit:Stop programma niet als laatste venster worden gesloten
diff --git a/test/Makefile b/test/Makefile
index 39953a3d3..64c3f39a4 100644
--- a/test/Makefile
+++ b/test/Makefile
@@ -134,7 +134,7 @@ endif
BASE_TESTCFLAGS := -std=c99 -g \
$(COMMON_WARNFLAGS) \
- -D_BSD_SOURCE \
+ -D_DEFAULT_SOURCE \
-D_POSIX_C_SOURCE=200809L \
-D_XOPEN_SOURCE=600 \
-Itest -Iinclude -Icontent/handlers -Ifrontends -I. -I.. \
diff --git a/test/data/Choices-all b/test/data/Choices-all
index b9cab1fb3..9f2e18377 100644
--- a/test/data/Choices-all
+++ b/test/data/Choices-all
@@ -95,6 +95,8 @@ sys_colour_ThreeDShadow:d5d5d5
sys_colour_Window:f1f1f1
sys_colour_WindowFrame:4e4e4e
sys_colour_WindowText:000000
+log_filter:level:WARNING
+verbose_filter:level:VERBOSE
render_resample:1
downloads_clear:0
request_overwrite:1
diff --git a/test/log.c b/test/log.c
index 90b4379e9..fc6b6285c 100644
--- a/test/log.c
+++ b/test/log.c
@@ -42,13 +42,15 @@ void nslog_log(const char *file, const char *func, int ln, const char *format, .
{
va_list ap;
- fprintf(stderr, "%s:%i %s: ", file, ln, func);
+ if (verbose_log) {
+ fprintf(stderr, "%s:%i %s: ", file, ln, func);
- va_start(ap, format);
+ va_start(ap, format);
- vfprintf(stderr, format, ap);
+ vfprintf(stderr, format, ap);
- va_end(ap);
+ va_end(ap);
- fputc('\n', stderr);
+ fputc('\n', stderr);
+ }
}
diff --git a/test/messages.c b/test/messages.c
index d102e361c..ae82d1ede 100644
--- a/test/messages.c
+++ b/test/messages.c
@@ -52,7 +52,6 @@ struct message_test_vec_s message_errorcode_test_vec[] = {
{ NSERROR_SAVE_FAILED, "SaveFailed" },
{ NSERROR_CLONE_FAILED, "CloneFailed" },
{ NSERROR_INIT_FAILED, "InitFailed" },
- { NSERROR_MNG_ERROR, "Error converting MNG/PNG/JNG: %i" },
{ NSERROR_BAD_ENCODING, "BadEncoding" },
{ NSERROR_NEED_DATA, "NeedData" },
{ NSERROR_ENCODING_CHANGE, "EncodingChanged" },
diff --git a/test/nsoption.c b/test/nsoption.c
index 5874c94b6..8f2388a5b 100644
--- a/test/nsoption.c
+++ b/test/nsoption.c
@@ -39,6 +39,9 @@ const char *test_choices_all_path = "test/data/Choices-all";
const char *test_choices_full_path = "test/data/Choices-full";
const char *test_choices_missing_path = "test/data/Choices-missing";
+/* Stubs */
+nserror nslog_set_filter_by_options() { return NSERROR_OK; }
+
/**
* generate test output filenames
*/
diff --git a/test/urldbtest.c b/test/urldbtest.c
index 75a7210b0..1c76de1ee 100644
--- a/test/urldbtest.c
+++ b/test/urldbtest.c
@@ -77,6 +77,9 @@ struct test_urls {
#define NELEMS(x) (sizeof(x) / sizeof((x)[0]))
+/* Stubs */
+nserror nslog_set_filter_by_options() { return NSERROR_OK; }
+
/**
* generate test output filenames
*/
@@ -143,7 +146,7 @@ static nsurl *make_url(const char *url)
{
nsurl *nsurl;
if (nsurl_create(url, &nsurl) != NSERROR_OK) {
- LOG("failed creating nsurl");
+ NSLOG(netsurf, INFO, "failed creating nsurl");
exit(1);
}
return nsurl;
@@ -229,9 +232,8 @@ static void urldb_lwc_iterator(lwc_string *str, void *pw)
{
int *scount = pw;
- LOG("[%3u] %.*s", str->refcnt,
- (int)lwc_string_length(str),
- lwc_string_data(str));
+ NSLOG(netsurf, INFO, "[%3u] %.*s", str->refcnt,
+ (int)lwc_string_length(str), lwc_string_data(str));
(*scount)++;
}
@@ -245,7 +247,7 @@ static void urldb_teardown(void)
corestrings_fini();
- LOG("Remaining lwc strings:");
+ NSLOG(netsurf, INFO, "Remaining lwc strings:");
lwc_iterate_strings(urldb_lwc_iterator, &scount);
ck_assert_int_eq(scount, 0);
}
@@ -712,7 +714,7 @@ static int cb_count;
static bool urldb_iterate_entries_cb(nsurl *url, const struct url_data *data)
{
- LOG("url: %s", nsurl_access(url));
+ NSLOG(netsurf, INFO, "url: %s", nsurl_access(url));
/* fprintf(stderr, "url:%s\ntitle:%s\n\n",nsurl_access(url), data->title); */
cb_count++;
return true;
@@ -867,27 +869,6 @@ START_TEST(urldb_auth_details_test)
END_TEST
-START_TEST(urldb_thumbnail_test)
-{
- nsurl *url;
- struct bitmap *bmap;
- struct bitmap *res;
- bool set;
-
- url = make_url(wikipedia_url);
- bmap = (struct bitmap*)url;
-
- set = urldb_set_thumbnail(url, bmap);
- ck_assert(set == true);
-
- res = urldb_get_thumbnail(url);
- ck_assert(res != NULL);
- ck_assert(res == bmap);
-
- nsurl_unref(url);
-}
-END_TEST
-
START_TEST(urldb_cert_permissions_test)
{
nsurl *url;
@@ -983,7 +964,6 @@ static TCase *urldb_case_create(void)
tcase_add_test(tc, urldb_iterate_partial_numeric_v4_test);
tcase_add_test(tc, urldb_iterate_partial_numeric_v6_test);
tcase_add_test(tc, urldb_auth_details_test);
- tcase_add_test(tc, urldb_thumbnail_test);
tcase_add_test(tc, urldb_cert_permissions_test);
tcase_add_test(tc, urldb_update_visit_test);
tcase_add_test(tc, urldb_reset_visit_test);
@@ -995,7 +975,7 @@ static TCase *urldb_case_create(void)
static bool urldb_iterate_cookies_cb(const struct cookie_data *data)
{
- LOG("%p", data);
+ NSLOG(netsurf, INFO, "%p", data);
/* fprintf(stderr, "domain:%s\npath:%s\nname:%s\n\n",data->domain, data->path, data->name);*/
return true;
}
diff --git a/utils/errors.h b/utils/errors.h
index b9e157c66..9a0a9bc04 100644
--- a/utils/errors.h
+++ b/utils/errors.h
@@ -27,58 +27,37 @@
* Enumeration of error codes
*/
typedef enum {
- NSERROR_OK, /**< No error */
-
- NSERROR_UNKNOWN, /**< Unknown error - DO *NOT* USE */
-
- NSERROR_NOMEM, /**< Memory exhaustion */
-
- NSERROR_NO_FETCH_HANDLER, /**< No fetch handler for URL scheme */
-
- NSERROR_NOT_FOUND, /**< Requested item not found */
-
- NSERROR_NOT_DIRECTORY, /**< Missing directory */
-
- NSERROR_SAVE_FAILED, /**< Failed to save data */
-
- NSERROR_CLONE_FAILED, /**< Failed to clone handle */
-
- NSERROR_INIT_FAILED, /**< Initialisation failed */
-
- NSERROR_MNG_ERROR, /**< An MNG error occurred */
-
- NSERROR_BAD_ENCODING, /**< The character set is unknown */
-
- NSERROR_NEED_DATA, /**< More data needed */
-
- NSERROR_ENCODING_CHANGE, /**< The character changed */
-
- NSERROR_BAD_PARAMETER, /**< Bad Parameter */
-
- NSERROR_INVALID, /**< Invalid data */
-
- NSERROR_BOX_CONVERT, /**< Box conversion failed */
-
- NSERROR_STOPPED, /**< Content conversion stopped */
-
- NSERROR_DOM, /**< DOM call returned error */
-
- NSERROR_CSS, /**< CSS call returned error */
-
+ NSERROR_OK, /**< No error */
+ NSERROR_UNKNOWN, /**< Unknown error - DO *NOT* USE */
+ NSERROR_NOMEM, /**< Memory exhaustion */
+ NSERROR_NO_FETCH_HANDLER, /**< No fetch handler for URL scheme */
+ NSERROR_NOT_FOUND, /**< Requested item not found */
+ NSERROR_NOT_DIRECTORY, /**< Missing directory */
+ NSERROR_SAVE_FAILED, /**< Failed to save data */
+ NSERROR_CLONE_FAILED, /**< Failed to clone handle */
+ NSERROR_INIT_FAILED, /**< Initialisation failed */
+ NSERROR_BMP_ERROR, /**< A BMP error occurred */
+ NSERROR_GIF_ERROR, /**< A GIF error occurred */
+ NSERROR_ICO_ERROR, /**< A ICO error occurred */
+ NSERROR_PNG_ERROR, /**< A PNG error occurred */
+ NSERROR_SPRITE_ERROR, /**< A RISC OS Sprite error occurred */
+ NSERROR_SVG_ERROR, /**< A SVG error occurred */
+ NSERROR_BAD_ENCODING, /**< The character set is unknown */
+ NSERROR_NEED_DATA, /**< More data needed */
+ NSERROR_ENCODING_CHANGE, /**< The character changed */
+ NSERROR_BAD_PARAMETER, /**< Bad Parameter */
+ NSERROR_INVALID, /**< Invalid data */
+ NSERROR_BOX_CONVERT, /**< Box conversion failed */
+ NSERROR_STOPPED, /**< Content conversion stopped */
+ NSERROR_DOM, /**< DOM call returned error */
+ NSERROR_CSS, /**< CSS call returned error */
NSERROR_CSS_BASE, /**< CSS base sheet failed */
-
- NSERROR_BAD_URL, /**< Bad URL */
-
- NSERROR_BAD_CONTENT, /**< Bad Content */
-
+ NSERROR_BAD_URL, /**< Bad URL */
+ NSERROR_BAD_CONTENT, /**< Bad Content */
NSERROR_FRAME_DEPTH, /**< Exceeded frame depth */
-
NSERROR_PERMISSION, /**< Permission error */
-
- NSERROR_NOSPACE, /**< Insufficient space */
-
+ NSERROR_NOSPACE, /**< Insufficient space */
NSERROR_BAD_SIZE, /**< Bad size */
-
NSERROR_NOT_IMPLEMENTED, /**< Functionality is not implemented */
} nserror;
diff --git a/utils/filename.c b/utils/filename.c
index 9c95901a1..01a403fd9 100644
--- a/utils/filename.c
+++ b/utils/filename.c
@@ -84,7 +84,8 @@ const char *filename_request(void)
/* no available slots - create a new directory */
dir = filename_create_directory(NULL);
if (dir == NULL) {
- LOG("Failed to create a new directory.");
+ NSLOG(netsurf, INFO,
+ "Failed to create a new directory.");
return NULL;
}
i = 63;
@@ -182,10 +183,12 @@ bool filename_initialise(void)
for (start = directory; *start != '\0'; start++) {
if (*start == '/') {
*start = '\0';
- LOG("Creating \"%s\"", directory);
+ NSLOG(netsurf, INFO, "Creating \"%s\"", directory);
ret = nsmkdir(directory, S_IRWXU);
if (ret != 0 && errno != EEXIST) {
- LOG("Failed to create directory \"%s\"", directory);
+ NSLOG(netsurf, INFO,
+ "Failed to create directory \"%s\"",
+ directory);
free(directory);
return false;
}
@@ -194,7 +197,7 @@ bool filename_initialise(void)
}
}
- LOG("Temporary directory location: %s", directory);
+ NSLOG(netsurf, INFO, "Temporary directory location: %s", directory);
ret = nsmkdir(directory, S_IRWXU);
free(directory);
@@ -280,7 +283,8 @@ bool filename_flush_directory(const char *folder, int depth)
child[sizeof(child) - 1] = '\0';
if (stat(child, &statbuf) == -1) {
- LOG("Unable to stat %s: %s", child, strerror(errno));
+ NSLOG(netsurf, INFO, "Unable to stat %s: %s", child,
+ strerror(errno));
continue;
}
@@ -348,7 +352,8 @@ bool filename_flush_directory(const char *folder, int depth)
filename_delete_recursive(child);
if (remove(child))
- LOG("Failed to remove '%s'", child);
+ NSLOG(netsurf, INFO, "Failed to remove '%s'",
+ child);
else
changed = true;
} else {
@@ -387,7 +392,8 @@ bool filename_delete_recursive(char *folder)
child[sizeof(child) - 1] = '\0';
if (stat(child, &statbuf) == -1) {
- LOG("Unable to stat %s: %s", child, strerror(errno));
+ NSLOG(netsurf, INFO, "Unable to stat %s: %s", child,
+ strerror(errno));
continue;
}
@@ -399,7 +405,7 @@ bool filename_delete_recursive(char *folder)
}
if (remove(child)) {
- LOG("Failed to remove '%s'", child);
+ NSLOG(netsurf, INFO, "Failed to remove '%s'", child);
closedir(parent);
return false;
}
@@ -465,7 +471,7 @@ static struct directory *filename_create_directory(const char *prefix)
/* allocate a new directory */
new_dir = malloc(sizeof(struct directory));
if (new_dir == NULL) {
- LOG("No memory for malloc()");
+ NSLOG(netsurf, INFO, "No memory for malloc()");
return NULL;
}
@@ -499,7 +505,9 @@ static struct directory *filename_create_directory(const char *prefix)
* whilst we are running if there is an error, so we
* don't report this yet and try to create the
* structure normally. */
- LOG("Failed to create optimised structure '%s'", filename_directory);
+ NSLOG(netsurf, INFO,
+ "Failed to create optimised structure '%s'",
+ filename_directory);
}
}
@@ -519,7 +527,9 @@ static struct directory *filename_create_directory(const char *prefix)
if (!is_dir(filename_directory)) {
if (nsmkdir(filename_directory, S_IRWXU)) {
- LOG("Failed to create directory '%s'", filename_directory);
+ NSLOG(netsurf, INFO,
+ "Failed to create directory '%s'",
+ filename_directory);
return NULL;
}
}
diff --git a/utils/hashtable.c b/utils/hashtable.c
index af100dfc9..3a1711da0 100644
--- a/utils/hashtable.c
+++ b/utils/hashtable.c
@@ -81,7 +81,7 @@ struct hash_table *hash_create(unsigned int chains)
struct hash_table *r = malloc(sizeof(struct hash_table));
if (r == NULL) {
- LOG("Not enough memory for hash table.");
+ NSLOG(netsurf, INFO, "Not enough memory for hash table.");
return NULL;
}
@@ -89,7 +89,8 @@ struct hash_table *hash_create(unsigned int chains)
r->chain = calloc(chains, sizeof(struct hash_entry *));
if (r->chain == NULL) {
- LOG("Not enough memory for %d hash table chains.", chains);
+ NSLOG(netsurf, INFO,
+ "Not enough memory for %d hash table chains.", chains);
free(r);
return NULL;
}
@@ -134,7 +135,7 @@ bool hash_add(struct hash_table *ht, const char *key, const char *value)
e = malloc(sizeof(struct hash_entry));
if (e == NULL) {
- LOG("Not enough memory for hash entry.");
+ NSLOG(netsurf, INFO, "Not enough memory for hash entry.");
return false;
}
@@ -144,7 +145,8 @@ bool hash_add(struct hash_table *ht, const char *key, const char *value)
v = strlen(value) ;
e->pairing = malloc(v + e->key_length + 2);
if (e->pairing == NULL) {
- LOG("Not enough memory for string duplication.");
+ NSLOG(netsurf, INFO,
+ "Not enough memory for string duplication.");
free(e);
return false;
}
diff --git a/utils/idna.c b/utils/idna.c
index 34cc40f83..572882ecb 100644
--- a/utils/idna.c
+++ b/utils/idna.c
@@ -63,17 +63,17 @@ static nserror punycode_status_to_nserror(enum punycode_status status)
break;
case punycode_bad_input:
- LOG("Bad input");
+ NSLOG(netsurf, INFO, "Bad input");
ret = NSERROR_BAD_ENCODING;
break;
case punycode_big_output:
- LOG("Output too big");
+ NSLOG(netsurf, INFO, "Output too big");
ret = NSERROR_BAD_SIZE;
break;
case punycode_overflow:
- LOG("Overflow");
+ NSLOG(netsurf, INFO, "Overflow");
ret = NSERROR_NOSPACE;
break;
@@ -437,7 +437,8 @@ static bool idna__is_valid(int32_t *label, size_t len)
/* 2. Check characters 3 and 4 are not '--'. */
if ((label[2] == 0x002d) && (label[3] == 0x002d)) {
- LOG("Check failed: characters 2 and 3 are '--'");
+ NSLOG(netsurf, INFO,
+ "Check failed: characters 2 and 3 are '--'");
return false;
}
@@ -447,7 +448,8 @@ static bool idna__is_valid(int32_t *label, size_t len)
if ((unicode_props->category == UTF8PROC_CATEGORY_MN) ||
(unicode_props->category == UTF8PROC_CATEGORY_MC) ||
(unicode_props->category == UTF8PROC_CATEGORY_ME)) {
- LOG("Check failed: character 0 is a combining mark");
+ NSLOG(netsurf, INFO,
+ "Check failed: character 0 is a combining mark");
return false;
}
@@ -456,14 +458,20 @@ static bool idna__is_valid(int32_t *label, size_t len)
/* 4. Check characters not DISALLOWED by RFC5892 */
if (idna_prop == IDNA_P_DISALLOWED) {
- LOG("Check failed: character %" PRIsizet " (%x) is DISALLOWED", i, label[i]);
+ NSLOG(netsurf, INFO,
+ "Check failed: character %"PRIsizet" (%x) is DISALLOWED",
+ i,
+ label[i]);
return false;
}
/* 5. Check CONTEXTJ characters conform to defined rules */
if (idna_prop == IDNA_P_CONTEXTJ) {
if (idna__contextj_rule(label, i, len) == false) {
- LOG("Check failed: character %" PRIsizet " (%x) does not conform to CONTEXTJ rule", i, label[i]);
+ NSLOG(netsurf, INFO,
+ "Check failed: character %"PRIsizet" (%x) does not conform to CONTEXTJ rule",
+ i,
+ label[i]);
return false;
}
}
@@ -472,14 +480,20 @@ static bool idna__is_valid(int32_t *label, size_t len)
/** \todo optionally we can check conformance to this rule */
if (idna_prop == IDNA_P_CONTEXTO) {
if (idna__contexto_rule(label[i]) == false) {
- LOG("Check failed: character %" PRIsizet " (%x) has no CONTEXTO rule defined", i, label[i]);
+ NSLOG(netsurf, INFO,
+ "Check failed: character %"PRIsizet" (%x) has no CONTEXTO rule defined",
+ i,
+ label[i]);
return false;
}
}
/* 7. Check characters are not UNASSIGNED */
if (idna_prop == IDNA_P_UNASSIGNED) {
- LOG("Check failed: character %" PRIsizet " (%x) is UNASSIGNED", i, label[i]);
+ NSLOG(netsurf, INFO,
+ "Check failed: character %"PRIsizet" (%x) is UNASSIGNED",
+ i,
+ label[i]);
return false;
}
@@ -588,7 +602,8 @@ static bool idna__verify(const char *label, size_t len)
return true;
}
- LOG("Re-encoded ACE label %s does not match input", ace);
+ NSLOG(netsurf, INFO, "Re-encoded ACE label %s does not match input",
+ ace);
free(ace);
return false;
@@ -641,7 +656,8 @@ idna_encode(const char *host, size_t len, char **ace_host, size_t *ace_len)
/* This is already a DNS-valid ASCII string */
if ((idna__is_ace(host, label_len) == true) &&
(idna__verify(host, label_len) == false)) {
- LOG("Cannot verify ACE label %s", host);
+ NSLOG(netsurf, INFO,
+ "Cannot verify ACE label %s", host);
return NSERROR_BAD_URL;
}
strncpy(fqdn_p, host, label_len);
diff --git a/utils/jenkins-build.sh b/utils/jenkins-build.sh
index b6ca21dd7..6fd6a777a 100755
--- a/utils/jenkins-build.sh
+++ b/utils/jenkins-build.sh
@@ -147,6 +147,23 @@ case ${TARGET} in
;;
+ "amigaos3")
+ case ${HOST} in
+ "m68k-unknown-amigaos")
+ ;;
+
+ *)
+ echo "Target \"${TARGET}\" cannot be built on \"${HOST})\""
+ exit 1
+ ;;
+
+ esac
+
+ PKG_SRC=NetSurf_Amiga/netsurf
+ PKG_SFX=.lha
+ ;;
+
+
"atari")
case ${HOST} in
"m68k-atari-mint")
@@ -291,6 +308,11 @@ case ${TARGET} in
export GCCSDK_INSTALL_CROSSBIN=/opt/netsurf/${HOST}/cross/bin
;;
+ "m68k-unknown-amigaos")
+ export GCCSDK_INSTALL_ENV=/opt/netsurf/${HOST}/env
+ export GCCSDK_INSTALL_CROSSBIN=/opt/netsurf/${HOST}/cross/bin
+ ;;
+
*)
echo "Target \"${TARGET}\" cannot be built on \"${HOST})\""
exit 1
diff --git a/utils/log.c b/utils/log.c
index 15a7a9e75..e267b3179 100644
--- a/utils/log.c
+++ b/utils/log.c
@@ -1,9 +1,5 @@
/*
- * Copyright 2007 Rob Kendrick <rjek@netsurf-browser.org>
- * Copyright 2004-2007 James Bursa <bursa@users.sourceforge.net>
- * Copyright 2003 Phil Mellor <monkeyson@users.sourceforge.net>
- * Copyright 2003 John M Bell <jmb202@ecs.soton.ac.uk>
- * Copyright 2004 John Tytgat <joty@netsurf-browser.org>
+ * Copyright 2017 Vincent Sanders <vince@netsurf-browser.org>
*
* This file is part of NetSurf, http://www.netsurf-browser.org/
*
@@ -24,6 +20,7 @@
#include <stdio.h>
#include "utils/config.h"
+#include "utils/nsoption.h"
#include "utils/sys_time.h"
#include "utils/utsname.h"
#include "desktop/version.h"
@@ -36,6 +33,154 @@ bool verbose_log = false;
/** The stream to which logging is sent */
static FILE *logfile;
+/** Subtract the `struct timeval' values X and Y
+ *
+ * \param result The timeval structure to store the result in
+ * \param x The first value
+ * \param y The second value
+ * \return 1 if the difference is negative, otherwise 0.
+ */
+static int
+timeval_subtract(struct timeval *result, struct timeval *x, struct timeval *y)
+{
+ /* Perform the carry for the later subtraction by updating y. */
+ if (x->tv_usec < y->tv_usec) {
+ int nsec = (int)(y->tv_usec - x->tv_usec) / 1000000 + 1;
+ y->tv_usec -= 1000000 * nsec;
+ y->tv_sec += nsec;
+ }
+ if ((int)(x->tv_usec - y->tv_usec) > 1000000) {
+ int nsec = (int)(x->tv_usec - y->tv_usec) / 1000000;
+ y->tv_usec += 1000000 * nsec;
+ y->tv_sec -= nsec;
+ }
+
+ /* Compute the time remaining to wait.
+ tv_usec is certainly positive. */
+ result->tv_sec = x->tv_sec - y->tv_sec;
+ result->tv_usec = x->tv_usec - y->tv_usec;
+
+ /* Return 1 if result is negative. */
+ return x->tv_sec < y->tv_sec;
+}
+
+/**
+ * Obtain a formatted string suitable for prepending to a log message
+ *
+ * \return formatted string of the time since first log call
+ */
+static const char *nslog_gettime(void)
+{
+ static struct timeval start_tv;
+ static char buff[32];
+
+ struct timeval tv;
+ struct timeval now_tv;
+
+ if (!timerisset(&start_tv)) {
+ gettimeofday(&start_tv, NULL);
+ }
+ gettimeofday(&now_tv, NULL);
+
+ timeval_subtract(&tv, &now_tv, &start_tv);
+
+ snprintf(buff, sizeof(buff),"(%ld.%06ld)",
+ (long)tv.tv_sec, (long)tv.tv_usec);
+
+ return buff;
+}
+
+#ifdef WITH_NSLOG
+
+NSLOG_DEFINE_CATEGORY(netsurf, "NetSurf default logging");
+NSLOG_DEFINE_CATEGORY(llcache, "Low level cache");
+NSLOG_DEFINE_CATEGORY(fetch, "objet fetching");
+NSLOG_DEFINE_CATEGORY(plot, "rendering system");
+NSLOG_DEFINE_CATEGORY(schedule, "scheduler");
+NSLOG_DEFINE_CATEGORY(fbtk, "Framebuffer toolkit");
+NSLOG_DEFINE_CATEGORY(layout, "Layout");
+
+static void
+netsurf_render_log(void *_ctx,
+ nslog_entry_context_t *ctx,
+ const char *fmt,
+ va_list args)
+{
+ fprintf(logfile,
+ "%s %.*s:%i %.*s: ",
+ nslog_gettime(),
+ ctx->filenamelen,
+ ctx->filename,
+ ctx->lineno,
+ ctx->funcnamelen,
+ ctx->funcname);
+
+ vfprintf(logfile, fmt, args);
+
+ /* Log entries aren't newline terminated add one for clarity */
+ fputc('\n', logfile);
+}
+
+/* exported interface documented in utils/log.h */
+nserror
+nslog_set_filter(const char *filter)
+{
+ nslog_error err;
+ nslog_filter_t *filt = NULL;
+
+ err = nslog_filter_from_text(filter, &filt);
+ if (err != NSLOG_NO_ERROR) {
+ if (err == NSLOG_NO_MEMORY)
+ return NSERROR_NOMEM;
+ else
+ return NSERROR_INVALID;
+ }
+
+ err = nslog_filter_set_active(filt, NULL);
+ filt = nslog_filter_unref(filt);
+ if (err != NSLOG_NO_ERROR) {
+ return NSERROR_NOSPACE;
+ }
+
+ return NSERROR_OK;
+}
+
+#else
+
+void
+nslog_log(const char *file, const char *func, int ln, const char *format, ...)
+{
+ va_list ap;
+
+ if (verbose_log) {
+ fprintf(logfile,
+ "%s %s:%i %s: ",
+ nslog_gettime(),
+ file,
+ ln,
+ func);
+
+ va_start(ap, format);
+
+ vfprintf(logfile, format, ap);
+
+ va_end(ap);
+
+ fputc('\n', logfile);
+ }
+}
+
+/* exported interface documented in utils/log.h */
+nserror
+nslog_set_filter(const char *filter)
+{
+ (void)(filter);
+ return NSERROR_OK;
+}
+
+
+#endif
+
nserror nslog_init(nslog_ensure_t *ensure, int *pargc, char **argv)
{
struct utsname utsname;
@@ -59,9 +204,9 @@ nserror nslog_init(nslog_ensure_t *ensure, int *pargc, char **argv)
/* ensure we actually show logging */
verbose_log = true;
} else if (((*pargc) > 2) &&
- (argv[1][0] == '-') &&
- (argv[1][1] == 'V') &&
- (argv[1][2] == 0)) {
+ (argv[1][0] == '-') &&
+ (argv[1][1] == 'V') &&
+ (argv[1][2] == 0)) {
int argcmv;
/* verbose logging to file */
@@ -82,7 +227,7 @@ nserror nslog_init(nslog_ensure_t *ensure, int *pargc, char **argv)
/* ensure we actually show logging */
verbose_log = true;
}
- } else if (verbose_log == true) {
+ } else {
/* default is logging to stderr */
logfile = stderr;
}
@@ -96,94 +241,65 @@ nserror nslog_init(nslog_ensure_t *ensure, int *pargc, char **argv)
verbose_log = false;
}
+#ifdef WITH_NSLOG
+
+ if (nslog_set_filter(verbose_log ?
+ NETSURF_BUILTIN_VERBOSE_FILTER :
+ NETSURF_BUILTIN_LOG_FILTER) != NSERROR_OK) {
+ ret = NSERROR_INIT_FAILED;
+ verbose_log = false;
+ } else if (nslog_set_render_callback(netsurf_render_log, NULL) != NSLOG_NO_ERROR) {
+ ret = NSERROR_INIT_FAILED;
+ verbose_log = false;
+ } else if (nslog_uncork() != NSLOG_NO_ERROR) {
+ ret = NSERROR_INIT_FAILED;
+ verbose_log = false;
+ }
+
+#endif
+
/* sucessfull logging initialisation so log system info */
if (ret == NSERROR_OK) {
- LOG("NetSurf version '%s'", netsurf_version);
+ NSLOG(netsurf, INFO, "NetSurf version '%s'", netsurf_version);
if (uname(&utsname) < 0) {
- LOG("Failed to extract machine information");
+ NSLOG(netsurf, INFO,
+ "Failed to extract machine information");
} else {
- LOG("NetSurf on <%s>, node <%s>, release <%s>, version <%s>, machine <%s>",
- utsname.sysname,
- utsname.nodename,
- utsname.release,
- utsname.version,
- utsname.machine);
+ NSLOG(netsurf, INFO,
+ "NetSurf on <%s>, node <%s>, release <%s>, version <%s>, machine <%s>",
+ utsname.sysname,
+ utsname.nodename,
+ utsname.release,
+ utsname.version,
+ utsname.machine);
}
}
return ret;
}
-#ifndef NDEBUG
-
-/* Subtract the `struct timeval' values X and Y,
- storing the result in RESULT.
- Return 1 if the difference is negative, otherwise 0.
-*/
-
-static int
-timeval_subtract(struct timeval *result, struct timeval *x, struct timeval *y)
+/* exported interface documented in utils/log.h */
+nserror
+nslog_set_filter_by_options()
{
- /* Perform the carry for the later subtraction by updating y. */
- if (x->tv_usec < y->tv_usec) {
- int nsec = (int)(y->tv_usec - x->tv_usec) / 1000000 + 1;
- y->tv_usec -= 1000000 * nsec;
- y->tv_sec += nsec;
- }
- if ((int)(x->tv_usec - y->tv_usec) > 1000000) {
- int nsec = (int)(x->tv_usec - y->tv_usec) / 1000000;
- y->tv_usec += 1000000 * nsec;
- y->tv_sec -= nsec;
- }
-
- /* Compute the time remaining to wait.
- tv_usec is certainly positive. */
- result->tv_sec = x->tv_sec - y->tv_sec;
- result->tv_usec = x->tv_usec - y->tv_usec;
-
- /* Return 1 if result is negative. */
- return x->tv_sec < y->tv_sec;
+ if (verbose_log)
+ return nslog_set_filter(nsoption_charp(verbose_filter));
+ else
+ return nslog_set_filter(nsoption_charp(log_filter));
}
-/**
- * Obtain a formatted string suitable for prepending to a log message
- *
- * \return formatted string of the time since first log call
- */
-static const char *nslog_gettime(void)
+/* exported interface documented in utils/log.h */
+void
+nslog_finalise()
{
- static struct timeval start_tv;
- static char buff[32];
-
- struct timeval tv;
- struct timeval now_tv;
-
- if (!timerisset(&start_tv)) {
- gettimeofday(&start_tv, NULL);
+ NSLOG(netsurf, INFO,
+ "Finalising logging, please report any further messages");
+ verbose_log = true;
+ if (logfile != stderr) {
+ fclose(logfile);
+ logfile = stderr;
}
- gettimeofday(&now_tv, NULL);
-
- timeval_subtract(&tv, &now_tv, &start_tv);
-
- snprintf(buff, sizeof(buff),"(%ld.%06ld)",
- (long)tv.tv_sec, (long)tv.tv_usec);
-
- return buff;
-}
-
-void nslog_log(const char *file, const char *func, int ln, const char *format, ...)
-{
- va_list ap;
-
- fprintf(logfile, "%s %s:%i %s: ", nslog_gettime(), file, ln, func);
-
- va_start(ap, format);
-
- vfprintf(logfile, format, ap);
-
- va_end(ap);
-
- fputc('\n', logfile);
-}
-
+#ifdef WITH_NSLOG
+ nslog_cleanup();
#endif
+}
diff --git a/utils/log.h b/utils/log.h
index 708016b18..b773ec4a2 100644
--- a/utils/log.h
+++ b/utils/log.h
@@ -17,8 +17,8 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef _NETSURF_LOG_H_
-#define _NETSURF_LOG_H_
+#ifndef NETSURF_LOG_H
+#define NETSURF_LOG_H
#include <stdio.h>
#include <stdbool.h>
@@ -43,9 +43,59 @@ typedef bool(nslog_ensure_t)(FILE *fptr);
*/
extern nserror nslog_init(nslog_ensure_t *ensure, int *pargc, char **argv);
-#ifdef NDEBUG
-# define LOG(format, ...) ((void) 0)
-#else
+/**
+ * Shut down the logging system.
+ *
+ * Shuts down the logging subsystem, resetting to verbose logging and output
+ * to stderr. Note, if logging is done after calling this, it will be sent
+ * to stderr without filtering.
+ */
+extern void nslog_finalise(void);
+
+/**
+ * Set the logging filter.
+ *
+ * Compiles and enables the given logging filter.
+ */
+extern nserror nslog_set_filter(const char *filter);
+
+/**
+ * Set the logging filter according to the options.
+ */
+extern nserror nslog_set_filter_by_options(void);
+
+/* ensure a logging level is defined */
+#ifndef NETSURF_LOG_LEVEL
+#define NETSURF_LOG_LEVEL INFO
+#endif
+
+#define NSLOG_LVL(level) NSLOG_LEVEL_ ## level
+#define NSLOG_EVL(level) NSLOG_LVL(level)
+#define NSLOG_COMPILED_MIN_LEVEL NSLOG_EVL(NETSURF_LOG_LEVEL)
+
+#ifdef WITH_NSLOG
+
+#include <nslog/nslog.h>
+
+NSLOG_DECLARE_CATEGORY(netsurf);
+NSLOG_DECLARE_CATEGORY(llcache);
+NSLOG_DECLARE_CATEGORY(fetch);
+NSLOG_DECLARE_CATEGORY(plot);
+NSLOG_DECLARE_CATEGORY(schedule);
+NSLOG_DECLARE_CATEGORY(fbtk);
+NSLOG_DECLARE_CATEGORY(layout);
+
+#else /* WITH_NSLOG */
+
+enum nslog_level {
+ NSLOG_LEVEL_DEEPDEBUG = 0,
+ NSLOG_LEVEL_DEBUG = 1,
+ NSLOG_LEVEL_VERBOSE = 2,
+ NSLOG_LEVEL_INFO = 3,
+ NSLOG_LEVEL_WARNING = 4,
+ NSLOG_LEVEL_ERROR = 5,
+ NSLOG_LEVEL_CRITICAL = 6
+};
extern void nslog_log(const char *file, const char *func, int ln, const char *format, ...) __attribute__ ((format (printf, 4, 5)));
@@ -60,13 +110,13 @@ extern void nslog_log(const char *file, const char *func, int ln, const char *fo
# define LOG_LN __LINE__
# endif
-#define LOG(format, args...) \
+#define NSLOG(catname, level, logmsg, args...) \
do { \
- if (verbose_log) { \
- nslog_log(__FILE__, LOG_FN, LOG_LN, format , ##args); \
+ if (NSLOG_LEVEL_##level >= NSLOG_COMPILED_MIN_LEVEL) { \
+ nslog_log(__FILE__, LOG_FN, LOG_LN, logmsg , ##args); \
} \
} while(0)
-#endif
+#endif /* WITH_NSLOG */
#endif
diff --git a/utils/messages.c b/utils/messages.c
index 0c558cdfc..e2d45e9da 100644
--- a/utils/messages.c
+++ b/utils/messages.c
@@ -74,7 +74,8 @@ message_process_line(struct hash_table *hash, uint8_t *ln, int lnlen)
value = colon + 1;
if (hash_add(hash, (char *)ln, (char *)value) == false) {
- LOG("Unable to add %s:%s to hash table", ln, value);
+ NSLOG(netsurf, INFO, "Unable to add %s:%s to hash table", ln,
+ value);
return NSERROR_INVALID;
}
return NSERROR_OK;
@@ -97,7 +98,9 @@ static nserror messages_load_ctx(const char *path, struct hash_table **ctx)
fp = gzopen(path, "r");
if (!fp) {
- LOG("Unable to open messages file \"%.100s\": %s", path, strerror(errno));
+ NSLOG(netsurf, INFO,
+ "Unable to open messages file \"%.100s\": %s", path,
+ strerror(errno));
return NSERROR_NOT_FOUND;
}
@@ -112,7 +115,9 @@ static nserror messages_load_ctx(const char *path, struct hash_table **ctx)
nctx = *ctx;
}
if (nctx == NULL) {
- LOG("Unable to create hash table for messages file %s", path);
+ NSLOG(netsurf, INFO,
+ "Unable to create hash table for messages file %s",
+ path);
gzclose(fp);
return NSERROR_NOMEM;
}
@@ -131,7 +136,9 @@ static nserror messages_load_ctx(const char *path, struct hash_table **ctx)
value = colon + 1;
if (hash_add(nctx, s, value) == false) {
- LOG("Unable to add %s:%s to hash table of %s", s, value, path);
+ NSLOG(netsurf, INFO,
+ "Unable to add %s:%s to hash table of %s", s,
+ value, path);
gzclose(fp);
if (*ctx == NULL) {
hash_destroy(nctx);
@@ -202,7 +209,7 @@ nserror messages_add_from_file(const char *path)
return NSERROR_BAD_PARAMETER;
}
- LOG("Loading Messages from '%s'", path);
+ NSLOG(netsurf, INFO, "Loading Messages from '%s'", path);
err = messages_load_ctx(path, &messages_hash);
@@ -225,7 +232,7 @@ nserror messages_add_from_inline(const uint8_t *data, size_t data_size)
messages_hash = hash_create(HASH_SIZE);
}
if (messages_hash == NULL) {
- LOG("Unable to create hash table");
+ NSLOG(netsurf, INFO, "Unable to create hash table");
return NSERROR_NOMEM;
}
@@ -238,7 +245,7 @@ nserror messages_add_from_inline(const uint8_t *data, size_t data_size)
ret = inflateInit2(&strm, 32 + MAX_WBITS);
if (ret != Z_OK) {
- LOG("inflateInit returned %d", ret);
+ NSLOG(netsurf, INFO, "inflateInit returned %d", ret);
return NSERROR_INVALID;
}
@@ -271,7 +278,7 @@ nserror messages_add_from_inline(const uint8_t *data, size_t data_size)
}
if (used == sizeof(s)) {
/* entire buffer used and no newline */
- LOG("Overlength line");
+ NSLOG(netsurf, INFO, "Overlength line");
used = 0;
}
} while (ret != Z_STREAM_END);
@@ -279,7 +286,7 @@ nserror messages_add_from_inline(const uint8_t *data, size_t data_size)
inflateEnd(&strm);
if (ret != Z_STREAM_END) {
- LOG("inflate returned %d", ret);
+ NSLOG(netsurf, INFO, "inflate returned %d", ret);
return NSERROR_INVALID;
}
return NSERROR_OK;
@@ -338,6 +345,10 @@ const char *messages_get_errorcode(nserror code)
/* Requested item not found */
return messages_get_ctx("NotFound", messages_hash);
+ case NSERROR_NOT_DIRECTORY:
+ /* Missing directory */
+ return messages_get_ctx("NotDirectory", messages_hash);
+
case NSERROR_SAVE_FAILED:
/* Failed to save data */
return messages_get_ctx("SaveFailed", messages_hash);
@@ -350,9 +361,29 @@ const char *messages_get_errorcode(nserror code)
/* Initialisation failed */
return messages_get_ctx("InitFailed", messages_hash);
- case NSERROR_MNG_ERROR:
- /* An MNG error occurred */
- return messages_get_ctx("MNGError", messages_hash);
+ case NSERROR_BMP_ERROR:
+ /* A BMP error occurred */
+ return messages_get_ctx("BMPError", messages_hash);
+
+ case NSERROR_GIF_ERROR:
+ /* A GIF error occurred */
+ return messages_get_ctx("GIFError", messages_hash);
+
+ case NSERROR_ICO_ERROR:
+ /* A ICO error occurred */
+ return messages_get_ctx("ICOError", messages_hash);
+
+ case NSERROR_PNG_ERROR:
+ /* A PNG error occurred */
+ return messages_get_ctx("PNGError", messages_hash);
+
+ case NSERROR_SPRITE_ERROR:
+ /* A RISC OS Sprite error occurred */
+ return messages_get_ctx("SpriteError", messages_hash);
+
+ case NSERROR_SVG_ERROR:
+ /* A SVG error occurred */
+ return messages_get_ctx("SVGError", messages_hash);
case NSERROR_BAD_ENCODING:
/* The character set is unknown */
@@ -398,12 +429,40 @@ const char *messages_get_errorcode(nserror code)
/* Bad URL */
return messages_get_ctx("BadURL", messages_hash);
- default:
+ case NSERROR_BAD_CONTENT:
+ /* Bad Content */
+ return messages_get_ctx("BadContent", messages_hash);
+
+ case NSERROR_FRAME_DEPTH:
+ /* Exceeded frame depth */
+ return messages_get_ctx("FrameDepth", messages_hash);
+
+ case NSERROR_PERMISSION:
+ /* Permission error */
+ return messages_get_ctx("PermissionError", messages_hash);
+
+ case NSERROR_BAD_SIZE:
+ /* Bad size */
+ return messages_get_ctx("BadSize", messages_hash);
+
+ case NSERROR_NOSPACE:
+ /* Insufficient space */
+ return messages_get_ctx("NoSpace", messages_hash);
+
+ case NSERROR_NOT_IMPLEMENTED:
+ /* Functionality is not implemented */
+ return messages_get_ctx("NotImplemented", messages_hash);
+
case NSERROR_UNKNOWN:
- break;
+ /* Unknown error */
+ return messages_get_ctx("Unknown", messages_hash);
}
- /* Unknown error */
+ /* The switch has no default, so the compiler should tell us when we
+ * forget to add messages for new error codes. As such, we should
+ * never get here.
+ */
+ assert(0);
return messages_get_ctx("Unknown", messages_hash);
}
diff --git a/utils/nsoption.c b/utils/nsoption.c
index 8f05a911b..09529a0d0 100644
--- a/utils/nsoption.c
+++ b/utils/nsoption.c
@@ -187,7 +187,7 @@ static void nsoption_validate(struct nsoption_s *opts, struct nsoption_s *defs)
break;
}
}
- if (black == true) {
+ if (black == true && defs != NULL) {
for (cloop = NSOPTION_SYS_COLOUR_START;
cloop <= NSOPTION_SYS_COLOUR_END;
cloop++) {
@@ -209,6 +209,9 @@ static void nsoption_validate(struct nsoption_s *opts, struct nsoption_s *defs)
opts[NSOPTION_max_retried_fetches].value.u) > 60) &&
(opts[NSOPTION_max_retried_fetches].value.u > 1))
opts[NSOPTION_max_retried_fetches].value.u--;
+
+ /* We ignore the result because we can't fail to validate. Yay */
+ (void)nslog_set_filter_by_options();
}
/**
@@ -648,11 +651,12 @@ nsoption_read(const char *path, struct nsoption_s *opts)
fp = fopen(path, "r");
if (!fp) {
- LOG("Failed to open file '%s'", path);
+ NSLOG(netsurf, INFO, "Failed to open file '%s'", path);
return NSERROR_NOT_FOUND;
}
- LOG("Successfully opened '%s' for Options file", path);
+ NSLOG(netsurf, INFO, "Successfully opened '%s' for Options file",
+ path);
while (fgets(s, NSOPTION_MAX_LINE_LEN, fp)) {
char *colon, *value;
@@ -718,7 +722,8 @@ nsoption_write(const char *path,
fp = fopen(path, "w");
if (!fp) {
- LOG("failed to open file '%s' for writing", path);
+ NSLOG(netsurf, INFO, "failed to open file '%s' for writing",
+ path);
return NSERROR_NOT_FOUND;
}
@@ -798,7 +803,7 @@ nsoption_commandline(int *pargc, char **argv, struct nsoption_s *opts)
/* arg+arglen is the option to set, val is the value */
- LOG("%.*s = %s", arglen, arg, val);
+ NSLOG(netsurf, INFO, "%.*s = %s", arglen, arg, val);
for (entry_loop = 0;
entry_loop < NSOPTION_LISTEND;
@@ -818,6 +823,8 @@ nsoption_commandline(int *pargc, char **argv, struct nsoption_s *opts)
}
*pargc -= (idx - 1);
+ nsoption_validate(opts, nsoptions_default);
+
return NSERROR_OK;
}
diff --git a/utils/nsurl/nsurl.c b/utils/nsurl/nsurl.c
index 7166a2707..3b0af9328 100644
--- a/utils/nsurl/nsurl.c
+++ b/utils/nsurl/nsurl.c
@@ -230,7 +230,8 @@ lwc_string *nsurl_get_component(const nsurl *url, nsurl_component part)
lwc_string_ref(url->components.fragment) : NULL;
default:
- LOG("Unsupported value passed to part param.");
+ NSLOG(netsurf, INFO,
+ "Unsupported value passed to part param.");
assert(0);
}
@@ -296,7 +297,8 @@ bool nsurl_has_component(const nsurl *url, nsurl_component part)
return false;
default:
- LOG("Unsupported value passed to part param.");
+ NSLOG(netsurf, INFO,
+ "Unsupported value passed to part param.");
assert(0);
}
diff --git a/utils/nsurl/parse.c b/utils/nsurl/parse.c
index 7474a612d..ce6f4435d 100644
--- a/utils/nsurl/parse.c
+++ b/utils/nsurl/parse.c
@@ -451,19 +451,19 @@ static void nsurl__get_string_markers(const char * const url_s,
}
#ifdef NSURL_DEBUG
- LOG("marker.start: %i", marker.start);
- LOG("marker.scheme_end: %i", marker.scheme_end);
- LOG("marker.authority: %i", marker.authority);
+ NSLOG(netsurf, INFO, "marker.start: %i", marker.start);
+ NSLOG(netsurf, INFO, "marker.scheme_end: %i", marker.scheme_end);
+ NSLOG(netsurf, INFO, "marker.authority: %i", marker.authority);
- LOG("marker.colon_first: %i", marker.colon_first);
- LOG("marker.at: %i", marker.at);
- LOG("marker.colon_last: %i", marker.colon_last);
+ NSLOG(netsurf, INFO, "marker.colon_first: %i", marker.colon_first);
+ NSLOG(netsurf, INFO, "marker.at: %i", marker.at);
+ NSLOG(netsurf, INFO, "marker.colon_last: %i", marker.colon_last);
- LOG("marker.path: %i", marker.path);
- LOG("marker.query: %i", marker.query);
- LOG("marker.fragment: %i", marker.fragment);
+ NSLOG(netsurf, INFO, "marker.path: %i", marker.path);
+ NSLOG(netsurf, INFO, "marker.query: %i", marker.query);
+ NSLOG(netsurf, INFO, "marker.fragment: %i", marker.fragment);
- LOG("marker.end: %i", marker.end);
+ NSLOG(netsurf, INFO, "marker.end: %i", marker.end);
#endif
/* Got all the URL components pegged out now */
@@ -485,8 +485,8 @@ static size_t nsurl__remove_dot_segments(char *path, char *output)
while (*path_pos != '\0') {
#ifdef NSURL_DEBUG
- LOG(" in:%s", path_pos);
- LOG("out:%.*s", output_pos - output, output);
+ NSLOG(netsurf, INFO, " in:%s", path_pos);
+ NSLOG(netsurf, INFO, "out:%.*s", output_pos - output, output);
#endif
if (*path_pos == '.') {
if (*(path_pos + 1) == '.' &&
@@ -1324,7 +1324,8 @@ nserror nsurl_join(const nsurl *base, const char *rel, nsurl **joined)
assert(rel != NULL);
#ifdef NSURL_DEBUG
- LOG("base: \"%s\", rel: \"%s\"", nsurl_access(base), rel);
+ NSLOG(netsurf, INFO, "base: \"%s\", rel: \"%s\"", nsurl_access(base),
+ rel);
#endif
/* Peg out the URL sections */
diff --git a/utils/nsurl/private.h b/utils/nsurl/private.h
index 89d7ed49e..bc6737cd6 100644
--- a/utils/nsurl/private.h
+++ b/utils/nsurl/private.h
@@ -187,28 +187,44 @@ static inline void nsurl__components_destroy(struct nsurl_components *c)
static inline void nsurl__dump(const nsurl *url)
{
if (url->components.scheme)
- LOG(" Scheme: %s", lwc_string_data(url->components.scheme));
+ NSLOG(netsurf, INFO,netsurf, INFO,
+ " Scheme: %s",
+ lwc_string_data(url->components.scheme));
if (url->components.username)
- LOG("Username: %s", lwc_string_data(url->components.username));
+ NSLOG(netsurf, INFO,
+ "Username: %s",
+ lwc_string_data(url->components.username));
if (url->components.password)
- LOG("Password: %s", lwc_string_data(url->components.password));
+ NSLOG(netsurf, INFO,
+ "Password: %s",
+ lwc_string_data(url->components.password));
if (url->components.host)
- LOG(" Host: %s", lwc_string_data(url->components.host));
+ NSLOG(netsurf, INFO,
+ " Host: %s",
+ lwc_string_data(url->components.host));
if (url->components.port)
- LOG(" Port: %s", lwc_string_data(url->components.port));
+ NSLOG(netsurf, INFO,
+ " Port: %s",
+ lwc_string_data(url->components.port));
if (url->components.path)
- LOG(" Path: %s", lwc_string_data(url->components.path));
+ NSLOG(netsurf, INFO,
+ " Path: %s",
+ lwc_string_data(url->components.path));
if (url->components.query)
- LOG(" Query: %s", lwc_string_data(url->components.query));
+ NSLOG(netsurf, INFO,
+ " Query: %s",
+ lwc_string_data(url->components.query));
if (url->components.fragment)
- LOG("Fragment: %s", lwc_string_data(url->components.fragment));
+ NSLOG(netsurf, INFO,
+ "Fragment: %s",
+ lwc_string_data(url->components.fragment));
}
#endif
diff --git a/utils/useragent.c b/utils/useragent.c
index 72e45aada..b528dce4f 100644
--- a/utils/useragent.c
+++ b/utils/useragent.c
@@ -65,7 +65,8 @@ user_agent_build_string(void)
core_user_agent_string = ua_string;
- LOG("Built user agent \"%s\"", core_user_agent_string);
+ NSLOG(netsurf, INFO, "Built user agent \"%s\"",
+ core_user_agent_string);
}
/* This is a function so that later we can override it trivially */
diff --git a/utils/utf8.c b/utils/utf8.c
index 5c930cd13..f0ac0c9b2 100644
--- a/utils/utf8.c
+++ b/utils/utf8.c
@@ -468,7 +468,8 @@ bool utf8_save_text(const char *utf8_text, const char *path)
ret = guit->utf8->utf8_to_local(utf8_text, strlen(utf8_text), &conv);
if (ret != NSERROR_OK) {
- LOG("failed to convert to local encoding, return %d", ret);
+ NSLOG(netsurf, INFO,
+ "failed to convert to local encoding, return %d", ret);
return false;
}
@@ -476,7 +477,7 @@ bool utf8_save_text(const char *utf8_text, const char *path)
if (out) {
int res = fputs(conv, out);
if (res < 0) {
- LOG("Warning: writing data failed");
+ NSLOG(netsurf, INFO, "Warning: writing data failed");
}
res = fputs("\n", out);