Index: build/premake/extern_libs5.lua =================================================================== --- build/premake/extern_libs5.lua +++ build/premake/extern_libs5.lua @@ -39,6 +39,13 @@ pkgconfig = require "pkgconfig" +-- Configure pkgconfig for MacOSX systems +if os.istarget("macosx") then + pkgconfig.additional_pc_path = libraries_dir .. "pkgconfig/" + pkgconfig.static_link_libs = true +elseif not os.istarget("windows") then + pkgconfig.additional_pc_path = libraries_source_dir .. "pkgconfig/" +end local function add_delayload(name, suffix, def) @@ -228,18 +235,21 @@ }, enet = { compile_settings = function() - if os.istarget("windows") or os.istarget("macosx") then + if os.istarget("windows") then add_default_include_paths("enet") + else + pkgconfig.add_includes("libenet") end end, link_settings = function() - if os.istarget("windows") or os.istarget("macosx") then + if os.istarget("windows") then add_default_lib_paths("enet") + add_default_links({ + win_names = { "enet" }, + }) + else + pkgconfig.add_links("libenet") end - add_default_links({ - win_names = { "enet" }, - unix_names = { "enet" }, - }) end, }, fcollada = { @@ -265,16 +275,18 @@ }, fmt = { compile_settings = function() - if os.istarget("windows") or os.istarget("macosx") then + if os.istarget("windows") then add_default_include_paths("fmt") + elseif os.istarget("macosx") then + pkgconfig.add_includes("fmt") end -- With Linux & BSD, we assume that fmt is installed in a standard location. -- - -- It would be nice to not assume, and to instead use pkgconfig: however that + -- It would be nice to not assume, and to instead use pkg-config: however that -- requires fmt 5.3.0 or greater. -- - -- Unfortunately (at the time of writing) only 69 out of 95 (~72.6%) of distros + -- Unfortunately (at the time of writing) only 81 out of 104 (~77.9%) of distros -- that provide a fmt package meet this, according to -- https://repology.org/badge/vertical-allrepos/fmt.svg?minversion=5.3 -- @@ -284,27 +296,23 @@ -- Mint). -- -- When fmt 5.3 (or better) becomes more widely used, then we can safely use the - -- following line: - -- pkgconfig.add_includes("fmt") + -- same line as we currently use for osx end, link_settings = function() - if os.istarget("windows") or os.istarget("macosx") then - add_default_lib_paths("fmt") - end - if os.istarget("windows") then + add_default_lib_paths("fmt") add_default_links({ win_names = { "fmt" }, dbg_suffix = "d", no_delayload = 1, }) + elseif os.istarget("macosx") then + -- See comment above as to why this is not also used on Linux or BSD. + pkgconfig.add_links("fmt") else add_default_links({ unix_names = { "fmt" }, }) - - -- See comment above as to why this is commented out. - -- pkgconfig.add_links("fmt") end end }, @@ -313,9 +321,7 @@ if os.istarget("windows") then add_default_include_paths("gloox") else - -- Support GLOOX_CONFIG for overriding the default (pkg-config --cflags gloox) - -- i.e. on OSX where it gets set in update-workspaces.sh - pkgconfig.add_includes("gloox", os.getenv("GLOOX_CONFIG")) + pkgconfig.add_includes("gloox") end end, link_settings = function() @@ -326,17 +332,12 @@ no_delayload = 1, }) else - pkgconfig.add_links("gloox", os.getenv("GLOOX_CONFIG")) + pkgconfig.add_links("gloox") if os.istarget("macosx") then - -- Manually add gnutls dependencies, those are not present in gloox's pkg-config - add_default_lib_paths("nettle") - add_default_lib_paths("gmp") - add_default_links({ - osx_names = { "nettle", "hogweed", "gmp" }, - }) + -- gloox depends on gnutls, but doesn't identify this via pkg-config + pkgconfig.add_links("gnutls") end - end end, }, @@ -373,9 +374,7 @@ if os.istarget("windows") then add_default_include_paths("icu") else - -- Support ICU_CONFIG for overriding the default (pkg-config --cflags icu-i18n) - -- i.e. on OSX where it gets set in update-workspaces.sh - pkgconfig.add_includes("icu-i18n", os.getenv("ICU_CONFIG"), "--cppflags") + pkgconfig.add_includes("icu-i18n") end end, link_settings = function() @@ -387,25 +386,27 @@ no_delayload = 1, }) else - pkgconfig.add_links("icu-i18n", os.getenv("ICU_CONFIG"), "--ldflags-searchpath --ldflags-libsonly --ldflags-system") + pkgconfig.add_links("icu-i18n") end end, }, libcurl = { compile_settings = function() - if os.istarget("windows") or os.istarget("macosx") then + if os.istarget("windows") then add_default_include_paths("libcurl") + else + pkgconfig.add_includes("libcurl") end end, link_settings = function() - if os.istarget("windows") or os.istarget("macosx") then + if os.istarget("windows") then add_default_lib_paths("libcurl") + else + pkgconfig.add_links("libcurl") end add_default_links({ win_names = { "libcurl" }, - unix_names = { "curl" }, - osx_names = { "curl", "z" }, - osx_frameworks = { "Security" } + osx_frameworks = { "Security" }, -- Not supplied by curl's pkg-config }) end, }, @@ -414,9 +415,7 @@ if os.istarget("windows") then add_default_include_paths("libpng") else - -- Support LIBPNG_CONFIG for overriding the default (pkg-config --cflags libpng) - -- i.e. on OSX where it gets set in update-workspaces.sh - pkgconfig.add_includes("libpng", os.getenv("LIBPNG_CONFIG")) + pkgconfig.add_includes("libpng") end end, link_settings = function() @@ -426,24 +425,27 @@ win_names = { "libpng16" }, }) else - pkgconfig.add_links("libpng", os.getenv("LIBPNG_CONFIG"), "--ldflags") + pkgconfig.add_links("libpng") end end, }, libsodium = { compile_settings = function() - if os.istarget("windows") or os.istarget("macosx") then + if os.istarget("windows") then add_default_include_paths("libsodium") + else + pkgconfig.add_includes("libsodium") end end, link_settings = function() - if os.istarget("windows") or os.istarget("macosx") then + if os.istarget("windows") then add_default_lib_paths("libsodium") + add_default_links({ + win_names = { "libsodium" }, + }) + else + pkgconfig.add_links("libsodium") end - add_default_links({ - win_names = { "libsodium" }, - unix_names = { "sodium" }, - }) end, }, libxml2 = { @@ -451,14 +453,13 @@ if os.istarget("windows") then add_default_include_paths("libxml2") else - -- Support XML2_CONFIG for overriding the default (pkg-config --cflags libxml-2.0) - -- i.e. on OSX where it gets set in update-workspaces.sh - pkgconfig.add_includes("libxml-2.0", os.getenv("XML2_CONFIG")) - end - if os.istarget("macosx") then - -- libxml2 needs _REENTRANT or __MT__ for thread support; - -- OS X doesn't get either set by default, so do it manually - defines { "_REENTRANT" } + pkgconfig.add_includes("libxml-2.0") + + if os.istarget("macosx") then + -- libxml2 needs _REENTRANT or __MT__ for thread support; + -- OS X doesn't get either set by default, so do it manually + defines { "_REENTRANT" } + end end end, link_settings = function() @@ -470,24 +471,48 @@ links { "libxml2" } filter { } else - pkgconfig.add_links("libxml-2.0", os.getenv("XML2_CONFIG")) + pkgconfig.add_links("libxml-2.0") end end, }, miniupnpc = { compile_settings = function() - if os.istarget("windows") or os.istarget("macosx") then + if os.istarget("windows") then add_default_include_paths("miniupnpc") + elseif os.istarget("macosx") then + pkgconfig.add_includes("miniupnpc") end + + -- On Linux and BSD systems we assume miniupnpc is installed in a standard location. + -- + -- Support for pkg-config was added in v2.1 of miniupnpc (May 2018). However, the + -- implementation was flawed - it provided the wrong path to the project's headers. + -- This was corrected in v2.2.1 (December 2020). + -- + -- At the time of writing, of the 115 Linux and BSD package repositories tracked by + -- Repology that supply a version of miniupnpc: + -- * 77 (~67.96%) have >= v2.1, needed to locate libraries + -- * 31 (~26.96%) have >= v2.2.1, needed to (correctly) locate headers + -- + -- Once more recent versions become more widespread, we can safely start to use + -- pkg-config to find miniupnpc on Linux and BSD systems. + -- https://repology.org/badge/vertical-allrepos/miniupnpc.svg?minversion=2.2.1 end, link_settings = function() - if os.istarget("windows") or os.istarget("macosx") then + if os.istarget("windows") then add_default_lib_paths("miniupnpc") + add_default_links({ + win_names = { "miniupnpc" }, + }) + elseif os.istarget("macosx") then + pkgconfig.add_links("miniupnpc") + else + -- Once miniupnpc v2.1 or better becomes near-universal (see above comment), + -- we can use pkg-config for Linux and BSD. + add_default_links({ + unix_names = { "miniupnpc" }, + }) end - add_default_links({ - win_names = { "miniupnpc" }, - unix_names = { "miniupnpc" }, - }) end, }, nvtt = { @@ -513,44 +538,53 @@ compile_settings = function() if os.istarget("windows") then add_default_include_paths("openal") + elseif not os.istarget("macosx") then + pkgconfig.add_includes("openal") end end, link_settings = function() if os.istarget("windows") then add_default_lib_paths("openal") + add_default_links({ + win_names = { "openal32" }, + dbg_suffix = "", + no_delayload = 1, -- delayload seems to cause errors on startup + }) + elseif os.istarget("macosx") then + add_default_links({ + osx_frameworks = { "OpenAL" }, + }) + else + pkgconfig.add_links("openal") end - add_default_links({ - win_names = { "openal32" }, - unix_names = { "openal" }, - osx_frameworks = { "OpenAL" }, - dbg_suffix = "", - no_delayload = 1, -- delayload seems to cause errors on startup - }) end, }, opengl = { compile_settings = function() if os.istarget("windows") then add_default_include_paths("opengl") + elseif _OPTIONS["gles"] then + pkgconfig.add_includes("glesv2") + elseif not os.istarget("macosx") then + pkgconfig.add_includes("gl") end end, link_settings = function() if os.istarget("windows") then add_default_lib_paths("opengl") - end - if _OPTIONS["gles"] then add_default_links({ - unix_names = { "GLESv2" }, + win_names = { "opengl32", "gdi32" }, dbg_suffix = "", + no_delayload = 1, -- delayload seems to cause errors on startup }) - else + elseif os.istarget("macosx") then add_default_links({ - win_names = { "opengl32", "gdi32" }, - unix_names = { "GL" }, osx_frameworks = { "OpenGL" }, - dbg_suffix = "", - no_delayload = 1, -- delayload seems to cause errors on startup }) + elseif _OPTIONS["gles"] then + pkgconfig.add_links("glesv2") + else + pkgconfig.add_links("gl") end end, }, @@ -559,16 +593,14 @@ if os.istarget("windows") then includedirs { libraries_dir .. "sdl2/include/SDL" } elseif not _OPTIONS["android"] then - -- Support SDL2_CONFIG for overriding the default (pkg-config sdl2) - -- i.e. on OSX where it gets set in update-workspaces.sh - pkgconfig.add_includes("sdl2", os.getenv("SDL2_CONFIG")) + pkgconfig.add_includes("sdl2") end end, link_settings = function() if os.istarget("windows") then add_default_lib_paths("sdl2") elseif not _OPTIONS["android"] then - pkgconfig.add_links("sdl2", os.getenv("SDL2_CONFIG")) + pkgconfig.add_links("sdl2") end end, }, @@ -579,17 +611,26 @@ pkgconfig.add_includes("mozjs-78") end else + library_name = "mozjs78-ps" if os.istarget("windows") then - include_dir = "include-win32" buildoptions { "/FI\"js/RequiredDefines.h\"" } - else - include_dir = "include-unix" end + filter "Debug" - sysincludedirs { libraries_source_dir.."spidermonkey/"..include_dir.."-debug" } defines { "DEBUG" } + if os.istarget("windows") then + sysincludedirs { libraries_dir.."spidermonkey/include/"..library_name.."-debug" } + else + pkgconfig.add_includes(library_name.."-debug") + end + filter "Release" - sysincludedirs { libraries_source_dir.."spidermonkey/"..include_dir.."-release" } + if os.istarget("windows") then + sysincludedirs { libraries_dir.."spidermonkey/include/"..library_name.."-release" } + else + pkgconfig.add_includes(library_name.."-release") + end + filter { } end end, @@ -601,18 +642,28 @@ pkgconfig.add_links("mozjs-78") end else - filter { "Debug", "action:vs*" } - links { "mozjs78-ps-debug" } - links { "mozjs78-ps-rust-debug" } - filter { "Debug", "action:not vs*" } - links { "mozjs78-ps-debug" } - links { "mozjs78-ps-rust" } - filter { "Release" } - links { "mozjs78-ps-release" } - links { "mozjs78-ps-rust" } + library_name = "mozjs78-ps" + if os.istarget("windows") then + add_default_lib_paths("spidermonkey") + end + + filter "Debug" + if os.istarget("windows") then + links { library_name.."-debug" } + else + pkgconfig.add_links(library_name.."-debug") + end + + filter "Release" + if os.istarget("windows") then + links { library_name.."-release" } + else + pkgconfig.add_links(library_name.."-release") + end + filter { } - add_source_lib_paths("spidermonkey") end + end, }, tinygettext = { @@ -629,31 +680,26 @@ compile_settings = function() if os.istarget("windows") then add_default_include_paths("vorbis") - elseif os.istarget("macosx") then - add_default_include_paths("libogg") - add_default_include_paths("vorbis") + else + pkgconfig.add_includes("ogg") + pkgconfig.add_includes("vorbisfile") end end, link_settings = function() if os.istarget("windows") then add_default_lib_paths("vorbis") - elseif os.istarget("macosx") then - add_default_lib_paths("libogg") - add_default_lib_paths("vorbis") - end - -- TODO: We need to force linking with these as currently - -- they need to be loaded explicitly on execution - if os.getversion().description == "OpenBSD" then add_default_links({ - unix_names = { "ogg", - "vorbis" }, + win_names = { "libvorbisfile" }, }) + elseif os.getversion().description == "OpenBSD" then + -- TODO: We need to force linking with these as currently + -- they need to be loaded explicitly on execution + add_default_links({ + unix_names = { "ogg", "vorbis" }, + }) + else + pkgconfig.add_links("vorbisfile") end - add_default_links({ - win_names = { "libvorbisfile" }, - unix_names = { "vorbisfile" }, - osx_names = { "vorbis", "vorbisenc", "vorbisfile", "ogg" }, - }) end, }, wxwidgets = { @@ -691,19 +737,22 @@ }, zlib = { compile_settings = function() - if os.istarget("windows") or os.istarget("macosx") then + if os.istarget("windows") then add_default_include_paths("zlib") + else + pkgconfig.add_includes("zlib") end end, link_settings = function() - if os.istarget("windows") or os.istarget("macosx") then + if os.istarget("windows") then add_default_lib_paths("zlib") + add_default_links({ + win_names = { "zlib1" }, + no_delayload = 1, + }) + else + pkgconfig.add_links("zlib") end - add_default_links({ - win_names = { "zlib1" }, - unix_names = { "z" }, - no_delayload = 1, - }) end, }, } Index: build/premake/pkgconfig/pkgconfig.lua =================================================================== --- build/premake/pkgconfig/pkgconfig.lua +++ build/premake/pkgconfig/pkgconfig.lua @@ -1,5 +1,8 @@ local m = {} -m._VERSION = "1.1.0-dev" +m._VERSION = "1.1.1-dev" + +m.additional_pc_path = nil +m.static_link_libs = false local function os_capture(cmd) return io.popen(cmd, 'r'):read('*a'):gsub("\n", " ") @@ -8,7 +11,8 @@ function m.add_includes(lib, alternative_cmd, alternative_flags) local result if not alternative_cmd then - result = os_capture("pkg-config --cflags "..lib) + local pc_path = m.additional_pc_path and "PKG_CONFIG_PATH="..m.additional_pc_path or "" + result = os_capture(pc_path.." pkg-config --cflags "..lib) else if not alternative_flags then result = os_capture(alternative_cmd.." --cflags") @@ -42,9 +46,11 @@ function m.add_links(lib, alternative_cmd, alternative_flags) local result if not alternative_cmd then - result = os_capture("pkg-config --libs "..lib) + local pc_path = m.additional_pc_path and "PKG_CONFIG_PATH="..m.additional_pc_path or "" + local static = m.static_link_libs and " --static " or "" + result = os_capture(pc_path.." pkg-config --libs "..static..lib) else - if not alternative_flags then + if not alternative_flags then result = os_capture(alternative_cmd.." --libs") else result = os_capture(alternative_cmd.." "..alternative_flags) Index: build/workspaces/update-workspaces.sh =================================================================== --- build/workspaces/update-workspaces.sh +++ build/workspaces/update-workspaces.sh @@ -70,13 +70,8 @@ # Set minimal SDK version export MIN_OSX_VERSION=${MIN_OSX_VERSION:="10.12"} - # Set *_CONFIG variables on OS X, to override the path to e.g. sdl2-config - export GLOOX_CONFIG=${GLOOX_CONFIG:="$(pwd)/../../libraries/osx/gloox/bin/gloox-config"} - export ICU_CONFIG=${ICU_CONFIG:="$(pwd)/../../libraries/osx/icu/bin/icu-config"} - export LIBPNG_CONFIG=${PNG_CONFIG:="$(pwd)/../../libraries/osx/libpng/bin/libpng-config"} - export SDL2_CONFIG=${SDL2_CONFIG:="$(pwd)/../../libraries/osx/sdl2/bin/sdl2-config"} + # Provide path to wx-config on OS X (as wxwidgets doesn't support pkgconfig) export WX_CONFIG=${WX_CONFIG:="$(pwd)/../../libraries/osx/wxwidgets/bin/wx-config"} - export XML2_CONFIG=${XML2_CONFIG:="$(pwd)/../../libraries/osx/libxml2/bin/xml2-config"} fi # Don't want to build bundled libs on OS X @@ -85,11 +80,15 @@ echo "Updating bundled third-party dependencies..." echo + # Create a directory to place pkg-config's .pc files in + PC_PATH="$(pwd)/../../libraries/source/pkgconfig/" + mkdir -p $PC_PATH + # Build/update bundled external libraries (cd ../../libraries/source/fcollada && MAKE=${MAKE} JOBS=${JOBS} ./build.sh) || die "FCollada build failed" echo if [ "$with_system_mozjs" = "false" ]; then - (cd ../../libraries/source/spidermonkey && MAKE=${MAKE} JOBS=${JOBS} ./build.sh) || die "SpiderMonkey build failed" + (cd ../../libraries/source/spidermonkey && MAKE=${MAKE} JOBS=${JOBS} PC_DIR=${PC_PATH} ./build.sh) || die "SpiderMonkey build failed" fi echo if [ "$with_system_nvtt" = "false" ] && [ "$without_nvtt" = "false" ]; then Index: libraries/osx/build-osx-libs.sh =================================================================== --- libraries/osx/build-osx-libs.sh +++ libraries/osx/build-osx-libs.sh @@ -133,6 +133,13 @@ cd "$(dirname $0)" # Now in libraries/osx/ (where we assume this script resides) +# Create a location to create copies of dependencies' *.pc files, so they can be found by pkg-config +PC_PATH="$(pwd)/pkgconfig/" +if [[ "$force_rebuild" = "true" ]]; then + rm -rf $PC_PATH +fi +mkdir -p $PC_PATH + # -------------------------------------------------------------- echo -e "Building zlib..." @@ -161,7 +168,9 @@ ./configure --prefix="$ZLIB_DIR" \ --static \ && make ${JOBS} && make install) || die "zlib build failed" + popd + cp -f lib/pkgconfig/* $PC_PATH echo "$LIB_VERSION" > .already-built else already_built @@ -218,7 +227,9 @@ --with-zlib="${ZLIB_DIR}" \ --enable-shared=no \ && make ${JOBS} && make install) || die "libcurl build failed" + popd + cp -f lib/pkgconfig/* $PC_PATH echo "$LIB_VERSION" > .already-built else already_built @@ -293,7 +304,9 @@ --with-zlib="${ZLIB_DIR}" \ --enable-shared=no \ && make ${JOBS} && make install) || die "libxml2 build failed" + popd + cp -f lib/pkgconfig/* $PC_PATH echo "$LIB_VERSION" > .already-built else already_built @@ -335,7 +348,9 @@ --enable-video-cocoa \ --enable-shared=no \ && make $JOBS && make install) || die "SDL2 build failed" + popd + cp -f lib/pkgconfig/* $PC_PATH echo "$LIB_VERSION" > .already-built else already_built @@ -475,7 +490,9 @@ --prefix=$INSTALL_DIR \ --enable-shared=no \ && make ${JOBS} && make install) || die "libpng build failed" + popd + cp -f lib/pkgconfig/* $PC_PATH echo "$LIB_VERSION" > .already-built else already_built @@ -483,6 +500,7 @@ popd > /dev/null # -------------------------------------------------------------- +# Dependency of vorbis echo -e "Building libogg..." LIB_VERSION="${OGG_VERSION}" @@ -490,11 +508,7 @@ LIB_DIRECTORY="$LIB_VERSION" LIB_URL="http://downloads.xiph.org/releases/ogg/" -# Dependency of vorbis -# we can install them in the same directory for convenience mkdir -p libogg -mkdir -p vorbis - pushd libogg > /dev/null OGG_DIR="$(pwd)" @@ -512,7 +526,9 @@ --prefix=$OGG_DIR \ --enable-shared=no \ && make ${JOBS} && make install) || die "libogg build failed" + popd + cp -f lib/pkgconfig/* $PC_PATH echo "$LIB_VERSION" > .already-built else already_built @@ -527,6 +543,7 @@ LIB_DIRECTORY="$LIB_VERSION" LIB_URL="http://downloads.xiph.org/releases/vorbis/" +mkdir -p vorbis pushd vorbis > /dev/null if [[ "$force_rebuild" = "true" ]] || [[ ! -e .already-built ]] || [[ "$(<.already-built)" != "$LIB_VERSION" ]] @@ -546,7 +563,9 @@ --enable-shared=no \ --with-ogg="$OGG_DIR" \ && make ${JOBS} && make install) || die "libvorbis build failed" + popd + cp -f lib/pkgconfig/* $PC_PATH echo "$LIB_VERSION" > .already-built else already_built @@ -587,7 +606,9 @@ --disable-shared \ --with-pic \ && make ${JOBS} && make install) || die "GMP build failed" + popd + cp -f lib/pkgconfig/* $PC_PATH echo "$LIB_VERSION" > .already-built else already_built @@ -596,6 +617,7 @@ # -------------------------------------------------------------- echo -e "Building Nettle..." +# Also builds hogweed LIB_VERSION="${NETTLE_VERSION}" LIB_ARCHIVE="$LIB_VERSION.tar.gz" @@ -632,7 +654,9 @@ --disable-openssl \ --disable-assembler \ && make ${JOBS} && make install) || die "Nettle build failed" + popd + cp -f lib/pkgconfig/* $PC_PATH echo "$LIB_VERSION" > .already-built else already_built @@ -688,7 +712,9 @@ --disable-tools \ --disable-nls \ && make ${JOBS} LDFLAGS= install) || die "GnuTLS build failed" + popd + cp -f lib/pkgconfig/* $PC_PATH echo "$LIB_VERSION" > .already-built else already_built @@ -733,7 +759,9 @@ --without-examples \ --disable-getaddrinfo \ && make ${JOBS} && make install) || die "gloox build failed" + popd + cp -f lib/pkgconfig/* $PC_PATH echo "$LIB_VERSION" > .already-built else already_built @@ -748,7 +776,7 @@ LIB_DIRECTORY="icu" LIB_URL="https://github.com/unicode-org/icu/releases/download/release-67-1/" -mkdir -p $LIB_DIRECTORY +mkdir -p icu pushd icu > /dev/null if [[ "$force_rebuild" = "true" ]] || [[ ! -e .already-built ]] || [[ "$(<.already-built)" != "$LIB_VERSION" ]] @@ -775,8 +803,10 @@ --enable-icuio \ --enable-tools \ && make ${JOBS} && make install) || die "ICU build failed" + popd popd + cp -f lib/pkgconfig/* $PC_PATH echo "$LIB_VERSION" > .already-built else already_built @@ -810,7 +840,9 @@ --prefix=${INSTALL_DIR} \ --enable-shared=no \ && make clean && make ${JOBS} && make install) || die "ENet build failed" + popd + cp -f lib/pkgconfig/* $PC_PATH echo "$LIB_VERSION" > .already-built else already_built @@ -843,9 +875,11 @@ && CFLAGS=$CFLAGS LDFLAGS=$LDFLAGS make ${JOBS} \ && INSTALLPREFIX="$INSTALL_DIR" make install \ ) || die "MiniUPnPc build failed" + popd # TODO: how can we not build the dylibs? rm -f lib/*.dylib + cp -f lib/pkgconfig/* $PC_PATH echo "$LIB_VERSION" > .already-built else already_built @@ -883,7 +917,9 @@ && make check \ && INSTALLPREFIX="$INSTALL_DIR" make install \ ) || die "libsodium build failed" + popd + cp -f lib/pkgconfig/* $PC_PATH echo "$LIB_VERSION" > .already-built else already_built @@ -925,6 +961,7 @@ popd popd + cp -f lib/pkgconfig/* $PC_PATH echo "$FMT_VERSION" > .already-built else already_built @@ -944,7 +981,7 @@ fi # Use the regular build script for SM. -JOBS="$JOBS" ZLIB_DIR="$ZLIB_DIR" ./build.sh || die "Error building spidermonkey" +JOBS="$JOBS" ZLIB_DIR="$ZLIB_DIR" PC_DIR="$PC_PATH" ./build.sh || die "Error building spidermonkey" popd > /dev/null Index: libraries/source/spidermonkey/RemoveShellInstall.diff =================================================================== --- /dev/null +++ libraries/source/spidermonkey/RemoveShellInstall.diff @@ -0,0 +1,10 @@ +--- a/js/src/Makefile.in ++++ b/js/src/Makefile.in +@@ -118,7 +118,6 @@ + + install:: + $(MAKE) -C build install +- $(MAKE) -C shell install + + ifdef HAVE_DTRACE + javascript-trace.h: $(srcdir)/devtools/javascript-trace.d Index: libraries/source/spidermonkey/build.sh =================================================================== --- libraries/source/spidermonkey/build.sh +++ libraries/source/spidermonkey/build.sh @@ -5,7 +5,7 @@ # This should match the version in config/milestone.txt FOLDER="mozjs-78.6.0" # If same-version changes are needed, increment this. -LIB_VERSION="78.6.0+2" +LIB_VERSION="78.6.0+3" LIB_NAME="mozjs78-ps" # Since this script is called by update-workspaces.sh, we want to quickly @@ -25,8 +25,10 @@ if [ "${OS}" = "Windows_NT" ] then MAKE="mozmake" + INSTALL_DIR="../../win32/spidermonkey" else MAKE=${MAKE:="make"} + INSTALL_DIR=$(pwd) fi MAKE_OPTS="${JOBS}" @@ -38,6 +40,7 @@ --disable-js-shell --without-intl-api --enable-shared-js + --prefix=${INSTALL_DIR} --disable-jitspew" if [ "${OS}" = "Windows_NT" ] @@ -98,12 +101,18 @@ download="$(command -v wget || echo "curl -L -o "${FOLDER}.tar.bz2"")" $download "https://github.com/wraitii/spidermonkey-tarballs/releases/download/v78.6.0/${FOLDER}.tar.bz2" fi + + echo "Uncompressing archive..." tar xjf "${FOLDER}.tar.bz2" # Clean up header files that may be left over by earlier versions of SpiderMonkey rm -rf include-unix-debug rm -rf include-unix-release + rm -rf bin + rm -rf include + rm -rf lib + # Apply patches cd "$FOLDER" . ../patch.sh @@ -126,7 +135,7 @@ --enable-debug \ --disable-optimize \ --enable-gczeal - ${MAKE} ${MAKE_OPTS} + ${MAKE} ${MAKE_OPTS} && ${MAKE} install cd .. fi @@ -136,97 +145,50 @@ LLVM_OBJDUMP="${LLVM_OBJDUMP}" \ ${CONF_OPTS} \ --enable-optimize -${MAKE} ${MAKE_OPTS} +${MAKE} ${MAKE_OPTS} && ${MAKE} install cd .. cd .. -if [ "${OS}" = "Windows_NT" ] -then - INCLUDE_DIR_DEBUG=include-win32-debug - INCLUDE_DIR_RELEASE=include-win32-release - LIB_PREFIX= - LIB_SUFFIX=.dll - STATIC_LIB_SUFFIX=.lib -else - INCLUDE_DIR_DEBUG=include-unix-debug - INCLUDE_DIR_RELEASE=include-unix-release - LIB_PREFIX=lib - LIB_SUFFIX=.so - STATIC_LIB_SUFFIX=.a - if [ "`uname -s`" = "OpenBSD" ]; - then - LIB_SUFFIX=.so.1.0 - elif [ "`uname -s`" = "Darwin" ]; - then - LIB_SUFFIX=.a - fi -fi +pyrogenesis_dir="../../../binaries/system/" -if [ "${OS}" = "Windows_NT" ] -then +if [ "${OS}" = "Windows_NT" ]; then # Bug #776126 # SpiderMonkey uses a tweaked zlib when building, and it wrongly copies its own files to include dirs # afterwards, so we have to remove them to not have them conflicting with the regular zlib - pushd "${FOLDER}/build-release/dist/include" + pushd "${INSTALL_DIR}/include/include-win32-release/" rm -f mozzconf.h zconf.h zlib.h popd - pushd "${FOLDER}/build-debug/dist/include" + pushd "${INSTALL_DIR}/include/include-win32-debug/" rm -f mozzconf.h zconf.h zlib.h popd -fi -# Copy files into the necessary locations for building and running the game + # Copy DLLs and debug symbols to binaries/system + cp -L ${INSTALL_DIR}/lib/*.dll ${pyrogenesis_dir} + cp -L ${INSTALL_DIR}/lib/*.pdb ${pyrogenesis_dir} -# js-config.h is different for debug and release builds, so we need different include directories for both -mkdir -p "${INCLUDE_DIR_RELEASE}" -cp -R -L "${FOLDER}"/build-release/dist/include/* "${INCLUDE_DIR_RELEASE}/" + # Windows need some additional libraries for posix emulation. + cp -L ${FOLDER}/build-release/dist/bin/nspr4.dll ${pyrogenesis_dir} + cp -L ${FOLDER}/build-release/dist/bin/plc4.dll ${pyrogenesis_dir} + cp -L ${FOLDER}/build-release/dist/bin/plds4.dll ${pyrogenesis_dir} -if [ "$(uname -s)" != "FreeBSD" ]; then - mkdir -p "${INCLUDE_DIR_DEBUG}" - cp -R -L "${FOLDER}"/build-debug/dist/include/* "${INCLUDE_DIR_DEBUG}/" -fi +else + LIB_SUFFIX=.so + if [ "`uname -s`" = "OpenBSD" ]; then + LIB_SUFFIX=.so.1.0 + fi -# These align the ligns below, making it easier to check for mistakes. -DEB="debug" -REL="release" + # Copy the .pc files to somewhere that pkg-config can find them + cp -L lib/pkgconfig/*.pc $PC_DIR -mkdir -p lib/ + # Create hard links of shared libraries so as to save space, but still allow bundling to be possible (in theory) + if [ "`uname -s`" != "Darwin" ]; then + ln -f lib/*${LIB_SUFFIX} ${pyrogenesis_dir} + fi -# Fetch the jsrust static library. Path is grepped from the build file as it varies by rust toolset. -rust_path=$(grep jsrust < "${FOLDER}/build-release/js/src/build/backend.mk" | cut -d = -f 2 | cut -c2-) -cp -L "${rust_path}" "lib/${LIB_PREFIX}${LIB_NAME}-rust${STATIC_LIB_SUFFIX}" + # Remove a copy of a static library we don't use to save ~650 MiB file space + rm lib/libjs_static.ajs -if [ "`uname -s`" = "Darwin" ] -then - # On MacOS, copy the static libraries only. - cp -L "${FOLDER}/build-${DEB}/js/src/build/${LIB_PREFIX}js_static${LIB_SUFFIX}" "lib/${LIB_PREFIX}${LIB_NAME}-${DEB}${LIB_SUFFIX}" - cp -L "${FOLDER}/build-${REL}/js/src/build/${LIB_PREFIX}js_static${LIB_SUFFIX}" "lib/${LIB_PREFIX}${LIB_NAME}-${REL}${LIB_SUFFIX}" -elif [ "${OS}" = "Windows_NT" ] -then - # Windows needs DLLs to binaries/, static stubs to lib/ and debug symbols - cp -L "${FOLDER}/build-${DEB}/js/src/build/${LIB_PREFIX}${LIB_NAME}-${DEB}${LIB_SUFFIX}" "../../../binaries/system/${LIB_PREFIX}${LIB_NAME}-${DEB}${LIB_SUFFIX}" - cp -L "${FOLDER}/build-${REL}/js/src/build/${LIB_PREFIX}${LIB_NAME}-${REL}${LIB_SUFFIX}" "../../../binaries/system/${LIB_PREFIX}${LIB_NAME}-${REL}${LIB_SUFFIX}" - cp -L "${FOLDER}/build-${DEB}/js/src/build/${LIB_PREFIX}${LIB_NAME}-${DEB}${STATIC_LIB_SUFFIX}" "lib/${LIB_PREFIX}${LIB_NAME}-${DEB}${STATIC_LIB_SUFFIX}" - cp -L "${FOLDER}/build-${REL}/js/src/build/${LIB_PREFIX}${LIB_NAME}-${REL}${STATIC_LIB_SUFFIX}" "lib/${LIB_PREFIX}${LIB_NAME}-${REL}${STATIC_LIB_SUFFIX}" - # Copy debug symbols as well. - cp -L "${FOLDER}/build-${DEB}/js/src/build/${LIB_PREFIX}${LIB_NAME}-${DEB}.pdb" "../../../binaries/system/${LIB_PREFIX}${LIB_NAME}-${DEB}.pdb" - cp -L "${FOLDER}/build-${REL}/js/src/build/${LIB_PREFIX}${LIB_NAME}-${REL}.pdb" "../../../binaries/system/${LIB_PREFIX}${LIB_NAME}-${REL}.pdb" - # Copy the debug jsrust library. - rust_path=$(grep jsrust < "${FOLDER}/build-debug/js/src/build/backend.mk" | cut -d = -f 2 | cut -c2-) - cp -L "${rust_path}" "lib/${LIB_PREFIX}${LIB_NAME}-rust-debug${STATIC_LIB_SUFFIX}" - # Windows need some additional libraries for posix emulation. - cp -L "${FOLDER}/build-release/dist/bin/${LIB_PREFIX}nspr4.dll" "../../../binaries/system/${LIB_PREFIX}nspr4.dll" - cp -L "${FOLDER}/build-release/dist/bin/${LIB_PREFIX}plc4.dll" "../../../binaries/system/${LIB_PREFIX}plc4.dll" - cp -L "${FOLDER}/build-release/dist/bin/${LIB_PREFIX}plds4.dll" "../../../binaries/system/${LIB_PREFIX}plds4.dll" -else - # Copy shared libs to both lib/ and binaries/ so the compiler and executable (resp.) can find them. - cp -L "${FOLDER}/build-${REL}/js/src/build/${LIB_PREFIX}${LIB_NAME}-${REL}${LIB_SUFFIX}" "lib/${LIB_PREFIX}${LIB_NAME}-${REL}${LIB_SUFFIX}" - cp -L "${FOLDER}/build-${REL}/js/src/build/${LIB_PREFIX}${LIB_NAME}-${REL}${LIB_SUFFIX}" "../../../binaries/system/${LIB_PREFIX}${LIB_NAME}-${REL}${LIB_SUFFIX}" - if [ "$(uname -s)" != "FreeBSD" ]; then - cp -L "${FOLDER}/build-${DEB}/js/src/build/${LIB_PREFIX}${LIB_NAME}-${DEB}${LIB_SUFFIX}" "../../../binaries/system/${LIB_PREFIX}${LIB_NAME}-${DEB}${LIB_SUFFIX}" - cp -L "${FOLDER}/build-${DEB}/js/src/build/${LIB_PREFIX}${LIB_NAME}-${DEB}${LIB_SUFFIX}" "lib/${LIB_PREFIX}${LIB_NAME}-${DEB}${LIB_SUFFIX}" - fi fi # Flag that it's already been built successfully so we can skip it next time Index: libraries/source/spidermonkey/include-win32-debug/BaseProfiler.h =================================================================== --- /dev/null +++ libraries/source/spidermonkey/include-win32-debug/BaseProfiler.h @@ -1,1076 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -// The Gecko Profiler is an always-on profiler that takes fast and low overhead -// samples of the program execution using only userspace functionality for -// portability. The goal of this module is to provide performance data in a -// generic cross-platform way without requiring custom tools or kernel support. -// -// Samples are collected to form a timeline with optional timeline event -// (markers) used for filtering. The samples include both native stacks and -// platform-independent "label stack" frames. - -#ifndef BaseProfiler_h -#define BaseProfiler_h - -// This file is safe to include unconditionally, and only defines -// empty macros if MOZ_GECKO_PROFILER is not set. - -// BaseProfilerCounts.h is also safe to include unconditionally, with empty -// macros if MOZ_GECKO_PROFILER is not set. -#include "mozilla/BaseProfilerCounts.h" - -#ifndef MOZ_GECKO_PROFILER - -// This file can be #included unconditionally. However, everything within this -// file must be guarded by a #ifdef MOZ_GECKO_PROFILER, *except* for the -// following macros, which encapsulate the most common operations and thus -// avoid the need for many #ifdefs. - -# define AUTO_BASE_PROFILER_INIT - -# define BASE_PROFILER_REGISTER_THREAD(name) -# define BASE_PROFILER_UNREGISTER_THREAD() -# define AUTO_BASE_PROFILER_REGISTER_THREAD(name) - -# define AUTO_BASE_PROFILER_THREAD_SLEEP -# define AUTO_BASE_PROFILER_THREAD_WAKE - -# define AUTO_BASE_PROFILER_LABEL(label, categoryPair) -# define AUTO_BASE_PROFILER_LABEL_CATEGORY_PAIR(categoryPair) -# define AUTO_BASE_PROFILER_LABEL_DYNAMIC_CSTR(label, categoryPair, cStr) -# define AUTO_BASE_PROFILER_LABEL_DYNAMIC_STRING(label, categoryPair, str) -# define AUTO_BASE_PROFILER_LABEL_FAST(label, categoryPair, ctx) -# define AUTO_BASE_PROFILER_LABEL_DYNAMIC_FAST(label, dynamicString, \ - categoryPair, ctx, flags) - -# define BASE_PROFILER_ADD_MARKER(markerName, categoryPair) -# define BASE_PROFILER_ADD_MARKER_WITH_PAYLOAD( \ - markerName, categoryPair, PayloadType, parenthesizedPayloadArgs) - -# define BASE_PROFILER_TRACING_MARKER(categoryString, markerName, \ - categoryPair, kind) -# define AUTO_BASE_PROFILER_TRACING_MARKER(categoryString, markerName, \ - categoryPair) -# define AUTO_BASE_PROFILER_TEXT_MARKER_CAUSE(markerName, text, categoryPair, \ - cause) - -# define AUTO_PROFILER_STATS(name) - -#else // !MOZ_GECKO_PROFILER - -# include "BaseProfilingStack.h" - -# include "mozilla/Assertions.h" -# include "mozilla/Atomics.h" -# include "mozilla/Attributes.h" -# include "mozilla/GuardObjects.h" -# include "mozilla/Maybe.h" -# include "mozilla/PowerOfTwo.h" -# include "mozilla/Sprintf.h" -# include "mozilla/ThreadLocal.h" -# include "mozilla/TimeStamp.h" -# include "mozilla/UniquePtr.h" - -# include -# include -# include - -namespace mozilla { - -class MallocAllocPolicy; -template -class Vector; - -namespace baseprofiler { - -class ProfilerBacktrace; -class ProfilerMarkerPayload; -class SpliceableJSONWriter; - -// Macros used by the AUTO_PROFILER_* macros below. -# define BASE_PROFILER_RAII_PASTE(id, line) id##line -# define BASE_PROFILER_RAII_EXPAND(id, line) BASE_PROFILER_RAII_PASTE(id, line) -# define BASE_PROFILER_RAII BASE_PROFILER_RAII_EXPAND(raiiObject, __LINE__) - -//--------------------------------------------------------------------------- -// Profiler features -//--------------------------------------------------------------------------- - -// Higher-order macro containing all the feature info in one place. Define -// |MACRO| appropriately to extract the relevant parts. Note that the number -// values are used internally only and so can be changed without consequence. -// Any changes to this list should also be applied to the feature list in -// toolkit/components/extensions/schemas/geckoProfiler.json. -# define BASE_PROFILER_FOR_EACH_FEATURE(MACRO) \ - MACRO(0, "java", Java, "Profile Java code, Android only") \ - \ - MACRO(1, "js", JS, \ - "Get the JS engine to expose the JS stack to the profiler") \ - \ - /* The DevTools profiler doesn't want the native addresses. */ \ - MACRO(2, "leaf", Leaf, "Include the C++ leaf node if not stackwalking") \ - \ - MACRO(3, "mainthreadio", MainThreadIO, "Add main thread file I/O") \ - \ - MACRO(4, "fileio", FileIO, \ - "Add file I/O from all profiled threads, implies mainthreadio") \ - \ - MACRO(5, "fileioall", FileIOAll, \ - "Add file I/O from all threads, implies fileio") \ - \ - MACRO(6, "noiostacks", NoIOStacks, \ - "File I/O markers do not capture stacks, to reduce overhead") \ - \ - MACRO(7, "screenshots", Screenshots, \ - "Take a snapshot of the window on every composition") \ - \ - MACRO(8, "seqstyle", SequentialStyle, \ - "Disable parallel traversal in styling") \ - \ - MACRO(9, "stackwalk", StackWalk, \ - "Walk the C++ stack, not available on all platforms") \ - \ - MACRO(10, "tasktracer", TaskTracer, \ - "Start profiling with feature TaskTracer") \ - \ - MACRO(11, "threads", Threads, "Profile the registered secondary threads") \ - \ - MACRO(12, "jstracer", JSTracer, "Enable tracing of the JavaScript engine") \ - \ - MACRO(13, "jsallocations", JSAllocations, \ - "Have the JavaScript engine track allocations") \ - \ - MACRO(14, "nostacksampling", NoStackSampling, \ - "Disable all stack sampling: Cancels \"js\", \"leaf\", " \ - "\"stackwalk\" and labels") \ - \ - MACRO(15, "preferencereads", PreferenceReads, \ - "Track when preferences are read") \ - \ - MACRO(16, "nativeallocations", NativeAllocations, \ - "Collect the stacks from a smaller subset of all native " \ - "allocations, biasing towards collecting larger allocations") \ - \ - MACRO(17, "ipcmessages", IPCMessages, \ - "Have the IPC layer track cross-process messages") - -struct ProfilerFeature { -# define DECLARE(n_, str_, Name_, desc_) \ - static constexpr uint32_t Name_ = (1u << n_); \ - static constexpr bool Has##Name_(uint32_t aFeatures) { \ - return aFeatures & Name_; \ - } \ - static constexpr void Set##Name_(uint32_t& aFeatures) { \ - aFeatures |= Name_; \ - } \ - static constexpr void Clear##Name_(uint32_t& aFeatures) { \ - aFeatures &= ~Name_; \ - } - - // Define a bitfield constant, a getter, and two setters for each feature. - BASE_PROFILER_FOR_EACH_FEATURE(DECLARE) - -# undef DECLARE -}; - -namespace detail { - -// RacyFeatures is only defined in this header file so that its methods can -// be inlined into profiler_is_active(). Please do not use anything from the -// detail namespace outside the profiler. - -// Within the profiler's code, the preferred way to check profiler activeness -// and features is via ActivePS(). However, that requires locking gPSMutex. -// There are some hot operations where absolute precision isn't required, so we -// duplicate the activeness/feature state in a lock-free manner in this class. -class RacyFeatures { - public: - MFBT_API static void SetActive(uint32_t aFeatures); - - MFBT_API static void SetInactive(); - - MFBT_API static void SetPaused(); - - MFBT_API static void SetUnpaused(); - - MFBT_API static bool IsActive(); - - MFBT_API static bool IsActiveWithFeature(uint32_t aFeature); - - MFBT_API static bool IsActiveAndUnpaused(); - - private: - static constexpr uint32_t Active = 1u << 31; - static constexpr uint32_t Paused = 1u << 30; - -// Ensure Active/Paused don't overlap with any of the feature bits. -# define NO_OVERLAP(n_, str_, Name_, desc_) \ - static_assert(ProfilerFeature::Name_ != Paused, "bad feature value"); - - BASE_PROFILER_FOR_EACH_FEATURE(NO_OVERLAP); - -# undef NO_OVERLAP - - // We combine the active bit with the feature bits so they can be read or - // written in a single atomic operation. - // TODO: Could this be MFBT_DATA for better inlining optimization? - static Atomic sActiveAndFeatures; -}; - -MFBT_API bool IsThreadBeingProfiled(); - -} // namespace detail - -//--------------------------------------------------------------------------- -// Start and stop the profiler -//--------------------------------------------------------------------------- - -static constexpr PowerOfTwo32 BASE_PROFILER_DEFAULT_ENTRIES = -# if !defined(GP_PLAT_arm_android) - MakePowerOfTwo32<1024 * 1024>(); // 1M entries = 8MB -# else - MakePowerOfTwo32<128 * 1024>(); // 128k entries = 1MB -# endif - -// Startup profiling usually need to capture more data, especially on slow -// systems. -static constexpr PowerOfTwo32 BASE_PROFILER_DEFAULT_STARTUP_ENTRIES = -# if !defined(GP_PLAT_arm_android) - MakePowerOfTwo32<4 * 1024 * 1024>(); // 4M entries = 32MB -# else - MakePowerOfTwo32<256 * 1024>(); // 256k entries = 2MB -# endif - -# define BASE_PROFILER_DEFAULT_DURATION 20 -# define BASE_PROFILER_DEFAULT_INTERVAL 1 - -// Initialize the profiler. If MOZ_PROFILER_STARTUP is set the profiler will -// also be started. This call must happen before any other profiler calls -// (except profiler_start(), which will call profiler_init() if it hasn't -// already run). -MFBT_API void profiler_init(void* stackTop); - -# define AUTO_BASE_PROFILER_INIT \ - ::mozilla::baseprofiler::AutoProfilerInit BASE_PROFILER_RAII - -// Clean up the profiler module, stopping it if required. This function may -// also save a shutdown profile if requested. No profiler calls should happen -// after this point and all profiling stack labels should have been popped. -MFBT_API void profiler_shutdown(); - -// Start the profiler -- initializing it first if necessary -- with the -// selected options. Stops and restarts the profiler if it is already active. -// After starting the profiler is "active". The samples will be recorded in a -// circular buffer. -// "aCapacity" is the maximum number of 8-byte entries in the profiler's -// circular buffer. -// "aInterval" the sampling interval, measured in millseconds. -// "aFeatures" is the feature set. Features unsupported by this -// platform/configuration are ignored. -// "aFilters" is the list of thread filters. Threads that do not match any -// of the filters are not profiled. A filter matches a thread if -// (a) the thread name contains the filter as a case-insensitive -// substring, or -// (b) the filter is of the form "pid:" where n is the process -// id of the process that the thread is running in. -// "aDuration" is the duration of entries in the profiler's circular buffer. -MFBT_API void profiler_start(PowerOfTwo32 aCapacity, double aInterval, - uint32_t aFeatures, const char** aFilters, - uint32_t aFilterCount, - const Maybe& aDuration = Nothing()); - -// Stop the profiler and discard the profile without saving it. A no-op if the -// profiler is inactive. After stopping the profiler is "inactive". -MFBT_API void profiler_stop(); - -// If the profiler is inactive, start it. If it's already active, restart it if -// the requested settings differ from the current settings. Both the check and -// the state change are performed while the profiler state is locked. -// The only difference to profiler_start is that the current buffer contents are -// not discarded if the profiler is already running with the requested settings. -MFBT_API void profiler_ensure_started( - PowerOfTwo32 aCapacity, double aInterval, uint32_t aFeatures, - const char** aFilters, uint32_t aFilterCount, - const Maybe& aDuration = Nothing()); - -//--------------------------------------------------------------------------- -// Control the profiler -//--------------------------------------------------------------------------- - -// Register/unregister threads with the profiler. Both functions operate the -// same whether the profiler is active or inactive. -# define BASE_PROFILER_REGISTER_THREAD(name) \ - do { \ - char stackTop; \ - ::mozilla::baseprofiler::profiler_register_thread(name, &stackTop); \ - } while (0) -# define BASE_PROFILER_UNREGISTER_THREAD() \ - ::mozilla::baseprofiler::profiler_unregister_thread() -MFBT_API ProfilingStack* profiler_register_thread(const char* name, - void* guessStackTop); -MFBT_API void profiler_unregister_thread(); - -// Registers a DOM Window (the JS global `window`) with the profiler. Each -// Window _roughly_ corresponds to a single document loaded within a -// BrowsingContext. The unique IDs for both the Window and BrowsingContext are -// recorded to allow correlating different Windows loaded within the same tab or -// frame element. -// -// We register pages for each navigations but we do not register -// history.pushState or history.replaceState since they correspond to the same -// Inner Window ID. When a Browsing context is first loaded, the first url -// loaded in it will be about:blank. Because of that, this call keeps the first -// non-about:blank registration of window and discards the previous one. -// -// "aBrowsingContextID" is the ID of the browsing context that document -// belongs to. That's used to determine the tab of -// that page. -// "aInnerWindowID" is the ID of the `window` global object of that -// document. -// "aUrl" is the URL of the page. -// "aEmbedderInnerWindowID" is the inner window id of embedder. It's used to -// determine sub documents of a page. -MFBT_API void profiler_register_page(uint64_t aBrowsingContextID, - uint64_t aInnerWindowID, - const std::string& aUrl, - uint64_t aEmbedderInnerWindowID); -// Unregister page with the profiler. -// -// Take a Inner Window ID and unregister the page entry that has the same ID. -MFBT_API void profiler_unregister_page(uint64_t aRegisteredInnerWindowID); - -// Remove all registered and unregistered pages in the profiler. -void profiler_clear_all_pages(); - -class BaseProfilerCount; -MFBT_API void profiler_add_sampled_counter(BaseProfilerCount* aCounter); -MFBT_API void profiler_remove_sampled_counter(BaseProfilerCount* aCounter); - -// Register and unregister a thread within a scope. -# define AUTO_BASE_PROFILER_REGISTER_THREAD(name) \ - ::mozilla::baseprofiler::AutoProfilerRegisterThread BASE_PROFILER_RAII(name) - -// Pause and resume the profiler. No-ops if the profiler is inactive. While -// paused the profile will not take any samples and will not record any data -// into its buffers. The profiler remains fully initialized in this state. -// Timeline markers will still be stored. This feature will keep JavaScript -// profiling enabled, thus allowing toggling the profiler without invalidating -// the JIT. -MFBT_API void profiler_pause(); -MFBT_API void profiler_resume(); - -// These functions tell the profiler that a thread went to sleep so that we can -// avoid sampling it while it's sleeping. Calling profiler_thread_sleep() -// twice without an intervening profiler_thread_wake() is an error. All three -// functions operate the same whether the profiler is active or inactive. -MFBT_API void profiler_thread_sleep(); -MFBT_API void profiler_thread_wake(); - -// Mark a thread as asleep/awake within a scope. -# define AUTO_BASE_PROFILER_THREAD_SLEEP \ - ::mozilla::baseprofiler::AutoProfilerThreadSleep BASE_PROFILER_RAII -# define AUTO_BASE_PROFILER_THREAD_WAKE \ - ::mozilla::baseprofiler::AutoProfilerThreadWake BASE_PROFILER_RAII - -//--------------------------------------------------------------------------- -// Get information from the profiler -//--------------------------------------------------------------------------- - -// Is the profiler active? Note: the return value of this function can become -// immediately out-of-date. E.g. the profile might be active but then -// profiler_stop() is called immediately afterward. One common and reasonable -// pattern of usage is the following: -// -// if (profiler_is_active()) { -// ExpensiveData expensiveData = CreateExpensiveData(); -// PROFILER_OPERATION(expensiveData); -// } -// -// where PROFILER_OPERATION is a no-op if the profiler is inactive. In this -// case the profiler_is_active() check is just an optimization -- it prevents -// us calling CreateExpensiveData() unnecessarily in most cases, but the -// expensive data will end up being created but not used if another thread -// stops the profiler between the CreateExpensiveData() and PROFILER_OPERATION -// calls. -inline bool profiler_is_active() { - return baseprofiler::detail::RacyFeatures::IsActive(); -} - -// Same as profiler_is_active(), but with the same extra checks that determine -// if the profiler would currently store markers. So this should be used before -// doing some potentially-expensive work that's used in a marker. E.g.: -// -// if (profiler_can_accept_markers()) { -// ExpensiveMarkerPayload expensivePayload = CreateExpensivePayload(); -// BASE_PROFILER_ADD_MARKER_WITH_PAYLOAD(name, OTHER, expensivePayload); -// } -inline bool profiler_can_accept_markers() { - return baseprofiler::detail::RacyFeatures::IsActiveAndUnpaused(); -} - -// Is the profiler active, and is the current thread being profiled? -// (Same caveats and recommented usage as profiler_is_active().) -inline bool profiler_thread_is_being_profiled() { - return profiler_is_active() && baseprofiler::detail::IsThreadBeingProfiled(); -} - -// Is the profiler active and paused? Returns false if the profiler is inactive. -MFBT_API bool profiler_is_paused(); - -// Is the current thread sleeping? -MFBT_API bool profiler_thread_is_sleeping(); - -// Get all the features supported by the profiler that are accepted by -// profiler_start(). The result is the same whether the profiler is active or -// not. -MFBT_API uint32_t profiler_get_available_features(); - -// Check if a profiler feature (specified via the ProfilerFeature type) is -// active. Returns false if the profiler is inactive. Note: the return value -// can become immediately out-of-date, much like the return value of -// profiler_is_active(). -MFBT_API bool profiler_feature_active(uint32_t aFeature); - -// Get the params used to start the profiler. Returns 0 and an empty vector -// (via outparams) if the profile is inactive. It's possible that the features -// returned may be slightly different to those requested due to required -// adjustments. -MFBT_API void profiler_get_start_params( - int* aEntrySize, Maybe* aDuration, double* aInterval, - uint32_t* aFeatures, Vector* aFilters); - -// The number of milliseconds since the process started. Operates the same -// whether the profiler is active or inactive. -MFBT_API double profiler_time(); - -// Get the current process's ID. -MFBT_API int profiler_current_process_id(); - -// Get the current thread's ID. -MFBT_API int profiler_current_thread_id(); - -// An object of this class is passed to profiler_suspend_and_sample_thread(). -// For each stack frame, one of the Collect methods will be called. -class ProfilerStackCollector { - public: - // Some collectors need to worry about possibly overwriting previous - // generations of data. If that's not an issue, this can return Nothing, - // which is the default behaviour. - virtual Maybe SamplePositionInBuffer() { return Nothing(); } - virtual Maybe BufferRangeStart() { return Nothing(); } - - // This method will be called once if the thread being suspended is the main - // thread. Default behaviour is to do nothing. - virtual void SetIsMainThread() {} - - // WARNING: The target thread is suspended when the Collect methods are - // called. Do not try to allocate or acquire any locks, or you could - // deadlock. The target thread will have resumed by the time this function - // returns. - - virtual void CollectNativeLeafAddr(void* aAddr) = 0; - - virtual void CollectProfilingStackFrame( - const ProfilingStackFrame& aFrame) = 0; -}; - -// This method suspends the thread identified by aThreadId, samples its -// profiling stack, JS stack, and (optionally) native stack, passing the -// collected frames into aCollector. aFeatures dictates which compiler features -// are used. |Leaf| is the only relevant one. -MFBT_API void profiler_suspend_and_sample_thread( - int aThreadId, uint32_t aFeatures, ProfilerStackCollector& aCollector, - bool aSampleNative = true); - -struct ProfilerBacktraceDestructor { - MFBT_API void operator()(ProfilerBacktrace*); -}; - -using UniqueProfilerBacktrace = - UniquePtr; - -// Immediately capture the current thread's call stack and return it. A no-op -// if the profiler is inactive. -MFBT_API UniqueProfilerBacktrace profiler_get_backtrace(); - -struct ProfilerStats { - unsigned n = 0; - double sum = 0; - double min = std::numeric_limits::max(); - double max = 0; - void Count(double v) { - ++n; - sum += v; - if (v < min) { - min = v; - } - if (v > max) { - max = v; - } - } -}; - -struct ProfilerBufferInfo { - // Index of the oldest entry. - uint64_t mRangeStart; - // Index of the newest entry. - uint64_t mRangeEnd; - // Buffer capacity in number of 8-byte entries. - uint32_t mEntryCount; - // Sampling stats: Interval (ns) between successive samplings. - ProfilerStats mIntervalsNs; - // Sampling stats: Total duration (ns) of each sampling. (Split detail below.) - ProfilerStats mOverheadsNs; - // Sampling stats: Time (ns) to acquire the lock before sampling. - ProfilerStats mLockingsNs; - // Sampling stats: Time (ns) to discard expired data. - ProfilerStats mCleaningsNs; - // Sampling stats: Time (ns) to collect counter data. - ProfilerStats mCountersNs; - // Sampling stats: Time (ns) to sample thread stacks. - ProfilerStats mThreadsNs; -}; - -// Get information about the current buffer status. -// Returns Nothing() if the profiler is inactive. -// -// This information may be useful to a user-interface displaying the current -// status of the profiler, allowing the user to get a sense for how fast the -// buffer is being written to, and how much data is visible. -MFBT_API Maybe profiler_get_buffer_info(); - -// Uncomment the following line to display profiler runtime statistics at -// shutdown. -// # define PROFILER_RUNTIME_STATS - -# ifdef PROFILER_RUNTIME_STATS -// This class gathers durations and displays some basic stats when destroyed. -// It is intended to be used as a static variable (see `AUTO_PROFILER_STATS` -// below), to display stats at the end of the program. -class StaticBaseProfilerStats { - public: - explicit StaticBaseProfilerStats(const char* aName) : mName(aName) {} - - ~StaticBaseProfilerStats() { - // Using unsigned long long for computations and printfs. - using ULL = unsigned long long; - ULL n = static_cast(mNumberDurations); - if (n != 0) { - ULL sumNs = static_cast(mSumDurationsNs); - printf( - "[%d] Profiler stats `%s`: %llu ns / %llu = %llu ns, max %llu ns\n", - profiler_current_process_id(), mName, sumNs, n, sumNs / n, - static_cast(mLongestDurationNs)); - } else { - printf("[%d] Profiler stats `%s`: (nothing)\n", - profiler_current_process_id(), mName); - } - } - - void AddDurationFrom(TimeStamp aStart) { - DurationNs duration = static_cast( - (TimeStamp::NowUnfuzzed() - aStart).ToMicroseconds() * 1000 + 0.5); - mSumDurationsNs += duration; - ++mNumberDurations; - // Update mLongestDurationNs if this one is longer. - for (;;) { - DurationNs longest = mLongestDurationNs; - if (MOZ_LIKELY(longest >= duration)) { - // This duration is not the longest, nothing to do. - break; - } - if (MOZ_LIKELY(mLongestDurationNs.compareExchange(longest, duration))) { - // Successfully updated `mLongestDurationNs` with the new value. - break; - } - // Otherwise someone else just updated `mLongestDurationNs`, we need to - // try again by looping. - } - } - - private: - using DurationNs = uint64_t; - using Count = uint32_t; - - Atomic mSumDurationsNs{0}; - Atomic mLongestDurationNs{0}; - Atomic mNumberDurations{0}; - const char* mName; -}; - -// RAII object that measure its scoped lifetime duration and reports it to a -// `StaticBaseProfilerStats`. -class MOZ_RAII AutoProfilerStats { - public: - explicit AutoProfilerStats( - StaticBaseProfilerStats& aStats MOZ_GUARD_OBJECT_NOTIFIER_PARAM) - : mStats(aStats), mStart(TimeStamp::NowUnfuzzed()) { - MOZ_GUARD_OBJECT_NOTIFIER_INIT; - } - - ~AutoProfilerStats() { mStats.AddDurationFrom(mStart); } - - private: - MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER - - StaticBaseProfilerStats& mStats; - TimeStamp mStart; -}; - -// Macro that should be used to collect basic statistics from measurements of -// block durations, from where this macro is, until the end of its enclosing -// scope. The name is used in the static variable name and when displaying stats -// at the end of the program; Another location could use the same name but their -// stats will not be combined, so use different name if these locations should -// be distinguished. -# define AUTO_PROFILER_STATS(name) \ - static ::mozilla::baseprofiler::StaticBaseProfilerStats sStat##name( \ - #name); \ - ::mozilla::baseprofiler::AutoProfilerStats autoStat##name(sStat##name); - -# else // PROFILER_RUNTIME_STATS - -# define AUTO_PROFILER_STATS(name) - -# endif // PROFILER_RUNTIME_STATS else - -//--------------------------------------------------------------------------- -// Put profiling data into the profiler (labels and markers) -//--------------------------------------------------------------------------- - -// Insert an RAII object in this scope to enter a label stack frame. Any -// samples collected in this scope will contain this label in their stack. -// The label argument must be a static C string. It is usually of the -// form "ClassName::FunctionName". (Ideally we'd use the compiler to provide -// that for us, but __func__ gives us the function name without the class -// name.) If the label applies to only part of a function, you can qualify it -// like this: "ClassName::FunctionName:PartName". -// -// Use AUTO_BASE_PROFILER_LABEL_DYNAMIC_* if you want to add additional / -// dynamic information to the label stack frame. -# define AUTO_BASE_PROFILER_LABEL(label, categoryPair) \ - ::mozilla::baseprofiler::AutoProfilerLabel BASE_PROFILER_RAII( \ - label, nullptr, \ - ::mozilla::baseprofiler::ProfilingCategoryPair::categoryPair) - -// Similar to AUTO_BASE_PROFILER_LABEL, but with only one argument: the category -// pair. The label string is taken from the category pair. This is convenient -// for labels like -// AUTO_BASE_PROFILER_LABEL_CATEGORY_PAIR(GRAPHICS_LayerBuilding) which would -// otherwise just repeat the string. -# define AUTO_BASE_PROFILER_LABEL_CATEGORY_PAIR(categoryPair) \ - ::mozilla::baseprofiler::AutoProfilerLabel BASE_PROFILER_RAII( \ - "", nullptr, \ - ::mozilla::baseprofiler::ProfilingCategoryPair::categoryPair, \ - uint32_t(::mozilla::baseprofiler::ProfilingStackFrame::Flags:: \ - LABEL_DETERMINED_BY_CATEGORY_PAIR)) - -// Similar to AUTO_BASE_PROFILER_LABEL, but with an additional string. The -// inserted RAII object stores the cStr pointer in a field; it does not copy the -// string. -// -// WARNING: This means that the string you pass to this macro needs to live at -// least until the end of the current scope. Be careful using this macro with -// ns[C]String; the other AUTO_BASE_PROFILER_LABEL_DYNAMIC_* macros below are -// preferred because they avoid this problem. -// -// If the profiler samples the current thread and walks the label stack while -// this RAII object is on the stack, it will copy the supplied string into the -// profile buffer. So there's one string copy operation, and it happens at -// sample time. -// -// Compare this to the plain AUTO_BASE_PROFILER_LABEL macro, which only accepts -// literal strings: When the label stack frames generated by -// AUTO_BASE_PROFILER_LABEL are sampled, no string copy needs to be made because -// the profile buffer can just store the raw pointers to the literal strings. -// Consequently, AUTO_BASE_PROFILER_LABEL frames take up considerably less space -// in the profile buffer than AUTO_BASE_PROFILER_LABEL_DYNAMIC_* frames. -# define AUTO_BASE_PROFILER_LABEL_DYNAMIC_CSTR(label, categoryPair, cStr) \ - ::mozilla::baseprofiler::AutoProfilerLabel BASE_PROFILER_RAII( \ - label, cStr, \ - ::mozilla::baseprofiler::ProfilingCategoryPair::categoryPair) - -// Similar to AUTO_BASE_PROFILER_LABEL_DYNAMIC_CSTR, but takes an std::string. -// -// Note: The use of the Maybe<>s ensures the scopes for the dynamic string and -// the AutoProfilerLabel are appropriate, while also not incurring the runtime -// cost of the string assignment unless the profiler is active. Therefore, -// unlike AUTO_BASE_PROFILER_LABEL and AUTO_BASE_PROFILER_LABEL_DYNAMIC_CSTR, -// this macro doesn't push/pop a label when the profiler is inactive. -# define AUTO_BASE_PROFILER_LABEL_DYNAMIC_STRING(label, categoryPair, str) \ - Maybe autoStr; \ - Maybe<::mozilla::baseprofiler::AutoProfilerLabel> raiiObjectString; \ - if (::mozilla::baseprofiler::profiler_is_active()) { \ - autoStr.emplace(str); \ - raiiObjectString.emplace( \ - label, autoStr->c_str(), \ - ::mozilla::baseprofiler::ProfilingCategoryPair::categoryPair); \ - } - -// Similar to AUTO_BASE_PROFILER_LABEL, but accepting a JSContext* parameter, -// and a no-op if the profiler is disabled. Used to annotate functions for which -// overhead in the range of nanoseconds is noticeable. It avoids overhead from -// the TLS lookup because it can get the ProfilingStack from the JS context, and -// avoids almost all overhead in the case where the profiler is disabled. -# define AUTO_BASE_PROFILER_LABEL_FAST(label, categoryPair, ctx) \ - ::mozilla::baseprofiler::AutoProfilerLabel BASE_PROFILER_RAII( \ - ctx, label, nullptr, \ - ::mozilla::baseprofiler::ProfilingCategoryPair::categoryPair) - -// Similar to AUTO_BASE_PROFILER_LABEL_FAST, but also takes an extra string and -// an additional set of flags. The flags parameter should carry values from the -// ProfilingStackFrame::Flags enum. -# define AUTO_BASE_PROFILER_LABEL_DYNAMIC_FAST(label, dynamicString, \ - categoryPair, ctx, flags) \ - ::mozilla::baseprofiler::AutoProfilerLabel BASE_PROFILER_RAII( \ - ctx, label, dynamicString, \ - ::mozilla::baseprofiler::ProfilingCategoryPair::categoryPair, flags) - -// Insert a marker in the profile timeline. This is useful to delimit something -// important happening such as the first paint. Unlike labels, which are only -// recorded in the profile buffer if a sample is collected while the label is -// on the label stack, markers will always be recorded in the profile buffer. -// aMarkerName is copied, so the caller does not need to ensure it lives for a -// certain length of time. A no-op if the profiler is inactive. - -# define BASE_PROFILER_ADD_MARKER(markerName, categoryPair) \ - do { \ - AUTO_PROFILER_STATS(base_add_marker); \ - ::mozilla::baseprofiler::profiler_add_marker( \ - markerName, \ - ::mozilla::baseprofiler::ProfilingCategoryPair::categoryPair); \ - } while (false) - -MFBT_API void profiler_add_marker(const char* aMarkerName, - ProfilingCategoryPair aCategoryPair); - -// `PayloadType` is a sub-class of BaseMarkerPayload, `parenthesizedPayloadArgs` -// is the argument list used to construct that `PayloadType`. E.g.: -// `BASE_PROFILER_ADD_MARKER_WITH_PAYLOAD("Load", DOM, TextMarkerPayload, -// ("text", start, end, ds, dsh))` -# define BASE_PROFILER_ADD_MARKER_WITH_PAYLOAD( \ - markerName, categoryPair, PayloadType, parenthesizedPayloadArgs) \ - do { \ - AUTO_PROFILER_STATS(base_add_marker_with_##PayloadType); \ - ::mozilla::baseprofiler::profiler_add_marker( \ - markerName, \ - ::mozilla::baseprofiler::ProfilingCategoryPair::categoryPair, \ - PayloadType parenthesizedPayloadArgs); \ - } while (false) - -MFBT_API void profiler_add_marker(const char* aMarkerName, - ProfilingCategoryPair aCategoryPair, - const ProfilerMarkerPayload& aPayload); - -MFBT_API void profiler_add_js_marker(const char* aMarkerName); - -// Returns true if the profiler lock is currently held *on the current thread*. -// This may be used by re-entrant code that may call profiler functions while -// the profiler already has the lock (which would deadlock). -bool profiler_is_locked_on_current_thread(); - -// Insert a marker in the profile timeline for a specified thread. -MFBT_API void profiler_add_marker_for_thread( - int aThreadId, ProfilingCategoryPair aCategoryPair, const char* aMarkerName, - const ProfilerMarkerPayload& aPayload); - -// Insert a marker in the profile timeline for the main thread. -// This may be used to gather some markers from any thread, that should be -// displayed in the main thread track. -MFBT_API void profiler_add_marker_for_mainthread( - ProfilingCategoryPair aCategoryPair, const char* aMarkerName, - const ProfilerMarkerPayload& aPayload); - -enum TracingKind { - TRACING_EVENT, - TRACING_INTERVAL_START, - TRACING_INTERVAL_END, -}; - -// Adds a tracing marker to the profile. A no-op if the profiler is inactive. - -# define BASE_PROFILER_TRACING_MARKER(categoryString, markerName, \ - categoryPair, kind) \ - ::mozilla::baseprofiler::profiler_tracing_marker( \ - categoryString, markerName, \ - ::mozilla::baseprofiler::ProfilingCategoryPair::categoryPair, kind) - -MFBT_API void profiler_tracing_marker( - const char* aCategoryString, const char* aMarkerName, - ProfilingCategoryPair aCategoryPair, TracingKind aKind, - const Maybe& aInnerWindowID = Nothing()); -MFBT_API void profiler_tracing_marker( - const char* aCategoryString, const char* aMarkerName, - ProfilingCategoryPair aCategoryPair, TracingKind aKind, - UniqueProfilerBacktrace aCause, - const Maybe& aInnerWindowID = Nothing()); - -// Adds a START/END pair of tracing markers. -# define AUTO_BASE_PROFILER_TRACING_MARKER(categoryString, markerName, \ - categoryPair) \ - ::mozilla::baseprofiler::AutoProfilerTracing BASE_PROFILER_RAII( \ - categoryString, markerName, \ - ::mozilla::baseprofiler::ProfilingCategoryPair::categoryPair, \ - Nothing()) - -// Add a text marker. Text markers are similar to tracing markers, with the -// difference that text markers have their "text" separate from the marker name; -// multiple text markers with the same name can have different text, and these -// markers will still be displayed in the same "row" in the UI. -// Another difference is that text markers combine the start and end markers -// into one marker. -MFBT_API void profiler_add_text_marker( - const char* aMarkerName, const std::string& aText, - ProfilingCategoryPair aCategoryPair, const TimeStamp& aStartTime, - const TimeStamp& aEndTime, - const Maybe& aInnerWindowID = Nothing(), - UniqueProfilerBacktrace aCause = nullptr); - -class MOZ_RAII AutoProfilerTextMarker { - public: - AutoProfilerTextMarker(const char* aMarkerName, const std::string& aText, - ProfilingCategoryPair aCategoryPair, - const Maybe& aInnerWindowID, - UniqueProfilerBacktrace&& aCause = - nullptr MOZ_GUARD_OBJECT_NOTIFIER_PARAM) - : mMarkerName(aMarkerName), - mText(aText), - mCategoryPair(aCategoryPair), - mStartTime(TimeStamp::NowUnfuzzed()), - mCause(std::move(aCause)), - mInnerWindowID(aInnerWindowID) { - MOZ_GUARD_OBJECT_NOTIFIER_INIT; - } - - ~AutoProfilerTextMarker() { - profiler_add_text_marker(mMarkerName, mText, mCategoryPair, mStartTime, - TimeStamp::NowUnfuzzed(), mInnerWindowID, - std::move(mCause)); - } - - protected: - MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER - const char* mMarkerName; - std::string mText; - const ProfilingCategoryPair mCategoryPair; - TimeStamp mStartTime; - UniqueProfilerBacktrace mCause; - const Maybe mInnerWindowID; -}; - -# define AUTO_BASE_PROFILER_TEXT_MARKER_CAUSE(markerName, text, categoryPair, \ - cause) \ - ::mozilla::baseprofiler::AutoProfilerTextMarker BASE_PROFILER_RAII( \ - markerName, text, \ - ::mozilla::baseprofiler::ProfilingCategoryPair::categoryPair, \ - mozilla::Nothing(), cause) - -//--------------------------------------------------------------------------- -// Output profiles -//--------------------------------------------------------------------------- - -// Set a user-friendly process name, used in JSON stream. -MFBT_API void profiler_set_process_name(const std::string& aProcessName); - -// Get the profile encoded as a JSON string. A no-op (returning nullptr) if the -// profiler is inactive. -// If aIsShuttingDown is true, the current time is included as the process -// shutdown time in the JSON's "meta" object. -MFBT_API UniquePtr profiler_get_profile(double aSinceTime = 0, - bool aIsShuttingDown = false, - bool aOnlyThreads = false); - -// Write the profile for this process (excluding subprocesses) into aWriter. -// Returns false if the profiler is inactive. -MFBT_API bool profiler_stream_json_for_this_process( - SpliceableJSONWriter& aWriter, double aSinceTime = 0, - bool aIsShuttingDown = false, bool aOnlyThreads = false); - -// Get the profile and write it into a file. A no-op if the profile is -// inactive. -MFBT_API void profiler_save_profile_to_file(const char* aFilename); - -//--------------------------------------------------------------------------- -// RAII classes -//--------------------------------------------------------------------------- - -class MOZ_RAII AutoProfilerInit { - public: - explicit AutoProfilerInit(MOZ_GUARD_OBJECT_NOTIFIER_ONLY_PARAM) { - MOZ_GUARD_OBJECT_NOTIFIER_INIT; - profiler_init(this); - } - - ~AutoProfilerInit() { profiler_shutdown(); } - - private: - MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER -}; - -// Convenience class to register and unregister a thread with the profiler. -// Needs to be the first object on the stack of the thread. -class MOZ_RAII AutoProfilerRegisterThread final { - public: - explicit AutoProfilerRegisterThread( - const char* aName MOZ_GUARD_OBJECT_NOTIFIER_PARAM) { - MOZ_GUARD_OBJECT_NOTIFIER_INIT; - profiler_register_thread(aName, this); - } - - ~AutoProfilerRegisterThread() { profiler_unregister_thread(); } - - private: - AutoProfilerRegisterThread(const AutoProfilerRegisterThread&) = delete; - AutoProfilerRegisterThread& operator=(const AutoProfilerRegisterThread&) = - delete; - MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER -}; - -class MOZ_RAII AutoProfilerThreadSleep { - public: - explicit AutoProfilerThreadSleep(MOZ_GUARD_OBJECT_NOTIFIER_ONLY_PARAM) { - MOZ_GUARD_OBJECT_NOTIFIER_INIT; - profiler_thread_sleep(); - } - - ~AutoProfilerThreadSleep() { profiler_thread_wake(); } - - private: - MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER -}; - -// Temporarily wake up the profiling of a thread while servicing events such as -// Asynchronous Procedure Calls (APCs). -class MOZ_RAII AutoProfilerThreadWake { - public: - explicit AutoProfilerThreadWake(MOZ_GUARD_OBJECT_NOTIFIER_ONLY_PARAM) - : mIssuedWake(profiler_thread_is_sleeping()) { - MOZ_GUARD_OBJECT_NOTIFIER_INIT; - if (mIssuedWake) { - profiler_thread_wake(); - } - } - - ~AutoProfilerThreadWake() { - if (mIssuedWake) { - MOZ_ASSERT(!profiler_thread_is_sleeping()); - profiler_thread_sleep(); - } - } - - private: - MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER - bool mIssuedWake; -}; - -// This class creates a non-owning ProfilingStack reference. Objects of this -// class are stack-allocated, and so exist within a thread, and are thus bounded -// by the lifetime of the thread, which ensures that the references held can't -// be used after the ProfilingStack is destroyed. -class MOZ_RAII AutoProfilerLabel { - public: - // This is the AUTO_BASE_PROFILER_LABEL and AUTO_BASE_PROFILER_LABEL_DYNAMIC - // variant. - AutoProfilerLabel(const char* aLabel, const char* aDynamicString, - ProfilingCategoryPair aCategoryPair, - uint32_t aFlags = 0 MOZ_GUARD_OBJECT_NOTIFIER_PARAM) { - MOZ_GUARD_OBJECT_NOTIFIER_INIT; - - // Get the ProfilingStack from TLS. - Push(GetProfilingStack(), aLabel, aDynamicString, aCategoryPair, aFlags); - } - - void Push(ProfilingStack* aProfilingStack, const char* aLabel, - const char* aDynamicString, ProfilingCategoryPair aCategoryPair, - uint32_t aFlags = 0) { - // This function runs both on and off the main thread. - - mProfilingStack = aProfilingStack; - if (mProfilingStack) { - mProfilingStack->pushLabelFrame(aLabel, aDynamicString, this, - aCategoryPair, aFlags); - } - } - - ~AutoProfilerLabel() { - // This function runs both on and off the main thread. - - if (mProfilingStack) { - mProfilingStack->pop(); - } - } - - MFBT_API static ProfilingStack* GetProfilingStack(); - - private: - MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER - - // We save a ProfilingStack pointer in the ctor so we don't have to redo the - // TLS lookup in the dtor. - ProfilingStack* mProfilingStack; - - public: - // See the comment on the definition in platform.cpp for details about this. - static MOZ_THREAD_LOCAL(ProfilingStack*) sProfilingStack; -}; - -class MOZ_RAII AutoProfilerTracing { - public: - AutoProfilerTracing(const char* aCategoryString, const char* aMarkerName, - ProfilingCategoryPair aCategoryPair, - const Maybe& aInnerWindowID - MOZ_GUARD_OBJECT_NOTIFIER_PARAM) - : mCategoryString(aCategoryString), - mMarkerName(aMarkerName), - mCategoryPair(aCategoryPair), - mInnerWindowID(aInnerWindowID) { - MOZ_GUARD_OBJECT_NOTIFIER_INIT; - profiler_tracing_marker(mCategoryString, mMarkerName, aCategoryPair, - TRACING_INTERVAL_START, mInnerWindowID); - } - - AutoProfilerTracing( - const char* aCategoryString, const char* aMarkerName, - ProfilingCategoryPair aCategoryPair, UniqueProfilerBacktrace aBacktrace, - const Maybe& aInnerWindowID MOZ_GUARD_OBJECT_NOTIFIER_PARAM) - : mCategoryString(aCategoryString), - mMarkerName(aMarkerName), - mCategoryPair(aCategoryPair), - mInnerWindowID(aInnerWindowID) { - MOZ_GUARD_OBJECT_NOTIFIER_INIT; - profiler_tracing_marker(mCategoryString, mMarkerName, aCategoryPair, - TRACING_INTERVAL_START, std::move(aBacktrace), - mInnerWindowID); - } - - ~AutoProfilerTracing() { - profiler_tracing_marker(mCategoryString, mMarkerName, mCategoryPair, - TRACING_INTERVAL_END, mInnerWindowID); - } - - protected: - MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER - const char* mCategoryString; - const char* mMarkerName; - const ProfilingCategoryPair mCategoryPair; - const Maybe mInnerWindowID; -}; - -// Get the MOZ_PROFILER_STARTUP* environment variables that should be -// supplied to a child process that is about to be launched, in order -// to make that child process start with the same profiler settings as -// in the current process. The given function is invoked once for -// each variable to be set. -MFBT_API void GetProfilerEnvVarsForChildProcess( - std::function&& aSetEnv); - -} // namespace baseprofiler -} // namespace mozilla - -#endif // !MOZ_GECKO_PROFILER - -#endif // BaseProfiler_h Index: libraries/source/spidermonkey/include-win32-debug/double-conversion/double-conversion.h =================================================================== --- /dev/null +++ libraries/source/spidermonkey/include-win32-debug/double-conversion/double-conversion.h @@ -1,34 +0,0 @@ -// Copyright 2012 the V8 project authors. All rights reserved. -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following -// disclaimer in the documentation and/or other materials provided -// with the distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived -// from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -#ifndef DOUBLE_CONVERSION_DOUBLE_CONVERSION_H_ -#define DOUBLE_CONVERSION_DOUBLE_CONVERSION_H_ - -#include "string-to-double.h" -#include "double-to-string.h" - -#endif // DOUBLE_CONVERSION_DOUBLE_CONVERSION_H_ Index: libraries/source/spidermonkey/include-win32-debug/double-conversion/double-to-string.h =================================================================== --- /dev/null +++ libraries/source/spidermonkey/include-win32-debug/double-conversion/double-to-string.h @@ -1,398 +0,0 @@ -// Copyright 2012 the V8 project authors. All rights reserved. -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following -// disclaimer in the documentation and/or other materials provided -// with the distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived -// from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -#ifndef DOUBLE_CONVERSION_DOUBLE_TO_STRING_H_ -#define DOUBLE_CONVERSION_DOUBLE_TO_STRING_H_ - -#include "mozilla/Types.h" -#include "utils.h" - -namespace double_conversion { - -class DoubleToStringConverter { - public: - // When calling ToFixed with a double > 10^kMaxFixedDigitsBeforePoint - // or a requested_digits parameter > kMaxFixedDigitsAfterPoint then the - // function returns false. - static const int kMaxFixedDigitsBeforePoint = 60; - static const int kMaxFixedDigitsAfterPoint = 60; - - // When calling ToExponential with a requested_digits - // parameter > kMaxExponentialDigits then the function returns false. - static const int kMaxExponentialDigits = 120; - - // When calling ToPrecision with a requested_digits - // parameter < kMinPrecisionDigits or requested_digits > kMaxPrecisionDigits - // then the function returns false. - static const int kMinPrecisionDigits = 1; - static const int kMaxPrecisionDigits = 120; - - enum Flags { - NO_FLAGS = 0, - EMIT_POSITIVE_EXPONENT_SIGN = 1, - EMIT_TRAILING_DECIMAL_POINT = 2, - EMIT_TRAILING_ZERO_AFTER_POINT = 4, - UNIQUE_ZERO = 8 - }; - - // Flags should be a bit-or combination of the possible Flags-enum. - // - NO_FLAGS: no special flags. - // - EMIT_POSITIVE_EXPONENT_SIGN: when the number is converted into exponent - // form, emits a '+' for positive exponents. Example: 1.2e+2. - // - EMIT_TRAILING_DECIMAL_POINT: when the input number is an integer and is - // converted into decimal format then a trailing decimal point is appended. - // Example: 2345.0 is converted to "2345.". - // - EMIT_TRAILING_ZERO_AFTER_POINT: in addition to a trailing decimal point - // emits a trailing '0'-character. This flag requires the - // EXMIT_TRAILING_DECIMAL_POINT flag. - // Example: 2345.0 is converted to "2345.0". - // - UNIQUE_ZERO: "-0.0" is converted to "0.0". - // - // Infinity symbol and nan_symbol provide the string representation for these - // special values. If the string is NULL and the special value is encountered - // then the conversion functions return false. - // - // The exponent_character is used in exponential representations. It is - // usually 'e' or 'E'. - // - // When converting to the shortest representation the converter will - // represent input numbers in decimal format if they are in the interval - // [10^decimal_in_shortest_low; 10^decimal_in_shortest_high[ - // (lower boundary included, greater boundary excluded). - // Example: with decimal_in_shortest_low = -6 and - // decimal_in_shortest_high = 21: - // ToShortest(0.000001) -> "0.000001" - // ToShortest(0.0000001) -> "1e-7" - // ToShortest(111111111111111111111.0) -> "111111111111111110000" - // ToShortest(100000000000000000000.0) -> "100000000000000000000" - // ToShortest(1111111111111111111111.0) -> "1.1111111111111111e+21" - // - // When converting to precision mode the converter may add - // max_leading_padding_zeroes before returning the number in exponential - // format. - // Example with max_leading_padding_zeroes_in_precision_mode = 6. - // ToPrecision(0.0000012345, 2) -> "0.0000012" - // ToPrecision(0.00000012345, 2) -> "1.2e-7" - // Similarily the converter may add up to - // max_trailing_padding_zeroes_in_precision_mode in precision mode to avoid - // returning an exponential representation. A zero added by the - // EMIT_TRAILING_ZERO_AFTER_POINT flag is counted for this limit. - // Examples for max_trailing_padding_zeroes_in_precision_mode = 1: - // ToPrecision(230.0, 2) -> "230" - // ToPrecision(230.0, 2) -> "230." with EMIT_TRAILING_DECIMAL_POINT. - // ToPrecision(230.0, 2) -> "2.3e2" with EMIT_TRAILING_ZERO_AFTER_POINT. - // - // The min_exponent_width is used for exponential representations. - // The converter adds leading '0's to the exponent until the exponent - // is at least min_exponent_width digits long. - // The min_exponent_width is clamped to 5. - // As such, the exponent may never have more than 5 digits in total. - DoubleToStringConverter(int flags, - const char* infinity_symbol, - const char* nan_symbol, - char exponent_character, - int decimal_in_shortest_low, - int decimal_in_shortest_high, - int max_leading_padding_zeroes_in_precision_mode, - int max_trailing_padding_zeroes_in_precision_mode, - int min_exponent_width = 0) - : flags_(flags), - infinity_symbol_(infinity_symbol), - nan_symbol_(nan_symbol), - exponent_character_(exponent_character), - decimal_in_shortest_low_(decimal_in_shortest_low), - decimal_in_shortest_high_(decimal_in_shortest_high), - max_leading_padding_zeroes_in_precision_mode_( - max_leading_padding_zeroes_in_precision_mode), - max_trailing_padding_zeroes_in_precision_mode_( - max_trailing_padding_zeroes_in_precision_mode), - min_exponent_width_(min_exponent_width) { - // When 'trailing zero after the point' is set, then 'trailing point' - // must be set too. - DOUBLE_CONVERSION_ASSERT(((flags & EMIT_TRAILING_DECIMAL_POINT) != 0) || - !((flags & EMIT_TRAILING_ZERO_AFTER_POINT) != 0)); - } - - // Returns a converter following the EcmaScript specification. - static MFBT_API const DoubleToStringConverter& EcmaScriptConverter(); - - // Computes the shortest string of digits that correctly represent the input - // number. Depending on decimal_in_shortest_low and decimal_in_shortest_high - // (see constructor) it then either returns a decimal representation, or an - // exponential representation. - // Example with decimal_in_shortest_low = -6, - // decimal_in_shortest_high = 21, - // EMIT_POSITIVE_EXPONENT_SIGN activated, and - // EMIT_TRAILING_DECIMAL_POINT deactived: - // ToShortest(0.000001) -> "0.000001" - // ToShortest(0.0000001) -> "1e-7" - // ToShortest(111111111111111111111.0) -> "111111111111111110000" - // ToShortest(100000000000000000000.0) -> "100000000000000000000" - // ToShortest(1111111111111111111111.0) -> "1.1111111111111111e+21" - // - // Note: the conversion may round the output if the returned string - // is accurate enough to uniquely identify the input-number. - // For example the most precise representation of the double 9e59 equals - // "899999999999999918767229449717619953810131273674690656206848", but - // the converter will return the shorter (but still correct) "9e59". - // - // Returns true if the conversion succeeds. The conversion always succeeds - // except when the input value is special and no infinity_symbol or - // nan_symbol has been given to the constructor. - bool ToShortest(double value, StringBuilder* result_builder) const { - return ToShortestIeeeNumber(value, result_builder, SHORTEST); - } - - // Same as ToShortest, but for single-precision floats. - bool ToShortestSingle(float value, StringBuilder* result_builder) const { - return ToShortestIeeeNumber(value, result_builder, SHORTEST_SINGLE); - } - - - // Computes a decimal representation with a fixed number of digits after the - // decimal point. The last emitted digit is rounded. - // - // Examples: - // ToFixed(3.12, 1) -> "3.1" - // ToFixed(3.1415, 3) -> "3.142" - // ToFixed(1234.56789, 4) -> "1234.5679" - // ToFixed(1.23, 5) -> "1.23000" - // ToFixed(0.1, 4) -> "0.1000" - // ToFixed(1e30, 2) -> "1000000000000000019884624838656.00" - // ToFixed(0.1, 30) -> "0.100000000000000005551115123126" - // ToFixed(0.1, 17) -> "0.10000000000000001" - // - // If requested_digits equals 0, then the tail of the result depends on - // the EMIT_TRAILING_DECIMAL_POINT and EMIT_TRAILING_ZERO_AFTER_POINT. - // Examples, for requested_digits == 0, - // let EMIT_TRAILING_DECIMAL_POINT and EMIT_TRAILING_ZERO_AFTER_POINT be - // - false and false: then 123.45 -> 123 - // 0.678 -> 1 - // - true and false: then 123.45 -> 123. - // 0.678 -> 1. - // - true and true: then 123.45 -> 123.0 - // 0.678 -> 1.0 - // - // Returns true if the conversion succeeds. The conversion always succeeds - // except for the following cases: - // - the input value is special and no infinity_symbol or nan_symbol has - // been provided to the constructor, - // - 'value' > 10^kMaxFixedDigitsBeforePoint, or - // - 'requested_digits' > kMaxFixedDigitsAfterPoint. - // The last two conditions imply that the result will never contain more than - // 1 + kMaxFixedDigitsBeforePoint + 1 + kMaxFixedDigitsAfterPoint characters - // (one additional character for the sign, and one for the decimal point). - MFBT_API bool ToFixed(double value, - int requested_digits, - StringBuilder* result_builder) const; - - // Computes a representation in exponential format with requested_digits - // after the decimal point. The last emitted digit is rounded. - // If requested_digits equals -1, then the shortest exponential representation - // is computed. - // - // Examples with EMIT_POSITIVE_EXPONENT_SIGN deactivated, and - // exponent_character set to 'e'. - // ToExponential(3.12, 1) -> "3.1e0" - // ToExponential(5.0, 3) -> "5.000e0" - // ToExponential(0.001, 2) -> "1.00e-3" - // ToExponential(3.1415, -1) -> "3.1415e0" - // ToExponential(3.1415, 4) -> "3.1415e0" - // ToExponential(3.1415, 3) -> "3.142e0" - // ToExponential(123456789000000, 3) -> "1.235e14" - // ToExponential(1000000000000000019884624838656.0, -1) -> "1e30" - // ToExponential(1000000000000000019884624838656.0, 32) -> - // "1.00000000000000001988462483865600e30" - // ToExponential(1234, 0) -> "1e3" - // - // Returns true if the conversion succeeds. The conversion always succeeds - // except for the following cases: - // - the input value is special and no infinity_symbol or nan_symbol has - // been provided to the constructor, - // - 'requested_digits' > kMaxExponentialDigits. - // The last condition implies that the result will never contain more than - // kMaxExponentialDigits + 8 characters (the sign, the digit before the - // decimal point, the decimal point, the exponent character, the - // exponent's sign, and at most 3 exponent digits). - MFBT_API bool ToExponential(double value, - int requested_digits, - StringBuilder* result_builder) const; - - // Computes 'precision' leading digits of the given 'value' and returns them - // either in exponential or decimal format, depending on - // max_{leading|trailing}_padding_zeroes_in_precision_mode (given to the - // constructor). - // The last computed digit is rounded. - // - // Example with max_leading_padding_zeroes_in_precision_mode = 6. - // ToPrecision(0.0000012345, 2) -> "0.0000012" - // ToPrecision(0.00000012345, 2) -> "1.2e-7" - // Similarily the converter may add up to - // max_trailing_padding_zeroes_in_precision_mode in precision mode to avoid - // returning an exponential representation. A zero added by the - // EMIT_TRAILING_ZERO_AFTER_POINT flag is counted for this limit. - // Examples for max_trailing_padding_zeroes_in_precision_mode = 1: - // ToPrecision(230.0, 2) -> "230" - // ToPrecision(230.0, 2) -> "230." with EMIT_TRAILING_DECIMAL_POINT. - // ToPrecision(230.0, 2) -> "2.3e2" with EMIT_TRAILING_ZERO_AFTER_POINT. - // Examples for max_trailing_padding_zeroes_in_precision_mode = 3, and no - // EMIT_TRAILING_ZERO_AFTER_POINT: - // ToPrecision(123450.0, 6) -> "123450" - // ToPrecision(123450.0, 5) -> "123450" - // ToPrecision(123450.0, 4) -> "123500" - // ToPrecision(123450.0, 3) -> "123000" - // ToPrecision(123450.0, 2) -> "1.2e5" - // - // Returns true if the conversion succeeds. The conversion always succeeds - // except for the following cases: - // - the input value is special and no infinity_symbol or nan_symbol has - // been provided to the constructor, - // - precision < kMinPericisionDigits - // - precision > kMaxPrecisionDigits - // The last condition implies that the result will never contain more than - // kMaxPrecisionDigits + 7 characters (the sign, the decimal point, the - // exponent character, the exponent's sign, and at most 3 exponent digits). - MFBT_API bool ToPrecision(double value, - int precision, - bool* used_exponential_notation, - StringBuilder* result_builder) const; - - enum DtoaMode { - // Produce the shortest correct representation. - // For example the output of 0.299999999999999988897 is (the less accurate - // but correct) 0.3. - SHORTEST, - // Same as SHORTEST, but for single-precision floats. - SHORTEST_SINGLE, - // Produce a fixed number of digits after the decimal point. - // For instance fixed(0.1, 4) becomes 0.1000 - // If the input number is big, the output will be big. - FIXED, - // Fixed number of digits (independent of the decimal point). - PRECISION - }; - - // The maximal number of digits that are needed to emit a double in base 10. - // A higher precision can be achieved by using more digits, but the shortest - // accurate representation of any double will never use more digits than - // kBase10MaximalLength. - // Note that DoubleToAscii null-terminates its input. So the given buffer - // should be at least kBase10MaximalLength + 1 characters long. - static const MFBT_DATA int kBase10MaximalLength = 17; - - // Converts the given double 'v' to digit characters. 'v' must not be NaN, - // +Infinity, or -Infinity. In SHORTEST_SINGLE-mode this restriction also - // applies to 'v' after it has been casted to a single-precision float. That - // is, in this mode static_cast(v) must not be NaN, +Infinity or - // -Infinity. - // - // The result should be interpreted as buffer * 10^(point-length). - // - // The digits are written to the buffer in the platform's charset, which is - // often UTF-8 (with ASCII-range digits) but may be another charset, such - // as EBCDIC. - // - // The output depends on the given mode: - // - SHORTEST: produce the least amount of digits for which the internal - // identity requirement is still satisfied. If the digits are printed - // (together with the correct exponent) then reading this number will give - // 'v' again. The buffer will choose the representation that is closest to - // 'v'. If there are two at the same distance, than the one farther away - // from 0 is chosen (halfway cases - ending with 5 - are rounded up). - // In this mode the 'requested_digits' parameter is ignored. - // - SHORTEST_SINGLE: same as SHORTEST but with single-precision. - // - FIXED: produces digits necessary to print a given number with - // 'requested_digits' digits after the decimal point. The produced digits - // might be too short in which case the caller has to fill the remainder - // with '0's. - // Example: toFixed(0.001, 5) is allowed to return buffer="1", point=-2. - // Halfway cases are rounded towards +/-Infinity (away from 0). The call - // toFixed(0.15, 2) thus returns buffer="2", point=0. - // The returned buffer may contain digits that would be truncated from the - // shortest representation of the input. - // - PRECISION: produces 'requested_digits' where the first digit is not '0'. - // Even though the length of produced digits usually equals - // 'requested_digits', the function is allowed to return fewer digits, in - // which case the caller has to fill the missing digits with '0's. - // Halfway cases are again rounded away from 0. - // DoubleToAscii expects the given buffer to be big enough to hold all - // digits and a terminating null-character. In SHORTEST-mode it expects a - // buffer of at least kBase10MaximalLength + 1. In all other modes the - // requested_digits parameter and the padding-zeroes limit the size of the - // output. Don't forget the decimal point, the exponent character and the - // terminating null-character when computing the maximal output size. - // The given length is only used in debug mode to ensure the buffer is big - // enough. - static MFBT_API void DoubleToAscii(double v, - DtoaMode mode, - int requested_digits, - char* buffer, - int buffer_length, - bool* sign, - int* length, - int* point); - - private: - // Implementation for ToShortest and ToShortestSingle. - MFBT_API bool ToShortestIeeeNumber(double value, - StringBuilder* result_builder, - DtoaMode mode) const; - - // If the value is a special value (NaN or Infinity) constructs the - // corresponding string using the configured infinity/nan-symbol. - // If either of them is NULL or the value is not special then the - // function returns false. - MFBT_API bool HandleSpecialValues(double value, StringBuilder* result_builder) const; - // Constructs an exponential representation (i.e. 1.234e56). - // The given exponent assumes a decimal point after the first decimal digit. - MFBT_API void CreateExponentialRepresentation(const char* decimal_digits, - int length, - int exponent, - StringBuilder* result_builder) const; - // Creates a decimal representation (i.e 1234.5678). - MFBT_API void CreateDecimalRepresentation(const char* decimal_digits, - int length, - int decimal_point, - int digits_after_point, - StringBuilder* result_builder) const; - - const int flags_; - const char* const infinity_symbol_; - const char* const nan_symbol_; - const char exponent_character_; - const int decimal_in_shortest_low_; - const int decimal_in_shortest_high_; - const int max_leading_padding_zeroes_in_precision_mode_; - const int max_trailing_padding_zeroes_in_precision_mode_; - const int min_exponent_width_; - - DOUBLE_CONVERSION_DISALLOW_IMPLICIT_CONSTRUCTORS(DoubleToStringConverter); -}; - -} // namespace double_conversion - -#endif // DOUBLE_CONVERSION_DOUBLE_TO_STRING_H_ Index: libraries/source/spidermonkey/include-win32-debug/double-conversion/string-to-double.h =================================================================== --- /dev/null +++ libraries/source/spidermonkey/include-win32-debug/double-conversion/string-to-double.h @@ -1,226 +0,0 @@ -// Copyright 2012 the V8 project authors. All rights reserved. -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following -// disclaimer in the documentation and/or other materials provided -// with the distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived -// from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -#ifndef DOUBLE_CONVERSION_STRING_TO_DOUBLE_H_ -#define DOUBLE_CONVERSION_STRING_TO_DOUBLE_H_ - -#include "utils.h" - -namespace double_conversion { - -class StringToDoubleConverter { - public: - // Enumeration for allowing octals and ignoring junk when converting - // strings to numbers. - enum Flags { - NO_FLAGS = 0, - ALLOW_HEX = 1, - ALLOW_OCTALS = 2, - ALLOW_TRAILING_JUNK = 4, - ALLOW_LEADING_SPACES = 8, - ALLOW_TRAILING_SPACES = 16, - ALLOW_SPACES_AFTER_SIGN = 32, - ALLOW_CASE_INSENSITIVITY = 64, - ALLOW_CASE_INSENSIBILITY = 64, // Deprecated - ALLOW_HEX_FLOATS = 128, - }; - - static const uc16 kNoSeparator = '\0'; - - // Flags should be a bit-or combination of the possible Flags-enum. - // - NO_FLAGS: no special flags. - // - ALLOW_HEX: recognizes the prefix "0x". Hex numbers may only be integers. - // Ex: StringToDouble("0x1234") -> 4660.0 - // In StringToDouble("0x1234.56") the characters ".56" are trailing - // junk. The result of the call is hence dependent on - // the ALLOW_TRAILING_JUNK flag and/or the junk value. - // With this flag "0x" is a junk-string. Even with ALLOW_TRAILING_JUNK, - // the string will not be parsed as "0" followed by junk. - // - // - ALLOW_OCTALS: recognizes the prefix "0" for octals: - // If a sequence of octal digits starts with '0', then the number is - // read as octal integer. Octal numbers may only be integers. - // Ex: StringToDouble("01234") -> 668.0 - // StringToDouble("012349") -> 12349.0 // Not a sequence of octal - // // digits. - // In StringToDouble("01234.56") the characters ".56" are trailing - // junk. The result of the call is hence dependent on - // the ALLOW_TRAILING_JUNK flag and/or the junk value. - // In StringToDouble("01234e56") the characters "e56" are trailing - // junk, too. - // - ALLOW_TRAILING_JUNK: ignore trailing characters that are not part of - // a double literal. - // - ALLOW_LEADING_SPACES: skip over leading whitespace, including spaces, - // new-lines, and tabs. - // - ALLOW_TRAILING_SPACES: ignore trailing whitespace. - // - ALLOW_SPACES_AFTER_SIGN: ignore whitespace after the sign. - // Ex: StringToDouble("- 123.2") -> -123.2. - // StringToDouble("+ 123.2") -> 123.2 - // - ALLOW_CASE_INSENSITIVITY: ignore case of characters for special values: - // infinity and nan. - // - ALLOW_HEX_FLOATS: allows hexadecimal float literals. - // This *must* start with "0x" and separate the exponent with "p". - // Examples: 0x1.2p3 == 9.0 - // 0x10.1p0 == 16.0625 - // ALLOW_HEX and ALLOW_HEX_FLOATS are indendent. - // - // empty_string_value is returned when an empty string is given as input. - // If ALLOW_LEADING_SPACES or ALLOW_TRAILING_SPACES are set, then a string - // containing only spaces is converted to the 'empty_string_value', too. - // - // junk_string_value is returned when - // a) ALLOW_TRAILING_JUNK is not set, and a junk character (a character not - // part of a double-literal) is found. - // b) ALLOW_TRAILING_JUNK is set, but the string does not start with a - // double literal. - // - // infinity_symbol and nan_symbol are strings that are used to detect - // inputs that represent infinity and NaN. They can be null, in which case - // they are ignored. - // The conversion routine first reads any possible signs. Then it compares the - // following character of the input-string with the first character of - // the infinity, and nan-symbol. If either matches, the function assumes, that - // a match has been found, and expects the following input characters to match - // the remaining characters of the special-value symbol. - // This means that the following restrictions apply to special-value symbols: - // - they must not start with signs ('+', or '-'), - // - they must not have the same first character. - // - they must not start with digits. - // - // If the separator character is not kNoSeparator, then that specific - // character is ignored when in between two valid digits of the significant. - // It is not allowed to appear in the exponent. - // It is not allowed to lead or trail the number. - // It is not allowed to appear twice next to each other. - // - // Examples: - // flags = ALLOW_HEX | ALLOW_TRAILING_JUNK, - // empty_string_value = 0.0, - // junk_string_value = NaN, - // infinity_symbol = "infinity", - // nan_symbol = "nan": - // StringToDouble("0x1234") -> 4660.0. - // StringToDouble("0x1234K") -> 4660.0. - // StringToDouble("") -> 0.0 // empty_string_value. - // StringToDouble(" ") -> NaN // junk_string_value. - // StringToDouble(" 1") -> NaN // junk_string_value. - // StringToDouble("0x") -> NaN // junk_string_value. - // StringToDouble("-123.45") -> -123.45. - // StringToDouble("--123.45") -> NaN // junk_string_value. - // StringToDouble("123e45") -> 123e45. - // StringToDouble("123E45") -> 123e45. - // StringToDouble("123e+45") -> 123e45. - // StringToDouble("123E-45") -> 123e-45. - // StringToDouble("123e") -> 123.0 // trailing junk ignored. - // StringToDouble("123e-") -> 123.0 // trailing junk ignored. - // StringToDouble("+NaN") -> NaN // NaN string literal. - // StringToDouble("-infinity") -> -inf. // infinity literal. - // StringToDouble("Infinity") -> NaN // junk_string_value. - // - // flags = ALLOW_OCTAL | ALLOW_LEADING_SPACES, - // empty_string_value = 0.0, - // junk_string_value = NaN, - // infinity_symbol = NULL, - // nan_symbol = NULL: - // StringToDouble("0x1234") -> NaN // junk_string_value. - // StringToDouble("01234") -> 668.0. - // StringToDouble("") -> 0.0 // empty_string_value. - // StringToDouble(" ") -> 0.0 // empty_string_value. - // StringToDouble(" 1") -> 1.0 - // StringToDouble("0x") -> NaN // junk_string_value. - // StringToDouble("0123e45") -> NaN // junk_string_value. - // StringToDouble("01239E45") -> 1239e45. - // StringToDouble("-infinity") -> NaN // junk_string_value. - // StringToDouble("NaN") -> NaN // junk_string_value. - // - // flags = NO_FLAGS, - // separator = ' ': - // StringToDouble("1 2 3 4") -> 1234.0 - // StringToDouble("1 2") -> NaN // junk_string_value - // StringToDouble("1 000 000.0") -> 1000000.0 - // StringToDouble("1.000 000") -> 1.0 - // StringToDouble("1.0e1 000") -> NaN // junk_string_value - StringToDoubleConverter(int flags, - double empty_string_value, - double junk_string_value, - const char* infinity_symbol, - const char* nan_symbol, - uc16 separator = kNoSeparator) - : flags_(flags), - empty_string_value_(empty_string_value), - junk_string_value_(junk_string_value), - infinity_symbol_(infinity_symbol), - nan_symbol_(nan_symbol), - separator_(separator) { - } - - // Performs the conversion. - // The output parameter 'processed_characters_count' is set to the number - // of characters that have been processed to read the number. - // Spaces than are processed with ALLOW_{LEADING|TRAILING}_SPACES are included - // in the 'processed_characters_count'. Trailing junk is never included. - double StringToDouble(const char* buffer, - int length, - int* processed_characters_count) const; - - // Same as StringToDouble above but for 16 bit characters. - double StringToDouble(const uc16* buffer, - int length, - int* processed_characters_count) const; - - // Same as StringToDouble but reads a float. - // Note that this is not equivalent to static_cast(StringToDouble(...)) - // due to potential double-rounding. - float StringToFloat(const char* buffer, - int length, - int* processed_characters_count) const; - - // Same as StringToFloat above but for 16 bit characters. - float StringToFloat(const uc16* buffer, - int length, - int* processed_characters_count) const; - - private: - const int flags_; - const double empty_string_value_; - const double junk_string_value_; - const char* const infinity_symbol_; - const char* const nan_symbol_; - const uc16 separator_; - - template - double StringToIeee(Iterator start_pointer, - int length, - bool read_as_double, - int* processed_characters_count) const; - - DOUBLE_CONVERSION_DISALLOW_IMPLICIT_CONSTRUCTORS(StringToDoubleConverter); -}; - -} // namespace double_conversion - -#endif // DOUBLE_CONVERSION_STRING_TO_DOUBLE_H_ Index: libraries/source/spidermonkey/include-win32-debug/double-conversion/utils.h =================================================================== --- /dev/null +++ libraries/source/spidermonkey/include-win32-debug/double-conversion/utils.h @@ -1,356 +0,0 @@ -// Copyright 2010 the V8 project authors. All rights reserved. -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following -// disclaimer in the documentation and/or other materials provided -// with the distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived -// from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -#ifndef DOUBLE_CONVERSION_UTILS_H_ -#define DOUBLE_CONVERSION_UTILS_H_ - -#include -#include - -#include "mozilla/Assertions.h" -#ifndef DOUBLE_CONVERSION_ASSERT -#define DOUBLE_CONVERSION_ASSERT(condition) \ - MOZ_ASSERT(condition) -#endif -#ifndef DOUBLE_CONVERSION_UNIMPLEMENTED -#define DOUBLE_CONVERSION_UNIMPLEMENTED() MOZ_CRASH() -#endif -#ifndef DOUBLE_CONVERSION_NO_RETURN -#ifdef _MSC_VER -#define DOUBLE_CONVERSION_NO_RETURN __declspec(noreturn) -#else -#define DOUBLE_CONVERSION_NO_RETURN __attribute__((noreturn)) -#endif -#endif -#ifndef DOUBLE_CONVERSION_UNREACHABLE -#ifdef _MSC_VER -void DOUBLE_CONVERSION_NO_RETURN abort_noreturn(); -inline void abort_noreturn() { MOZ_CRASH(); } -#define DOUBLE_CONVERSION_UNREACHABLE() (abort_noreturn()) -#else -#define DOUBLE_CONVERSION_UNREACHABLE() MOZ_CRASH() -#endif -#endif - -#ifndef DOUBLE_CONVERSION_UNUSED -#ifdef __GNUC__ -#define DOUBLE_CONVERSION_UNUSED __attribute__((unused)) -#else -#define DOUBLE_CONVERSION_UNUSED -#endif -#endif - -// Double operations detection based on target architecture. -// Linux uses a 80bit wide floating point stack on x86. This induces double -// rounding, which in turn leads to wrong results. -// An easy way to test if the floating-point operations are correct is to -// evaluate: 89255.0/1e22. If the floating-point stack is 64 bits wide then -// the result is equal to 89255e-22. -// The best way to test this, is to create a division-function and to compare -// the output of the division with the expected result. (Inlining must be -// disabled.) -// On Linux,x86 89255e-22 != Div_double(89255.0/1e22) -// -// For example: -/* -// -- in div.c -double Div_double(double x, double y) { return x / y; } - -// -- in main.c -double Div_double(double x, double y); // Forward declaration. - -int main(int argc, char** argv) { - return Div_double(89255.0, 1e22) == 89255e-22; -} -*/ -// Run as follows ./main || echo "correct" -// -// If it prints "correct" then the architecture should be here, in the "correct" section. -#if defined(_M_X64) || defined(__x86_64__) || \ - defined(__ARMEL__) || defined(__avr32__) || defined(_M_ARM) || defined(_M_ARM64) || \ - defined(__hppa__) || defined(__ia64__) || \ - defined(__mips__) || \ - defined(__powerpc__) || defined(__ppc__) || defined(__ppc64__) || \ - defined(_POWER) || defined(_ARCH_PPC) || defined(_ARCH_PPC64) || \ - defined(__sparc__) || defined(__sparc) || defined(__s390__) || \ - defined(__SH4__) || defined(__alpha__) || \ - defined(_MIPS_ARCH_MIPS32R2) || defined(__ARMEB__) ||\ - defined(__AARCH64EL__) || defined(__aarch64__) || defined(__AARCH64EB__) || \ - defined(__riscv) || defined(__e2k__) || \ - defined(__or1k__) || defined(__arc__) || \ - defined(__EMSCRIPTEN__) -#define DOUBLE_CONVERSION_CORRECT_DOUBLE_OPERATIONS 1 -#elif defined(__mc68000__) || \ - defined(__pnacl__) || defined(__native_client__) -#undef DOUBLE_CONVERSION_CORRECT_DOUBLE_OPERATIONS -#elif defined(_M_IX86) || defined(__i386__) || defined(__i386) -#if defined(_WIN32) -// Windows uses a 64bit wide floating point stack. -#define DOUBLE_CONVERSION_CORRECT_DOUBLE_OPERATIONS 1 -#else -#undef DOUBLE_CONVERSION_CORRECT_DOUBLE_OPERATIONS -#endif // _WIN32 -#else -#error Target architecture was not detected as supported by Double-Conversion. -#endif - -#if defined(_WIN32) && !defined(__MINGW32__) - -typedef signed char int8_t; -typedef unsigned char uint8_t; -typedef short int16_t; // NOLINT -typedef unsigned short uint16_t; // NOLINT -typedef int int32_t; -typedef unsigned int uint32_t; -typedef __int64 int64_t; -typedef unsigned __int64 uint64_t; -// intptr_t and friends are defined in crtdefs.h through stdio.h. - -#else - -#include - -#endif - -typedef uint16_t uc16; - -// The following macro works on both 32 and 64-bit platforms. -// Usage: instead of writing 0x1234567890123456 -// write DOUBLE_CONVERSION_UINT64_2PART_C(0x12345678,90123456); -#define DOUBLE_CONVERSION_UINT64_2PART_C(a, b) (((static_cast(a) << 32) + 0x##b##u)) - - -// The expression DOUBLE_CONVERSION_ARRAY_SIZE(a) is a compile-time constant of type -// size_t which represents the number of elements of the given -// array. You should only use DOUBLE_CONVERSION_ARRAY_SIZE on statically allocated -// arrays. -#ifndef DOUBLE_CONVERSION_ARRAY_SIZE -#define DOUBLE_CONVERSION_ARRAY_SIZE(a) \ - ((sizeof(a) / sizeof(*(a))) / \ - static_cast(!(sizeof(a) % sizeof(*(a))))) -#endif - -// A macro to disallow the evil copy constructor and operator= functions -// This should be used in the private: declarations for a class -#ifndef DOUBLE_CONVERSION_DISALLOW_COPY_AND_ASSIGN -#define DOUBLE_CONVERSION_DISALLOW_COPY_AND_ASSIGN(TypeName) \ - TypeName(const TypeName&); \ - void operator=(const TypeName&) -#endif - -// A macro to disallow all the implicit constructors, namely the -// default constructor, copy constructor and operator= functions. -// -// This should be used in the private: declarations for a class -// that wants to prevent anyone from instantiating it. This is -// especially useful for classes containing only static methods. -#ifndef DOUBLE_CONVERSION_DISALLOW_IMPLICIT_CONSTRUCTORS -#define DOUBLE_CONVERSION_DISALLOW_IMPLICIT_CONSTRUCTORS(TypeName) \ - TypeName(); \ - DOUBLE_CONVERSION_DISALLOW_COPY_AND_ASSIGN(TypeName) -#endif - -namespace double_conversion { - -inline int StrLength(const char* string) { - size_t length = strlen(string); - DOUBLE_CONVERSION_ASSERT(length == static_cast(static_cast(length))); - return static_cast(length); -} - -// This is a simplified version of V8's Vector class. -template -class Vector { - public: - Vector() : start_(NULL), length_(0) {} - Vector(T* data, int len) : start_(data), length_(len) { - DOUBLE_CONVERSION_ASSERT(len == 0 || (len > 0 && data != NULL)); - } - - // Returns a vector using the same backing storage as this one, - // spanning from and including 'from', to but not including 'to'. - Vector SubVector(int from, int to) { - DOUBLE_CONVERSION_ASSERT(to <= length_); - DOUBLE_CONVERSION_ASSERT(from < to); - DOUBLE_CONVERSION_ASSERT(0 <= from); - return Vector(start() + from, to - from); - } - - // Returns the length of the vector. - int length() const { return length_; } - - // Returns whether or not the vector is empty. - bool is_empty() const { return length_ == 0; } - - // Returns the pointer to the start of the data in the vector. - T* start() const { return start_; } - - // Access individual vector elements - checks bounds in debug mode. - T& operator[](int index) const { - DOUBLE_CONVERSION_ASSERT(0 <= index && index < length_); - return start_[index]; - } - - T& first() { return start_[0]; } - - T& last() { return start_[length_ - 1]; } - - void pop_back() { - DOUBLE_CONVERSION_ASSERT(!is_empty()); - --length_; - } - - private: - T* start_; - int length_; -}; - - -// Helper class for building result strings in a character buffer. The -// purpose of the class is to use safe operations that checks the -// buffer bounds on all operations in debug mode. -class StringBuilder { - public: - StringBuilder(char* buffer, int buffer_size) - : buffer_(buffer, buffer_size), position_(0) { } - - ~StringBuilder() { if (!is_finalized()) Finalize(); } - - int size() const { return buffer_.length(); } - - // Get the current position in the builder. - int position() const { - DOUBLE_CONVERSION_ASSERT(!is_finalized()); - return position_; - } - - // Reset the position. - void Reset() { position_ = 0; } - - // Add a single character to the builder. It is not allowed to add - // 0-characters; use the Finalize() method to terminate the string - // instead. - void AddCharacter(char c) { - DOUBLE_CONVERSION_ASSERT(c != '\0'); - DOUBLE_CONVERSION_ASSERT(!is_finalized() && position_ < buffer_.length()); - buffer_[position_++] = c; - } - - // Add an entire string to the builder. Uses strlen() internally to - // compute the length of the input string. - void AddString(const char* s) { - AddSubstring(s, StrLength(s)); - } - - // Add the first 'n' characters of the given string 's' to the - // builder. The input string must have enough characters. - void AddSubstring(const char* s, int n) { - DOUBLE_CONVERSION_ASSERT(!is_finalized() && position_ + n < buffer_.length()); - DOUBLE_CONVERSION_ASSERT(static_cast(n) <= strlen(s)); - memmove(&buffer_[position_], s, n); - position_ += n; - } - - - // Add character padding to the builder. If count is non-positive, - // nothing is added to the builder. - void AddPadding(char c, int count) { - for (int i = 0; i < count; i++) { - AddCharacter(c); - } - } - - // Finalize the string by 0-terminating it and returning the buffer. - char* Finalize() { - DOUBLE_CONVERSION_ASSERT(!is_finalized() && position_ < buffer_.length()); - buffer_[position_] = '\0'; - // Make sure nobody managed to add a 0-character to the - // buffer while building the string. - DOUBLE_CONVERSION_ASSERT(strlen(buffer_.start()) == static_cast(position_)); - position_ = -1; - DOUBLE_CONVERSION_ASSERT(is_finalized()); - return buffer_.start(); - } - - private: - Vector buffer_; - int position_; - - bool is_finalized() const { return position_ < 0; } - - DOUBLE_CONVERSION_DISALLOW_IMPLICIT_CONSTRUCTORS(StringBuilder); -}; - -// The type-based aliasing rule allows the compiler to assume that pointers of -// different types (for some definition of different) never alias each other. -// Thus the following code does not work: -// -// float f = foo(); -// int fbits = *(int*)(&f); -// -// The compiler 'knows' that the int pointer can't refer to f since the types -// don't match, so the compiler may cache f in a register, leaving random data -// in fbits. Using C++ style casts makes no difference, however a pointer to -// char data is assumed to alias any other pointer. This is the 'memcpy -// exception'. -// -// Bit_cast uses the memcpy exception to move the bits from a variable of one -// type of a variable of another type. Of course the end result is likely to -// be implementation dependent. Most compilers (gcc-4.2 and MSVC 2005) -// will completely optimize BitCast away. -// -// There is an additional use for BitCast. -// Recent gccs will warn when they see casts that may result in breakage due to -// the type-based aliasing rule. If you have checked that there is no breakage -// you can use BitCast to cast one pointer type to another. This confuses gcc -// enough that it can no longer see that you have cast one pointer type to -// another thus avoiding the warning. -template -Dest BitCast(const Source& source) { - // Compile time assertion: sizeof(Dest) == sizeof(Source) - // A compile error here means your Dest and Source have different sizes. -#if __cplusplus >= 201103L - static_assert(sizeof(Dest) == sizeof(Source), - "source and destination size mismatch"); -#else - DOUBLE_CONVERSION_UNUSED - typedef char VerifySizesAreEqual[sizeof(Dest) == sizeof(Source) ? 1 : -1]; -#endif - - Dest dest; - memmove(&dest, &source, sizeof(dest)); - return dest; -} - -template -Dest BitCast(Source* source) { - return BitCast(reinterpret_cast(source)); -} - -} // namespace double_conversion - -#endif // DOUBLE_CONVERSION_UTILS_H_ Index: libraries/source/spidermonkey/include-win32-debug/encoding_rs_mem.h =================================================================== --- /dev/null +++ libraries/source/spidermonkey/include-win32-debug/encoding_rs_mem.h @@ -1,704 +0,0 @@ -// Copyright 2015-2016 Mozilla Foundation. See the COPYRIGHT -// file at the top-level directory of this distribution. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -#ifndef encoding_rs_mem_h_ -#define encoding_rs_mem_h_ - -#include -#include -#include - -/* - * _Note:_ "Latin1" in this header refers to the Unicode range from U+0000 to - * U+00FF, inclusive, and does not refer to the windows-1252 range. This - * in-memory encoding is sometimes used as a storage optimization of text - * when UTF-16 indexing and length semantics are exposed. - */ - -/** - * Classification of text as Latin1 (all code points are below U+0100), - * left-to-right with some non-Latin1 characters or as containing at least - * some right-to-left characters. - */ -typedef enum { - /** - * Every character is below U+0100. - */ - Latin1 = 0, - /** - * There is at least one character that's U+0100 or higher, but there - * are no right-to-left characters. - */ - LeftToRight = 1, - /** - * There is at least one right-to-left character. - */ - Bidi = 2, -} Latin1Bidi; - -#ifdef __cplusplus -extern "C" { -#endif // __cplusplus - -/** - * Checks whether a valid UTF-8 buffer contains code points - * that trigger right-to-left processing or is all-Latin1. - * - * Possibly more efficient than performing the checks separately. - * - * Returns `Latin1Bidi::Latin1` if `is_str_latin1()` would return `true`. - * Otherwise, returns `Latin1Bidi::Bidi` if `is_str_bidi()` would return - * `true`. Otherwise, returns `Latin1Bidi::LeftToRight`. - * - * # Undefined behavior - * - * UB ensues if `buffer` and `buffer_len` don't designate a valid memory block, - * if `buffer` is `NULL`, or if the memory designated by `buffer` and - * `buffer_len` does not contain valid UTF-8. (If `buffer_len` is `0`, `buffer` - * may be bogus but still has to be non-`NULL`.) - */ -Latin1Bidi encoding_mem_check_str_for_latin1_and_bidi(const char* buffer, - size_t len); - -/** - * Checks whether a potentially invalid UTF-16 buffer contains code points - * that trigger right-to-left processing or is all-Latin1. - * - * Possibly more efficient than performing the checks separately. - * - * Returns `Latin1Bidi::Latin1` if `is_utf16_latin1()` would return `true`. - * Otherwise, returns `Latin1Bidi::Bidi` if `is_utf16_bidi()` would return - * `true`. Otherwise, returns `Latin1Bidi::LeftToRight`. - * - * # Undefined behavior - * - * UB ensues if `buffer` and `buffer_len` don't designate a valid memory block - * or if `buffer` is `NULL`. (If `buffer_len` is `0`, `buffer` may be bogus but - * still has to be non-`NULL` and aligned.) - */ -Latin1Bidi encoding_mem_check_utf16_for_latin1_and_bidi(const char16_t* buffer, - size_t len); - -/** - * Checks whether a potentially invalid UTF-8 buffer contains code points - * that trigger right-to-left processing or is all-Latin1. - * - * Possibly more efficient than performing the checks separately. - * - * Returns `Latin1Bidi::Latin1` if `is_utf8_latin1()` would return `true`. - * - * Otherwise, returns `Latin1Bidi::Bidi` if `is_utf8_bidi()` would return - * `true`. Otherwise, returns `Latin1Bidi::LeftToRight`. - * - * # Undefined behavior - * - * UB ensues if `buffer` and `buffer_len` don't designate a valid memory block - * or if `buffer` is `NULL`. (If `buffer_len` is `0`, `buffer` may be bogus but - * still has to be non-`NULL`.) - */ -Latin1Bidi encoding_mem_check_utf8_for_latin1_and_bidi(const char* buffer, - size_t len); - -/** - * Converts bytes whose unsigned value is interpreted as Unicode code point - * (i.e. U+0000 to U+00FF, inclusive) to UTF-16. - * - * The length of the destination buffer must be at least the length of the - * source buffer. - * - * The number of `char16_t`s written equals the length of the source buffer. - * - * # Panics - * - * Panics if the destination buffer is shorter than stated above. - * - * # Undefined behavior - * - * UB ensues if `src` and `src_len` don't designate a valid memory block, if - * `src` is `NULL`, if `dst` and `dst_len` don't designate a valid memory - * block, if `dst` is `NULL` or if the two memory blocks overlap. (If - * `src_len` is `0`, `src` may be bogus but still has to be non-`NULL` and - * aligned. Likewise for `dst` and `dst_len`.) - */ -void encoding_mem_convert_latin1_to_utf16(const char* src, size_t src_len, - char16_t* dst, size_t dst_len); - -/** - * Converts bytes whose unsigned value is interpreted as Unicode code point - * (i.e. U+0000 to U+00FF, inclusive) to UTF-8. - * - * The length of the destination buffer must be at least the length of the - * source buffer times two. - * - * Returns the number of bytes written. - * - * # Panics - * - * Panics if the destination buffer is shorter than stated above. - * - * # Safety - * - * Note that this function may write garbage beyond the number of bytes - * indicated by the return value. - * - * # Undefined behavior - * - * UB ensues if `src` and `src_len` don't designate a valid memory block, if - * `src` is `NULL`, if `dst` and `dst_len` don't designate a valid memory - * block, if `dst` is `NULL` or if the two memory blocks overlap. (If - * `src_len` is `0`, `src` may be bogus but still has to be non-`NULL` and - * aligned. Likewise for `dst` and `dst_len`.) - */ -size_t encoding_mem_convert_latin1_to_utf8(const char* src, size_t src_len, - char* dst, size_t dst_len); - -/** - * Converts bytes whose unsigned value is interpreted as Unicode code point - * (i.e. U+0000 to U+00FF, inclusive) to UTF-8 with potentially insufficient - * output space. - * - * Writes the number of code units read into `*src_len` and the number of - * bytes written into `*dst_len`. - * - * If the output isn't large enough, not all input is consumed. - * - * # Undefined behavior - * - * UB ensues if `src` and `src_len` don't designate a valid memory block, if - * `src` is `NULL`, if `dst` and `dst_len` don't designate a valid memory - * block, if `dst` is `NULL` or if the two memory blocks overlap. (If - * `src_len` is `0`, `src` may be bogus but still has to be non-`NULL` and - * aligned. Likewise for `dst` and `dst_len`.) - */ -void encoding_mem_convert_latin1_to_utf8_partial(const char* src, - size_t* src_len, char* dst, - size_t* dst_len); - -/** - * Converts valid UTF-8 to valid UTF-16. - * - * The length of the destination buffer must be at least the length of the - * source buffer. - * - * Returns the number of `char16_t`s written. - * - * # Panics - * - * Panics if the destination buffer is shorter than stated above. - * - * # Undefined behavior - * - * UB ensues if `src` and `src_len` don't designate a valid memory block, if - * `src` is `NULL`, if `dst` and `dst_len` don't designate a valid memory - * block, if `dst` is `NULL`, if the two memory blocks overlap, of if the - * buffer designated by `src` and `src_len` does not contain valid UTF-8. (If - * `src_len` is `0`, `src` may be bogus but still has to be non-`NULL` and - * aligned. Likewise for `dst` and `dst_len`.) - */ -size_t encoding_mem_convert_str_to_utf16(const char* src, size_t src_len, - char16_t* dst, size_t dst_len); - -/** - * If the input is valid UTF-16 representing only Unicode code points from - * U+0000 to U+00FF, inclusive, converts the input into output that - * represents the value of each code point as the unsigned byte value of - * each output byte. - * - * If the input does not fulfill the condition stated above, does something - * that is memory-safe without any promises about any properties of the - * output and will probably assert in debug builds in future versions. - * In particular, callers shouldn't assume the output to be the same across - * crate versions or CPU architectures and should not assume that non-ASCII - * input can't map to ASCII output. - * - * The length of the destination buffer must be at least the length of the - * source buffer. - * - * The number of bytes written equals the length of the source buffer. - * - * # Panics - * - * Panics if the destination buffer is shorter than stated above. - * (Probably in future versions if debug assertions are enabled (and not - * fuzzing) and the input is not in the range U+0000 to U+00FF, inclusive.) - * - * # Undefined behavior - * - * UB ensues if `src` and `src_len` don't designate a valid memory block, if - * `src` is `NULL`, if `dst` and `dst_len` don't designate a valid memory - * block, if `dst` is `NULL` or if the two memory blocks overlap. (If - * `src_len` is `0`, `src` may be bogus but still has to be non-`NULL` and - * aligned. Likewise for `dst` and `dst_len`.) - */ -void encoding_mem_convert_utf16_to_latin1_lossy(const char16_t* src, - size_t src_len, char* dst, - size_t dst_len); - -/** - * Converts potentially-invalid UTF-16 to valid UTF-8 with errors replaced - * with the REPLACEMENT CHARACTER. - * - * The length of the destination buffer must be at least the length of the - * source buffer times three. - * - * Returns the number of bytes written. - * - * # Panics - * - * Panics if the destination buffer is shorter than stated above. - * - * # Undefined behavior - * - * UB ensues if `src` and `src_len` don't designate a valid memory block, if - * `src` is `NULL`, if `dst` and `dst_len` don't designate a valid memory - * block, if `dst` is `NULL` or if the two memory blocks overlap. (If - * `src_len` is `0`, `src` may be bogus but still has to be non-`NULL` and - * aligned. Likewise for `dst` and `dst_len`.) - */ -size_t encoding_mem_convert_utf16_to_utf8(const char16_t* src, size_t src_len, - char* dst, size_t dst_len); - -/** - * Converts potentially-invalid UTF-16 to valid UTF-8 with errors replaced - * with the REPLACEMENT CHARACTER with potentially insufficient output - * space. - * - * Writes the number of code units read into `*src_len` and the number of - * bytes written into `*dst_len`. - * - * Guarantees that the bytes in the destination beyond the number of - * bytes claimed as written by the second item of the return tuple - * are left unmodified. - * - * Not all code units are read if there isn't enough output space. - * Note that this method isn't designed for general streamability but for - * not allocating memory for the worst case up front. Specifically, - * if the input starts with or ends with an unpaired surrogate, those are - * replaced with the REPLACEMENT CHARACTER. - * - * Matches the semantics of `TextEncoder.encodeInto()` from the - * Encoding Standard. - * - * # Undefined behavior - * - * UB ensues if `src` and `src_len` don't designate a valid memory block, if - * `src` is `NULL`, if `dst` and `dst_len` don't designate a valid memory - * block, if `dst` is `NULL` or if the two memory blocks overlap. (If - * `src_len` is `0`, `src` may be bogus but still has to be non-`NULL` and - * aligned. Likewise for `dst` and `dst_len`.) - */ -void encoding_mem_convert_utf16_to_utf8_partial(const char16_t* src, - size_t* src_len, char* dst, - size_t* dst_len); - -/** - * If the input is valid UTF-8 representing only Unicode code points from - * U+0000 to U+00FF, inclusive, converts the input into output that - * represents the value of each code point as the unsigned byte value of - * each output byte. - * - * If the input does not fulfill the condition stated above, this function - * panics if debug assertions are enabled (and fuzzing isn't) and otherwise - * does something that is memory-safe without any promises about any - * properties of the output. In particular, callers shouldn't assume the - * output to be the same across crate versions or CPU architectures and - * should not assume that non-ASCII input can't map to ASCII output. - * The length of the destination buffer must be at least the length of the - * source buffer. - * - * Returns the number of bytes written. - * - * # Panics - * - * Panics if the destination buffer is shorter than stated above. - * If debug assertions are enabled (and not fuzzing) and the input is - * not in the range U+0000 to U+00FF, inclusive. - * - * # Undefined behavior - * - * UB ensues if `src` and `src_len` don't designate a valid memory block, if - * `src` is `NULL`, if `dst` and `dst_len` don't designate a valid memory - * block, if `dst` is `NULL` or if the two memory blocks overlap. (If - * `src_len` is `0`, `src` may be bogus but still has to be non-`NULL` and - * aligned. Likewise for `dst` and `dst_len`.) - */ -size_t encoding_mem_convert_utf8_to_latin1_lossy(const char* src, - size_t src_len, char* dst, - size_t dst_len); - -/** - * Converts potentially-invalid UTF-8 to valid UTF-16 with errors replaced - * with the REPLACEMENT CHARACTER. - * - * The length of the destination buffer must be at least the length of the - * source buffer _plus one_. - * - * Returns the number of `char16_t`s written. - * - * # Panics - * - * Panics if the destination buffer is shorter than stated above. - * - * # Undefined behavior - * - * UB ensues if `src` and `src_len` don't designate a valid memory block, if - * `src` is `NULL`, if `dst` and `dst_len` don't designate a valid memory - * block, if `dst` is `NULL` or if the two memory blocks overlap. (If - * `src_len` is `0`, `src` may be bogus but still has to be non-`NULL` and - * aligned. Likewise for `dst` and `dst_len`.) - */ -size_t encoding_mem_convert_utf8_to_utf16(const char* src, size_t src_len, - char16_t* dst, size_t dst_len); - -/** - * Converts potentially-invalid UTF-8 to valid UTF-16 signaling on error. - * - * The length of the destination buffer must be at least the length of the - * source buffer. - * - * Returns the number of `char16_t`s written or `SIZE_MAX` if the input was - * invalid. - * - * When the input was invalid, some output may have been written. - * - * # Panics - * - * Panics if the destination buffer is shorter than stated above. - * - * # Undefined behavior - * - * UB ensues if `src` and `src_len` don't designate a valid memory block, if - * `src` is `NULL`, if `dst` and `dst_len` don't designate a valid memory - * block, if `dst` is `NULL` or if the two memory blocks overlap. (If - * `src_len` is `0`, `src` may be bogus but still has to be non-`NULL` and - * aligned. Likewise for `dst` and `dst_len`.) - */ -size_t encoding_mem_convert_utf8_to_utf16_without_replacement(const char* src, - size_t src_len, - char16_t* dst, - size_t dst_len); - -/** - * Copies ASCII from source to destination up to the first non-ASCII byte - * (or the end of the input if it is ASCII in its entirety). - * - * The length of the destination buffer must be at least the length of the - * source buffer. - * - * Returns the number of bytes written. - * - * # Panics - * - * Panics if the destination buffer is shorter than stated above. - * - * # Undefined behavior - * - * UB ensues if `src` and `src_len` don't designate a valid memory block, if - * `src` is `NULL`, if `dst` and `dst_len` don't designate a valid memory - * block, if `dst` is `NULL` or if the two memory blocks overlap. (If - * `src_len` is `0`, `src` may be bogus but still has to be non-`NULL` and - * aligned. Likewise for `dst` and `dst_len`.) - */ -size_t encoding_mem_copy_ascii_to_ascii(const char* src, size_t src_len, - char* dst, size_t dst_len); - -/** - * Copies ASCII from source to destination zero-extending it to UTF-16 up to - * the first non-ASCII byte (or the end of the input if it is ASCII in its - * entirety). - * - * The length of the destination buffer must be at least the length of the - * source buffer. - * - * Returns the number of `char16_t`s written. - * - * # Panics - * - * Panics if the destination buffer is shorter than stated above. - * - * # Undefined behavior - * - * UB ensues if `src` and `src_len` don't designate a valid memory block, if - * `src` is `NULL`, if `dst` and `dst_len` don't designate a valid memory - * block, if `dst` is `NULL` or if the two memory blocks overlap. (If - * `src_len` is `0`, `src` may be bogus but still has to be non-`NULL` and - * aligned. Likewise for `dst` and `dst_len`.) - */ -size_t encoding_mem_copy_ascii_to_basic_latin(const char* src, size_t src_len, - char16_t* dst, size_t dst_len); - -/** - * Copies Basic Latin from source to destination narrowing it to ASCII up to - * the first non-Basic Latin code unit (or the end of the input if it is - * Basic Latin in its entirety). - * - * The length of the destination buffer must be at least the length of the - * source buffer. - * - * Returns the number of bytes written. - * - * # Panics - * - * Panics if the destination buffer is shorter than stated above. - * - * # Undefined behavior - * - * UB ensues if `src` and `src_len` don't designate a valid memory block, if - * `src` is `NULL`, if `dst` and `dst_len` don't designate a valid memory - * block, if `dst` is `NULL` or if the two memory blocks overlap. (If - * `src_len` is `0`, `src` may be bogus but still has to be non-`NULL` and - * aligned. Likewise for `dst` and `dst_len`.) - */ -size_t encoding_mem_copy_basic_latin_to_ascii(const char16_t* src, - size_t src_len, char* dst, - size_t dst_len); - -/** - * Replaces unpaired surrogates in the input with the REPLACEMENT CHARACTER. - * - * # Undefined behavior - * - * UB ensues if `buffer` and `buffer_len` don't designate a valid memory block - * or if `buffer` is `NULL`. (If `buffer_len` is `0`, `buffer` may be bogus but - * still has to be non-`NULL` and aligned.) - */ -void encoding_mem_ensure_utf16_validity(char16_t* buffer, size_t len); - -/** - * Checks whether the buffer is all-ASCII. - * - * May read the entire buffer even if it isn't all-ASCII. (I.e. the function - * is not guaranteed to fail fast.) - * - * # Undefined behavior - * - * UB ensues if `buffer` and `buffer_len` don't designate a valid memory block - * or if `buffer` is `NULL`. (If `buffer_len` is `0`, `buffer` may be bogus but - * still has to be non-`NULL`.) - */ -bool encoding_mem_is_ascii(const char* buffer, size_t len); - -/** - * Checks whether the buffer is all-Basic Latin (i.e. UTF-16 representing - * only ASCII characters). - * - * May read the entire buffer even if it isn't all-ASCII. (I.e. the function - * is not guaranteed to fail fast.) - * - * # Undefined behavior - * - * UB ensues if `buffer` and `buffer_len` don't designate a valid memory block - * or if `buffer` is `NULL`. (If `buffer_len` is `0`, `buffer` may be bogus but - * still has to be non-`NULL` and aligned.) - */ -bool encoding_mem_is_basic_latin(const char16_t* buffer, size_t len); - -/** - * Checks whether a scalar value triggers right-to-left processing. - * - * The check is done on a Unicode block basis without regard to assigned - * vs. unassigned code points in the block. Hebrew presentation forms in - * the Alphabetic Presentation Forms block are treated as if they formed - * a block on their own (i.e. it treated as right-to-left). Additionally, - * the four RIGHT-TO-LEFT FOO controls in General Punctuation are checked - * for. Control characters that are technically bidi controls but do not - * cause right-to-left behavior without the presence of right-to-left - * characters or right-to-left controls are not checked for. As a special - * case, U+FEFF is excluded from Arabic Presentation Forms-B. - * - * # Undefined behavior - * - * Undefined behavior ensues if `c` is not a valid Unicode Scalar Value. - */ -bool encoding_mem_is_char_bidi(char32_t c); - -/** - * Checks whether a valid UTF-8 buffer contains code points that trigger - * right-to-left processing. - * - * The check is done on a Unicode block basis without regard to assigned - * vs. unassigned code points in the block. Hebrew presentation forms in - * the Alphabetic Presentation Forms block are treated as if they formed - * a block on their own (i.e. it treated as right-to-left). Additionally, - * the four RIGHT-TO-LEFT FOO controls in General Punctuation are checked - * for. Control characters that are technically bidi controls but do not - * cause right-to-left behavior without the presence of right-to-left - * characters or right-to-left controls are not checked for. As a special - * case, U+FEFF is excluded from Arabic Presentation Forms-B. - * - * # Undefined behavior - * - * UB ensues if `buffer` and `buffer_len` don't designate a valid memory block, - * if `buffer` is `NULL`, or if the memory designated by `buffer` and - * `buffer_len` does not contain valid UTF-8. (If `buffer_len` is `0`, `buffer` - * may be bogus but still has to be non-`NULL`.) - */ -bool encoding_mem_is_str_bidi(const char* buffer, size_t len); - -/** - * Checks whether the buffer represents only code points less than or equal - * to U+00FF. - * - * Fails fast. (I.e. returns before having read the whole buffer if code - * points above U+00FF are discovered. - * - * # Undefined behavior - * - * UB ensues if `buffer` and `buffer_len` don't designate a valid memory block, - * if `buffer` is `NULL`, or if the memory designated by `buffer` and - * `buffer_len` does not contain valid UTF-8. (If `buffer_len` is `0`, `buffer` - * may be bogus but still has to be non-`NULL`.) - */ -bool encoding_mem_is_str_latin1(const char* buffer, size_t len); - -/** - * Checks whether a UTF-16 buffer contains code points that trigger - * right-to-left processing. - * - * The check is done on a Unicode block basis without regard to assigned - * vs. unassigned code points in the block. Hebrew presentation forms in - * the Alphabetic Presentation Forms block are treated as if they formed - * a block on their own (i.e. it treated as right-to-left). Additionally, - * the four RIGHT-TO-LEFT FOO controls in General Punctuation are checked - * for. Control characters that are technically bidi controls but do not - * cause right-to-left behavior without the presence of right-to-left - * characters or right-to-left controls are not checked for. As a special - * case, U+FEFF is excluded from Arabic Presentation Forms-B. - * Returns `true` if the input contains an RTL character or an unpaired - * high surrogate that could be the high half of an RTL character. - * Returns `false` if the input contains neither RTL characters nor - * unpaired high surrogates that could be higher halves of RTL characters. - * - * # Undefined behavior - * - * UB ensues if `buffer` and `buffer_len` don't designate a valid memory block - * or if `buffer` is `NULL`. (If `buffer_len` is `0`, `buffer` may be bogus but - * still has to be non-`NULL` and aligned.) - */ -bool encoding_mem_is_utf16_bidi(const char16_t* buffer, size_t len); - -/** - * Checks whether a UTF-16 code unit triggers right-to-left processing. - * - * The check is done on a Unicode block basis without regard to assigned - * vs. unassigned code points in the block. Hebrew presentation forms in - * the Alphabetic Presentation Forms block are treated as if they formed - * a block on their own (i.e. it treated as right-to-left). Additionally, - * the four RIGHT-TO-LEFT FOO controls in General Punctuation are checked - * for. Control characters that are technically bidi controls but do not - * cause right-to-left behavior without the presence of right-to-left - * characters or right-to-left controls are not checked for. As a special - * case, U+FEFF is excluded from Arabic Presentation Forms-B. - * Since supplementary-plane right-to-left blocks are identifiable from the - * high surrogate without examining the low surrogate, this function returns - * `true` for such high surrogates making the function suitable for handling - * supplementary-plane text without decoding surrogate pairs to scalar - * values. Obviously, such high surrogates are then reported as right-to-left - * even if actually unpaired. - */ -bool encoding_mem_is_utf16_code_unit_bidi(char16_t u); - -/** - * Checks whether the buffer represents only code point less than or equal - * to U+00FF. - * - * May read the entire buffer even if it isn't all-Latin1. (I.e. the function - * is not guaranteed to fail fast.) - * - * # Undefined behavior - * - * UB ensues if `buffer` and `buffer_len` don't designate a valid memory block - * or if `buffer` is `NULL`. (If `buffer_len` is `0`, `buffer` may be bogus but - * still has to be non-`NULL` and aligned.) - */ -bool encoding_mem_is_utf16_latin1(const char16_t* buffer, size_t len); - -/** - * Checks whether a potentially-invalid UTF-8 buffer contains code points - * that trigger right-to-left processing. - * - * The check is done on a Unicode block basis without regard to assigned - * vs. unassigned code points in the block. Hebrew presentation forms in - * the Alphabetic Presentation Forms block are treated as if they formed - * a block on their own (i.e. it treated as right-to-left). Additionally, - * the four RIGHT-TO-LEFT FOO controls in General Punctuation are checked - * for. Control characters that are technically bidi controls but do not - * cause right-to-left behavior without the presence of right-to-left - * characters or right-to-left controls are not checked for. As a special - * case, U+FEFF is excluded from Arabic Presentation Forms-B. - * Returns `true` if the input is invalid UTF-8 or the input contains an - * RTL character. Returns `false` if the input is valid UTF-8 and contains - * no RTL characters. - * - * # Undefined behavior - * - * UB ensues if `buffer` and `buffer_len` don't designate a valid memory block - * or if `buffer` is `NULL`. (If `buffer_len` is `0`, `buffer` may be bogus but - * still has to be non-`NULL`.) - */ -bool encoding_mem_is_utf8_bidi(const char* buffer, size_t len); - -/** - * Checks whether the buffer is valid UTF-8 representing only code points - * less than or equal to U+00FF. - * - * Fails fast. (I.e. returns before having read the whole buffer if UTF-8 - * invalidity or code points above U+00FF are discovered. - * - * # Undefined behavior - * - * UB ensues if `buffer` and `buffer_len` don't designate a valid memory block - * or if `buffer` is `NULL`. (If `buffer_len` is `0`, `buffer` may be bogus but - * still has to be non-`NULL`.) - */ -bool encoding_mem_is_utf8_latin1(const char* buffer, size_t len); - -/** - * Returns the index of the first unpaired surrogate or, if the input is - * valid UTF-16 in its entirety, the length of the input. - * - * # Undefined behavior - * - * UB ensues if `buffer` and `buffer_len` don't designate a valid memory block - * or if `buffer` is `NULL`. (If `buffer_len` is `0`, `buffer` may be bogus but - * still has to be non-`NULL` and aligned.) - */ -size_t encoding_mem_utf16_valid_up_to(const char16_t* buffer, size_t len); - -/** - * Returns the index of first byte that starts an invalid byte - * sequence or a non-Latin1 byte sequence, or the length of the - * string if there are neither. - * - * # Undefined behavior - * - * UB ensues if `buffer` and `buffer_len` don't designate a valid memory block - * or if `buffer` is `NULL`. (If `buffer_len` is `0`, `buffer` may be bogus but - * still has to be non-`NULL` and aligned.) - */ -size_t encoding_mem_utf8_latin1_up_to(const char* buffer, size_t len); - -/** - * Returns the index of first byte that starts a non-Latin1 byte - * sequence, or the length of the string if there are none. - * - * # Undefined behavior - * - * UB ensues if `buffer` and `buffer_len` don't designate a valid memory block, - * if `buffer` is `NULL`, or if the memory block does not contain valid UTF-8. - * (If `buffer_len` is `0`, `buffer` may be bogus but still has to be non-`NULL` - * and aligned.) - */ -size_t encoding_mem_str_latin1_up_to(const char* buffer, size_t len); - -#ifdef __cplusplus -} // extern "C" -#endif // __cplusplus - -#endif // encoding_rs_mem_h_ Index: libraries/source/spidermonkey/include-win32-debug/fdlibm.h =================================================================== --- /dev/null +++ libraries/source/spidermonkey/include-win32-debug/fdlibm.h @@ -1,64 +0,0 @@ -/* - * ==================================================== - * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. - * - * Developed at SunPro, a Sun Microsystems, Inc. business. - * Permission to use, copy, modify, and distribute this - * software is freely granted, provided that this notice - * is preserved. - * ==================================================== - */ - -/* - * from: @(#)fdlibm.h 5.1 93/09/24 - * $FreeBSD$ - */ - -#ifndef mozilla_imported_fdlibm_h -#define mozilla_imported_fdlibm_h - -namespace fdlibm { - -double acos(double); -double asin(double); -double atan(double); -double atan2(double, double); - -double cosh(double); -double sinh(double); -double tanh(double); - -double exp(double); -double log(double); -double log10(double); - -double pow(double, double); -double fabs(double); - -double floor(double); -double trunc(double); -double ceil(double); - -double acosh(double); -double asinh(double); -double atanh(double); -double cbrt(double); -double expm1(double); -double hypot(double, double); -double log1p(double); -double log2(double); -double rint(double); -double copysign(double, double); -double nearbyint(double); -double scalbn(double, int); - -float ceilf(float); -float floorf(float); - -float nearbyintf(float); -float rintf(float); -float truncf(float); - -} /* namespace fdlibm */ - -#endif /* mozilla_imported_fdlibm_h */ Index: libraries/source/spidermonkey/include-win32-debug/js-config.h =================================================================== --- /dev/null +++ libraries/source/spidermonkey/include-win32-debug/js-config.h @@ -1,68 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=8 sw=4 et tw=78: - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef js_config_h -#define js_config_h - -/* Definitions set at build time that affect SpiderMonkey's public API. - This header file is generated by the SpiderMonkey configure script, - and installed along with jsapi.h. */ - -/* Define to 1 if SpiderMonkey is in debug mode. */ -#define JS_DEBUG 1 - -/* - * NB: We have a special case for rust-bindgen, which wants to be able to - * generate both debug and release bindings on a single objdir. - */ -#ifdef JS_DEBUG -#if !defined(DEBUG) && !defined(RUST_BINDGEN) -# error "SpiderMonkey was configured with --enable-debug, so DEBUG must be defined when including this header" -# endif -#else -# if defined(DEBUG) && !defined(RUST_BINDGEN) -# error "SpiderMonkey was configured with --disable-debug, so DEBUG must be not defined when including this header" -# endif -#endif - -/* Define to 1 if SpiderMonkey should include ctypes support. */ -/* #undef JS_HAS_CTYPES */ - -/* Define to 1 if SpiderMonkey should include trace logging support. */ -/* #undef JS_TRACE_LOGGING */ - -/* Define to 1 if SpiderMonkey should include typed objects support. */ -/* #undef JS_HAS_TYPED_OBJECTS */ - -/* Define to 1 if SpiderMonkey should include support for the Intl API. */ -/* #undef JS_HAS_INTL_API */ - -/* Define to 1 if SpiderMonkey should include a breakpoint function for - * artificial OOMs. */ -/* #undef JS_OOM_BREAKPOINT */ - -/* Define to 1 if SpiderMonkey should support the ability to perform - entirely too much GC. */ -#define JS_GC_ZEAL 1 - -/* Define to 1 if SpiderMonkey should use small chunks. */ -/* #undef JS_GC_SMALL_CHUNK_SIZE */ - -/* Define to 1 to perform extra assertions and heap poisoning. */ -/* #undef JS_CRASH_DIAGNOSTICS */ - -/* Define to 1 if SpiderMonkey is in NUNBOX32 mode. */ -#define JS_NUNBOX32 1 - -/* Define to 1 if SpiderMonkey is in PUNBOX64 mode. */ -/* #undef JS_PUNBOX64 */ - -/* MOZILLA JSAPI version number components */ -#define MOZJS_MAJOR_VERSION 78 -#define MOZJS_MINOR_VERSION 6 - -#endif /* js_config_h */ Index: libraries/source/spidermonkey/include-win32-debug/js.msg =================================================================== --- /dev/null +++ libraries/source/spidermonkey/include-win32-debug/js.msg @@ -1,750 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* - * This is the JavaScript error message file. - * - * The format for each JS error message is: - * - * MSG_DEF(, , , - * ) - * - * where ; - * is a legal C identifer that will be used in the - * JS engine source. - * - * is an integer literal specifying the total number of - * replaceable arguments in the following format string. - * - * is an enum JSExnType value, defined in jsapi.h. - * - * is a string literal, optionally containing sequences - * {X} where X is an integer representing the argument number that will - * be replaced with a string value when the error is reported. - * - * e.g. - * - * MSG_DEF(JSMSG_NOT_A_SUBSPECIES, 2, JSEXN_TYPEERROR, - * "{0} is not a member of the {1} family") - * - * can be used: - * - * JS_ReportErrorNumberASCII(JSMSG_NOT_A_SUBSPECIES, "Rhino", "Monkey"); - * - * to report: - * - * "TypeError: Rhino is not a member of the Monkey family" - */ - -MSG_DEF(JSMSG_NOT_AN_ERROR, 0, JSEXN_ERR, "") -MSG_DEF(JSMSG_NOT_DEFINED, 1, JSEXN_REFERENCEERR, "{0} is not defined") -MSG_DEF(JSMSG_MORE_ARGS_NEEDED, 4, JSEXN_TYPEERR, "{0}: At least {1} argument{2} required, but only {3} passed") -MSG_DEF(JSMSG_INCOMPATIBLE_PROTO, 3, JSEXN_TYPEERR, "{0}.prototype.{1} called on incompatible {2}") -MSG_DEF(JSMSG_NO_CONSTRUCTOR, 1, JSEXN_TYPEERR, "{0} has no constructor") -MSG_DEF(JSMSG_BAD_SORT_ARG, 0, JSEXN_TYPEERR, "invalid Array.prototype.sort argument") -MSG_DEF(JSMSG_READ_ONLY, 1, JSEXN_TYPEERR, "{0} is read-only") -MSG_DEF(JSMSG_CANT_DELETE, 1, JSEXN_TYPEERR, "property {0} is non-configurable and can't be deleted") -MSG_DEF(JSMSG_CANT_TRUNCATE_ARRAY, 0, JSEXN_TYPEERR, "can't delete non-configurable array element") -MSG_DEF(JSMSG_NOT_FUNCTION, 1, JSEXN_TYPEERR, "{0} is not a function") -MSG_DEF(JSMSG_NOT_CONSTRUCTOR, 1, JSEXN_TYPEERR, "{0} is not a constructor") -MSG_DEF(JSMSG_BOGUS_CONSTRUCTOR, 1, JSEXN_TYPEERR, "{0} constructor can't be used directly") -MSG_DEF(JSMSG_CANT_CONVERT_TO, 2, JSEXN_TYPEERR, "can't convert {0} to {1}") -MSG_DEF(JSMSG_TOPRIMITIVE_NOT_CALLABLE, 2, JSEXN_TYPEERR, "can't convert {0} to {1}: its [Symbol.toPrimitive] property is not a function") -MSG_DEF(JSMSG_TOPRIMITIVE_RETURNED_OBJECT, 2, JSEXN_TYPEERR, "can't convert {0} to {1}: its [Symbol.toPrimitive] method returned an object") -MSG_DEF(JSMSG_NO_PROPERTIES, 1, JSEXN_TYPEERR, "{0} has no properties") -MSG_DEF(JSMSG_PROPERTY_FAIL, 2, JSEXN_TYPEERR, "can't access property {0} of {1}") -MSG_DEF(JSMSG_PROPERTY_FAIL_EXPR, 3, JSEXN_TYPEERR, "can't access property {0}, {1} is {2}") -MSG_DEF(JSMSG_BAD_REGEXP_FLAG, 1, JSEXN_SYNTAXERR, "invalid regular expression flag {0}") -MSG_DEF(JSMSG_INVALID_DATA_VIEW_LENGTH, 0, JSEXN_RANGEERR, "invalid data view length") -MSG_DEF(JSMSG_OFFSET_LARGER_THAN_FILESIZE, 0, JSEXN_RANGEERR, "offset is larger than filesize") -MSG_DEF(JSMSG_OFFSET_OUT_OF_BUFFER, 0, JSEXN_RANGEERR, "start offset is outside the bounds of the buffer") -MSG_DEF(JSMSG_OFFSET_OUT_OF_DATAVIEW, 0, JSEXN_RANGEERR, "offset is outside the bounds of the DataView") -MSG_DEF(JSMSG_SPREAD_TOO_LARGE, 0, JSEXN_RANGEERR, "array too large due to spread operand(s)") -MSG_DEF(JSMSG_BAD_WEAKMAP_KEY, 0, JSEXN_TYPEERR, "cannot use the given object as a weak map key") -MSG_DEF(JSMSG_BAD_GETTER_OR_SETTER, 1, JSEXN_TYPEERR, "invalid {0} usage") -MSG_DEF(JSMSG_BAD_ARRAY_LENGTH, 0, JSEXN_RANGEERR, "invalid array length") -MSG_DEF(JSMSG_SOURCE_ARRAY_TOO_LONG, 0, JSEXN_RANGEERR, "source array is too long") -MSG_DEF(JSMSG_REDECLARED_PREV, 2, JSEXN_NOTE, "Previously declared at line {0}, column {1}") -MSG_DEF(JSMSG_REDECLARED_VAR, 2, JSEXN_SYNTAXERR, "redeclaration of {0} {1}") -MSG_DEF(JSMSG_UNDECLARED_VAR, 1, JSEXN_REFERENCEERR, "assignment to undeclared variable {0}") -MSG_DEF(JSMSG_GETTER_ONLY, 1, JSEXN_TYPEERR, "setting getter-only property {0}") -MSG_DEF(JSMSG_OVERWRITING_ACCESSOR, 1, JSEXN_TYPEERR, "can't overwrite accessor property {0}") -MSG_DEF(JSMSG_INVALID_MAP_ITERABLE, 1, JSEXN_TYPEERR, "iterable for {0} should have array-like objects") -MSG_DEF(JSMSG_NESTING_GENERATOR, 0, JSEXN_TYPEERR, "already executing generator") -MSG_DEF(JSMSG_INCOMPATIBLE_METHOD, 3, JSEXN_TYPEERR, "{0} {1} called on incompatible {2}") -MSG_DEF(JSMSG_BAD_SURROGATE_CHAR, 1, JSEXN_TYPEERR, "bad surrogate character {0}") -MSG_DEF(JSMSG_UTF8_CHAR_TOO_LARGE, 1, JSEXN_TYPEERR, "UTF-8 character {0} too large") -MSG_DEF(JSMSG_MALFORMED_UTF8_CHAR, 1, JSEXN_TYPEERR, "malformed UTF-8 character sequence at offset {0}") -MSG_DEF(JSMSG_BUILTIN_CTOR_NO_NEW, 1, JSEXN_TYPEERR, "calling a builtin {0} constructor without new is forbidden") -MSG_DEF(JSMSG_EMPTY_ARRAY_REDUCE, 0, JSEXN_TYPEERR, "reduce of empty array with no initial value") -MSG_DEF(JSMSG_UNEXPECTED_TYPE, 2, JSEXN_TYPEERR, "{0} is {1}") -MSG_DEF(JSMSG_MISSING_FUN_ARG, 2, JSEXN_TYPEERR, "missing argument {0} when calling function {1}") -MSG_DEF(JSMSG_OBJECT_REQUIRED, 1, JSEXN_TYPEERR, "{0} is not a non-null object") -MSG_DEF(JSMSG_OBJECT_REQUIRED_ARG, 3, JSEXN_TYPEERR, "{0} argument of {1} must be an object, got {2}") -MSG_DEF(JSMSG_OBJECT_REQUIRED_WEAKMAP_KEY, 1, JSEXN_TYPEERR, "WeakMap key must be an object, got {0}") -MSG_DEF(JSMSG_OBJECT_REQUIRED_WEAKSET_VAL, 1, JSEXN_TYPEERR, "WeakSet value must be an object, got {0}") -MSG_DEF(JSMSG_OBJECT_REQUIRED_PROP_DESC, 1, JSEXN_TYPEERR, "Property descriptor must be an object, got {0}") -MSG_DEF(JSMSG_OBJECT_REQUIRED_RET_OWNKEYS, 1, JSEXN_TYPEERR, "ownKeys trap must be an object, got {0}") -MSG_DEF(JSMSG_WRONG_TYPE_ARG, 4, JSEXN_TYPEERR, "argument {0} to {1} must be an object of type {2}, got {3}") -MSG_DEF(JSMSG_SET_NON_OBJECT_RECEIVER, 2, JSEXN_TYPEERR, "can't assign to property {1} on {0}: not an object") -MSG_DEF(JSMSG_INVALID_DESCRIPTOR, 0, JSEXN_TYPEERR, "property descriptors must not specify a value or be writable when a getter or setter has been specified") -MSG_DEF(JSMSG_OBJECT_NOT_EXTENSIBLE, 1, JSEXN_TYPEERR, "{0}: Object is not extensible") -MSG_DEF(JSMSG_CANT_DEFINE_PROP_OBJECT_NOT_EXTENSIBLE, 2, JSEXN_TYPEERR, "can't define property {1}: {0} is not extensible") -MSG_DEF(JSMSG_CANT_REDEFINE_PROP, 1, JSEXN_TYPEERR, "can't redefine non-configurable property {0}") -MSG_DEF(JSMSG_CANT_REDEFINE_ARRAY_LENGTH, 0, JSEXN_TYPEERR, "can't redefine array length") -MSG_DEF(JSMSG_CANT_DEFINE_PAST_ARRAY_LENGTH, 0, JSEXN_TYPEERR, "can't define array index property past the end of an array with non-writable length") -MSG_DEF(JSMSG_BAD_GET_SET_FIELD, 1, JSEXN_TYPEERR, "property descriptor's {0} field is neither undefined nor a function") -MSG_DEF(JSMSG_THROW_TYPE_ERROR, 0, JSEXN_TYPEERR, "'caller', 'callee', and 'arguments' properties may not be accessed on strict mode functions or the arguments objects for calls to them") -MSG_DEF(JSMSG_NOT_EXPECTED_TYPE, 3, JSEXN_TYPEERR, "{0}: expected {1}, got {2}") -MSG_DEF(JSMSG_NOT_ITERABLE, 1, JSEXN_TYPEERR, "{0} is not iterable") -MSG_DEF(JSMSG_ALREADY_HAS_PRAGMA, 2, JSEXN_WARN, "{0} is being assigned a {1}, but already has one") -MSG_DEF(JSMSG_GET_ITER_RETURNED_PRIMITIVE, 0, JSEXN_TYPEERR, "[Symbol.iterator]() returned a non-object value") -MSG_DEF(JSMSG_ITER_METHOD_RETURNED_PRIMITIVE, 1, JSEXN_TYPEERR, "iterator.{0}() returned a non-object value") -MSG_DEF(JSMSG_CANT_SET_PROTO, 0, JSEXN_TYPEERR, "can't set prototype of this object") -MSG_DEF(JSMSG_CANT_SET_PROTO_OF, 1, JSEXN_TYPEERR, "can't set prototype of {0}") -MSG_DEF(JSMSG_CANT_SET_PROTO_CYCLE, 0, JSEXN_TYPEERR, "can't set prototype: it would cause a prototype chain cycle") -MSG_DEF(JSMSG_INVALID_ARG_TYPE, 3, JSEXN_TYPEERR, "Invalid type: {0} can't be a{1} {2}") -MSG_DEF(JSMSG_TERMINATED, 1, JSEXN_ERR, "Script terminated by timeout at:\n{0}") -MSG_DEF(JSMSG_CANT_CALL_CLASS_CONSTRUCTOR, 0, JSEXN_TYPEERR, "class constructors must be invoked with 'new'") -MSG_DEF(JSMSG_UNINITIALIZED_THIS, 0, JSEXN_REFERENCEERR, "must call super constructor before using 'this' in derived class constructor") -MSG_DEF(JSMSG_BAD_DERIVED_RETURN, 1, JSEXN_TYPEERR, "derived class constructor returned invalid value {0}") -MSG_DEF(JSMSG_BAD_HERITAGE, 2, JSEXN_TYPEERR, "class heritage {0} is {1}") -MSG_DEF(JSMSG_NOT_OBJORNULL, 1, JSEXN_TYPEERR, "{0} is not an object or null") -MSG_DEF(JSMSG_CONSTRUCTOR_DISABLED, 1, JSEXN_TYPEERR, "{0} is disabled") - -// JSON -MSG_DEF(JSMSG_JSON_BAD_PARSE, 3, JSEXN_SYNTAXERR, "JSON.parse: {0} at line {1} column {2} of the JSON data") -MSG_DEF(JSMSG_JSON_CYCLIC_VALUE, 0, JSEXN_TYPEERR, "cyclic object value") - -// Runtime errors -MSG_DEF(JSMSG_ASSIGN_TO_CALL, 0, JSEXN_REFERENCEERR, "cannot assign to function call") -MSG_DEF(JSMSG_BAD_INSTANCEOF_RHS, 1, JSEXN_TYPEERR, "invalid 'instanceof' operand {0}") -MSG_DEF(JSMSG_BAD_PROTOTYPE, 1, JSEXN_TYPEERR, "'prototype' property of {0} is not an object") -MSG_DEF(JSMSG_IN_NOT_OBJECT, 1, JSEXN_TYPEERR, "right-hand side of 'in' should be an object, got {0}") -MSG_DEF(JSMSG_IN_STRING, 2, JSEXN_TYPEERR, "cannot use 'in' operator to search for {0} in {1}") -MSG_DEF(JSMSG_TOO_MANY_CON_SPREADARGS, 0, JSEXN_RANGEERR, "too many constructor arguments") -MSG_DEF(JSMSG_TOO_MANY_FUN_SPREADARGS, 0, JSEXN_RANGEERR, "too many function arguments") -MSG_DEF(JSMSG_UNINITIALIZED_LEXICAL, 1, JSEXN_REFERENCEERR, "can't access lexical declaration '{0}' before initialization") -MSG_DEF(JSMSG_BAD_CONST_ASSIGN, 1, JSEXN_TYPEERR, "invalid assignment to const '{0}'") -MSG_DEF(JSMSG_CANT_DECLARE_GLOBAL_BINDING, 2, JSEXN_TYPEERR, "cannot declare global binding '{0}': {1}") - -// Date -MSG_DEF(JSMSG_INVALID_DATE, 0, JSEXN_RANGEERR, "invalid date") -MSG_DEF(JSMSG_BAD_TOISOSTRING_PROP, 0, JSEXN_TYPEERR, "toISOString property is not callable") - -// String -MSG_DEF(JSMSG_BAD_URI, 0, JSEXN_URIERR, "malformed URI sequence") -MSG_DEF(JSMSG_INVALID_NORMALIZE_FORM, 0, JSEXN_RANGEERR, "form must be one of 'NFC', 'NFD', 'NFKC', or 'NFKD'") -MSG_DEF(JSMSG_NEGATIVE_REPETITION_COUNT, 0, JSEXN_RANGEERR, "repeat count must be non-negative") -MSG_DEF(JSMSG_NOT_A_CODEPOINT, 1, JSEXN_RANGEERR, "{0} is not a valid code point") -MSG_DEF(JSMSG_RESULTING_STRING_TOO_LARGE, 0, JSEXN_RANGEERR, "repeat count must be less than infinity and not overflow maximum string size") -MSG_DEF(JSMSG_FLAGS_UNDEFINED_OR_NULL, 0, JSEXN_TYPEERR, "'flags' property must neither be undefined nor null") -MSG_DEF(JSMSG_REQUIRES_GLOBAL_REGEXP, 1, JSEXN_TYPEERR, "{0} must be called with a global RegExp") - -// Number -MSG_DEF(JSMSG_BAD_RADIX, 0, JSEXN_RANGEERR, "radix must be an integer at least 2 and no greater than 36") -MSG_DEF(JSMSG_PRECISION_RANGE, 1, JSEXN_RANGEERR, "precision {0} out of range") - -// Function -MSG_DEF(JSMSG_BAD_APPLY_ARGS, 1, JSEXN_TYPEERR, "second argument to Function.prototype.{0} must be an array") -MSG_DEF(JSMSG_BAD_FORMAL, 0, JSEXN_SYNTAXERR, "malformed formal parameter") -MSG_DEF(JSMSG_CALLER_IS_STRICT, 0, JSEXN_TYPEERR, "access to strict mode caller function is censored") -MSG_DEF(JSMSG_DEPRECATED_USAGE, 1, JSEXN_REFERENCEERR, "deprecated {0} usage") -MSG_DEF(JSMSG_NOT_SCRIPTED_FUNCTION, 1, JSEXN_TYPEERR, "{0} is not a scripted function") -MSG_DEF(JSMSG_NO_REST_NAME, 0, JSEXN_SYNTAXERR, "no parameter name after ...") -MSG_DEF(JSMSG_PARAMETER_AFTER_REST, 0, JSEXN_SYNTAXERR, "parameter after rest parameter") -MSG_DEF(JSMSG_TOO_MANY_ARGUMENTS, 0, JSEXN_RANGEERR, "too many arguments provided for a function call") - -// CSP -MSG_DEF(JSMSG_CSP_BLOCKED_EVAL, 0, JSEXN_EVALERR, "call to eval() blocked by CSP") -MSG_DEF(JSMSG_CSP_BLOCKED_FUNCTION, 0, JSEXN_EVALERR, "call to Function() blocked by CSP") - -// Wrappers -MSG_DEF(JSMSG_ACCESSOR_DEF_DENIED, 1, JSEXN_ERR, "Permission denied to define accessor property {0}") -MSG_DEF(JSMSG_DEAD_OBJECT, 0, JSEXN_TYPEERR, "can't access dead object") -MSG_DEF(JSMSG_OBJECT_ACCESS_DENIED, 0, JSEXN_ERR, "Permission denied to access object") -MSG_DEF(JSMSG_PROPERTY_ACCESS_DENIED, 1, JSEXN_ERR, "Permission denied to access property {0}") - -// JSAPI-only (Not thrown as JS exceptions) -MSG_DEF(JSMSG_CANT_CLONE_OBJECT, 0, JSEXN_TYPEERR, "can't clone object") -MSG_DEF(JSMSG_CANT_OPEN, 2, JSEXN_ERR, "can't open {0}: {1}") -MSG_DEF(JSMSG_SUPPORT_NOT_ENABLED, 1, JSEXN_ERR, "support for {0} is not enabled") -MSG_DEF(JSMSG_USER_DEFINED_ERROR, 0, JSEXN_ERR, "JS_ReportError was called") - -// Internal errors -MSG_DEF(JSMSG_ALLOC_OVERFLOW, 0, JSEXN_INTERNALERR, "allocation size overflow") -MSG_DEF(JSMSG_BAD_BYTECODE, 1, JSEXN_INTERNALERR, "unimplemented JavaScript bytecode {0}") -MSG_DEF(JSMSG_BUFFER_TOO_SMALL, 0, JSEXN_INTERNALERR, "buffer too small") -MSG_DEF(JSMSG_BUILD_ID_NOT_AVAILABLE, 0, JSEXN_INTERNALERR, "build ID is not available") -MSG_DEF(JSMSG_BYTECODE_TOO_BIG, 2, JSEXN_INTERNALERR, "bytecode {0} too large (limit {1})") -MSG_DEF(JSMSG_NEED_DIET, 1, JSEXN_INTERNALERR, "{0} too large") -MSG_DEF(JSMSG_OUT_OF_MEMORY, 0, JSEXN_INTERNALERR, "out of memory") -MSG_DEF(JSMSG_OVER_RECURSED, 0, JSEXN_INTERNALERR, "too much recursion") -MSG_DEF(JSMSG_TOO_BIG_TO_ENCODE, 0, JSEXN_INTERNALERR, "data are to big to encode") -MSG_DEF(JSMSG_TOO_DEEP, 1, JSEXN_INTERNALERR, "{0} nested too deeply") -MSG_DEF(JSMSG_UNCAUGHT_EXCEPTION, 1, JSEXN_INTERNALERR, "uncaught exception: {0}") -MSG_DEF(JSMSG_UNKNOWN_FORMAT, 1, JSEXN_INTERNALERR, "unknown bytecode format {0}") -MSG_DEF(JSMSG_UNSAFE_FILENAME, 1, JSEXN_INTERNALERR, "unsafe filename: {0}") - -// Frontend -MSG_DEF(JSMSG_ACCESSOR_WRONG_ARGS, 3, JSEXN_SYNTAXERR, "{0} functions must have {1} argument{2}") -MSG_DEF(JSMSG_ARRAY_INIT_TOO_BIG, 0, JSEXN_INTERNALERR, "array initializer too large") -MSG_DEF(JSMSG_AS_AFTER_IMPORT_STAR, 0, JSEXN_SYNTAXERR, "missing keyword 'as' after import *") -MSG_DEF(JSMSG_AS_AFTER_RESERVED_WORD, 1, JSEXN_SYNTAXERR, "missing keyword 'as' after reserved word '{0}'") -MSG_DEF(JSMSG_AWAIT_IN_PARAMETER, 0, JSEXN_SYNTAXERR, "await expression can't be used in parameter") -MSG_DEF(JSMSG_AWAIT_OUTSIDE_ASYNC, 0, JSEXN_SYNTAXERR, "await is only valid in async functions and async generators") -MSG_DEF(JSMSG_BAD_ARROW_ARGS, 0, JSEXN_SYNTAXERR, "invalid arrow-function arguments (parentheses around the arrow-function may help)") -MSG_DEF(JSMSG_BAD_BINDING, 1, JSEXN_SYNTAXERR, "redefining {0} is deprecated") -MSG_DEF(JSMSG_BAD_COALESCE_MIXING, 0, JSEXN_SYNTAXERR, "cannot use `??` unparenthesized within `||` and `&&` expressions") -MSG_DEF(JSMSG_BAD_CONST_DECL, 0, JSEXN_SYNTAXERR, "missing = in const declaration") -MSG_DEF(JSMSG_BAD_CONTINUE, 0, JSEXN_SYNTAXERR, "continue must be inside loop") -MSG_DEF(JSMSG_BAD_DESTRUCT_ASS, 0, JSEXN_SYNTAXERR, "invalid destructuring assignment operator") -MSG_DEF(JSMSG_BAD_DESTRUCT_TARGET, 0, JSEXN_SYNTAXERR, "invalid destructuring target") -MSG_DEF(JSMSG_BAD_DESTRUCT_PARENS, 0, JSEXN_SYNTAXERR, "destructuring patterns in assignments can't be parenthesized") -MSG_DEF(JSMSG_BAD_DESTRUCT_DECL, 0, JSEXN_SYNTAXERR, "missing = in destructuring declaration") -MSG_DEF(JSMSG_BAD_DUP_ARGS, 0, JSEXN_SYNTAXERR, "duplicate argument names not allowed in this context") -MSG_DEF(JSMSG_BAD_FOR_EACH_LOOP, 0, JSEXN_SYNTAXERR, "invalid for each loop") -MSG_DEF(JSMSG_BAD_FOR_LEFTSIDE, 0, JSEXN_SYNTAXERR, "invalid for-in/of left-hand side") -MSG_DEF(JSMSG_LEXICAL_DECL_DEFINES_LET,0, JSEXN_SYNTAXERR, "a lexical declaration can't define a 'let' binding") -MSG_DEF(JSMSG_LET_STARTING_FOROF_LHS, 0, JSEXN_SYNTAXERR, "an expression X in 'for (X of Y)' must not start with 'let'") -MSG_DEF(JSMSG_BAD_INCOP_OPERAND, 0, JSEXN_SYNTAXERR, "invalid increment/decrement operand") -MSG_DEF(JSMSG_BAD_LEFTSIDE_OF_ASS, 0, JSEXN_SYNTAXERR, "invalid assignment left-hand side") -MSG_DEF(JSMSG_BAD_METHOD_DEF, 0, JSEXN_SYNTAXERR, "bad method definition") -MSG_DEF(JSMSG_BAD_POW_LEFTSIDE, 0, JSEXN_SYNTAXERR, "unparenthesized unary expression can't appear on the left-hand side of '**'") -MSG_DEF(JSMSG_BAD_PROP_ID, 0, JSEXN_SYNTAXERR, "invalid property id") -MSG_DEF(JSMSG_BAD_RETURN_OR_YIELD, 1, JSEXN_SYNTAXERR, "{0} not in function") -MSG_DEF(JSMSG_BAD_STRICT_ASSIGN, 1, JSEXN_SYNTAXERR, "'{0}' can't be defined or assigned to in strict mode code") -MSG_DEF(JSMSG_BAD_STRICT_ASSIGN_ARGUMENTS, 0, JSEXN_SYNTAXERR, "'arguments' can't be defined or assigned to in strict mode code") -MSG_DEF(JSMSG_BAD_STRICT_ASSIGN_EVAL, 0, JSEXN_SYNTAXERR, "'eval' can't be defined or assigned to in strict mode code") -MSG_DEF(JSMSG_BAD_SWITCH, 0, JSEXN_SYNTAXERR, "invalid switch statement") -MSG_DEF(JSMSG_BAD_SUPER, 0, JSEXN_SYNTAXERR, "invalid use of keyword 'super'") -MSG_DEF(JSMSG_BAD_SUPERPROP, 1, JSEXN_SYNTAXERR, "use of super {0} accesses only valid within methods or eval code within methods") -MSG_DEF(JSMSG_BAD_SUPERCALL, 0, JSEXN_SYNTAXERR, "super() is only valid in derived class constructors") -MSG_DEF(JSMSG_BAD_ARGUMENTS, 0, JSEXN_SYNTAXERR, "arguments is not valid in fields") -MSG_DEF(JSMSG_BRACKET_AFTER_LIST, 0, JSEXN_SYNTAXERR, "missing ] after element list") -MSG_DEF(JSMSG_BRACKET_IN_INDEX, 0, JSEXN_SYNTAXERR, "missing ] in index expression") -MSG_DEF(JSMSG_BRACKET_OPENED, 2, JSEXN_NOTE, "[ opened at line {0}, column {1}") -MSG_DEF(JSMSG_CATCH_AFTER_GENERAL, 0, JSEXN_SYNTAXERR, "catch after unconditional catch") -MSG_DEF(JSMSG_CATCH_IDENTIFIER, 0, JSEXN_SYNTAXERR, "missing identifier in catch") -MSG_DEF(JSMSG_CATCH_OR_FINALLY, 0, JSEXN_SYNTAXERR, "missing catch or finally after try") -MSG_DEF(JSMSG_CATCH_WITHOUT_TRY, 0, JSEXN_SYNTAXERR, "catch without try") -MSG_DEF(JSMSG_COLON_AFTER_CASE, 0, JSEXN_SYNTAXERR, "missing : after case label") -MSG_DEF(JSMSG_COLON_AFTER_ID, 0, JSEXN_SYNTAXERR, "missing : after property id") -MSG_DEF(JSMSG_COLON_IN_COND, 0, JSEXN_SYNTAXERR, "missing : in conditional expression") -MSG_DEF(JSMSG_COMP_PROP_UNTERM_EXPR, 0, JSEXN_SYNTAXERR, "missing ] in computed property name") -MSG_DEF(JSMSG_CURLY_AFTER_BODY, 0, JSEXN_SYNTAXERR, "missing } after function body") -MSG_DEF(JSMSG_CURLY_OPENED, 2, JSEXN_NOTE, "{ opened at line {0}, column {1}") -MSG_DEF(JSMSG_CURLY_AFTER_CATCH, 0, JSEXN_SYNTAXERR, "missing } after catch block") -MSG_DEF(JSMSG_CURLY_AFTER_FINALLY, 0, JSEXN_SYNTAXERR, "missing } after finally block") -MSG_DEF(JSMSG_CURLY_AFTER_LIST, 0, JSEXN_SYNTAXERR, "missing } after property list") -MSG_DEF(JSMSG_CURLY_AFTER_TRY, 0, JSEXN_SYNTAXERR, "missing } after try block") -MSG_DEF(JSMSG_CURLY_BEFORE_BODY, 0, JSEXN_SYNTAXERR, "missing { before function body") -MSG_DEF(JSMSG_CURLY_BEFORE_CATCH, 0, JSEXN_SYNTAXERR, "missing { before catch block") -MSG_DEF(JSMSG_CURLY_BEFORE_CLASS, 0, JSEXN_SYNTAXERR, "missing { before class body") -MSG_DEF(JSMSG_CURLY_BEFORE_FINALLY, 0, JSEXN_SYNTAXERR, "missing { before finally block") -MSG_DEF(JSMSG_CURLY_BEFORE_SWITCH, 0, JSEXN_SYNTAXERR, "missing { before switch body") -MSG_DEF(JSMSG_CURLY_BEFORE_TRY, 0, JSEXN_SYNTAXERR, "missing { before try block") -MSG_DEF(JSMSG_CURLY_IN_COMPOUND, 0, JSEXN_SYNTAXERR, "missing } in compound statement") -MSG_DEF(JSMSG_DECLARATION_AFTER_EXPORT,0, JSEXN_SYNTAXERR, "missing declaration after 'export' keyword") -MSG_DEF(JSMSG_DECLARATION_AFTER_IMPORT,0, JSEXN_SYNTAXERR, "missing declaration after 'import' keyword") -MSG_DEF(JSMSG_DEPRECATED_DELETE_OPERAND, 0, JSEXN_SYNTAXERR, "applying the 'delete' operator to an unqualified name is deprecated") -MSG_DEF(JSMSG_DEPRECATED_OCTAL, 0, JSEXN_SYNTAXERR, "\"0\"-prefixed octal literals and octal escape sequences are deprecated; for octal literals use the \"0o\" prefix instead") -MSG_DEF(JSMSG_DEPRECATED_PRAGMA, 1, JSEXN_WARN, "Using //@ to indicate {0} pragmas is deprecated. Use //# instead") -MSG_DEF(JSMSG_DUPLICATE_EXPORT_NAME, 1, JSEXN_SYNTAXERR, "duplicate export name '{0}'") -MSG_DEF(JSMSG_DUPLICATE_FORMAL, 1, JSEXN_SYNTAXERR, "duplicate formal argument {0}") -MSG_DEF(JSMSG_DUPLICATE_LABEL, 0, JSEXN_SYNTAXERR, "duplicate label") -MSG_DEF(JSMSG_DUPLICATE_PROPERTY, 1, JSEXN_SYNTAXERR, "property name {0} appears more than once in object literal") -MSG_DEF(JSMSG_DUPLICATE_PROTO_PROPERTY, 0, JSEXN_SYNTAXERR, "property name __proto__ appears more than once in object literal") -MSG_DEF(JSMSG_EMPTY_CONSEQUENT, 0, JSEXN_SYNTAXERR, "mistyped ; after conditional?") -MSG_DEF(JSMSG_EQUAL_AS_ASSIGN, 0, JSEXN_SYNTAXERR, "test for equality (==) mistyped as assignment (=)?") -MSG_DEF(JSMSG_EXPORT_DECL_AT_TOP_LEVEL,0, JSEXN_SYNTAXERR, "export declarations may only appear at top level of a module") -MSG_DEF(JSMSG_FINALLY_WITHOUT_TRY, 0, JSEXN_SYNTAXERR, "finally without try") -MSG_DEF(JSMSG_FORBIDDEN_AS_STATEMENT, 1, JSEXN_SYNTAXERR, "{0} can't appear in single-statement context") -MSG_DEF(JSMSG_FOR_AWAIT_OUTSIDE_ASYNC, 0, JSEXN_SYNTAXERR, "for await (... of ...) is only valid in async functions and async generators") -MSG_DEF(JSMSG_FROM_AFTER_IMPORT_CLAUSE, 0, JSEXN_SYNTAXERR, "missing keyword 'from' after import clause") -MSG_DEF(JSMSG_FROM_AFTER_EXPORT_STAR, 0, JSEXN_SYNTAXERR, "missing keyword 'from' after export *") -MSG_DEF(JSMSG_GARBAGE_AFTER_INPUT, 2, JSEXN_SYNTAXERR, "unexpected garbage after {0}, starting with {1}") -MSG_DEF(JSMSG_IDSTART_AFTER_NUMBER, 0, JSEXN_SYNTAXERR, "identifier starts immediately after numeric literal") -MSG_DEF(JSMSG_BAD_ESCAPE, 0, JSEXN_SYNTAXERR, "invalid escape sequence") -MSG_DEF(JSMSG_MISSING_PRIVATE_NAME, 0, JSEXN_SYNTAXERR, "'#' not followed by identifier") -MSG_DEF(JSMSG_ILLEGAL_CHARACTER, 0, JSEXN_SYNTAXERR, "illegal character") -MSG_DEF(JSMSG_IMPORT_META_OUTSIDE_MODULE, 0, JSEXN_SYNTAXERR, "import.meta may only appear in a module") -MSG_DEF(JSMSG_IMPORT_DECL_AT_TOP_LEVEL, 0, JSEXN_SYNTAXERR, "import declarations may only appear at top level of a module") -MSG_DEF(JSMSG_OF_AFTER_FOR_LOOP_DECL, 0, JSEXN_SYNTAXERR, "a declaration in the head of a for-of loop can't have an initializer") -MSG_DEF(JSMSG_IN_AFTER_LEXICAL_FOR_DECL,0,JSEXN_SYNTAXERR, "a lexical declaration in the head of a for-in loop can't have an initializer") -MSG_DEF(JSMSG_INVALID_FOR_IN_DECL_WITH_INIT,0,JSEXN_SYNTAXERR,"for-in loop head declarations may not have initializers") -MSG_DEF(JSMSG_INVALID_ID, 1, JSEXN_SYNTAXERR, "{0} is an invalid identifier") -MSG_DEF(JSMSG_SEPARATOR_IN_ZERO_PREFIXED_NUMBER, 0, JSEXN_SYNTAXERR, "numeric separators '_' are not allowed in numbers that start with '0'") -MSG_DEF(JSMSG_LABEL_NOT_FOUND, 0, JSEXN_SYNTAXERR, "label not found") -MSG_DEF(JSMSG_GENERATOR_LABEL, 0, JSEXN_SYNTAXERR, "generator functions cannot be labelled") -MSG_DEF(JSMSG_FUNCTION_LABEL, 0, JSEXN_SYNTAXERR, "functions cannot be labelled") -MSG_DEF(JSMSG_SLOPPY_FUNCTION_LABEL, 0, JSEXN_SYNTAXERR, "functions can only be labelled inside blocks") -MSG_DEF(JSMSG_LINE_BREAK_AFTER_THROW, 0, JSEXN_SYNTAXERR, "no line break is allowed between 'throw' and its expression") -MSG_DEF(JSMSG_LINE_BREAK_BEFORE_ARROW, 0, JSEXN_SYNTAXERR, "no line break is allowed before '=>'") -MSG_DEF(JSMSG_MALFORMED_ESCAPE, 1, JSEXN_SYNTAXERR, "malformed {0} character escape sequence") -MSG_DEF(JSMSG_MISSING_BINARY_DIGITS, 0, JSEXN_SYNTAXERR, "missing binary digits after '0b'") -MSG_DEF(JSMSG_MISSING_EXPONENT, 0, JSEXN_SYNTAXERR, "missing exponent") -MSG_DEF(JSMSG_MISSING_EXPR_AFTER_THROW,0, JSEXN_SYNTAXERR, "throw statement is missing an expression") -MSG_DEF(JSMSG_MISSING_FORMAL, 0, JSEXN_SYNTAXERR, "missing formal parameter") -MSG_DEF(JSMSG_MISSING_HEXDIGITS, 0, JSEXN_SYNTAXERR, "missing hexadecimal digits after '0x'") -MSG_DEF(JSMSG_MISSING_OCTAL_DIGITS, 0, JSEXN_SYNTAXERR, "missing octal digits after '0o'") -MSG_DEF(JSMSG_NUMBER_END_WITH_UNDERSCORE, 0, JSEXN_SYNTAXERR, "underscore can appear only between digits, not after the last digit in a number") -MSG_DEF(JSMSG_NUMBER_MULTIPLE_ADJACENT_UNDERSCORES, 0, JSEXN_SYNTAXERR, "number cannot contain multiple adjacent underscores") -MSG_DEF(JSMSG_MODULE_SPEC_AFTER_FROM, 0, JSEXN_SYNTAXERR, "missing module specifier after 'from' keyword") -MSG_DEF(JSMSG_NAME_AFTER_DOT, 0, JSEXN_SYNTAXERR, "missing name after . operator") -MSG_DEF(JSMSG_NAMED_IMPORTS_OR_NAMESPACE_IMPORT, 0, JSEXN_SYNTAXERR, "expected named imports or namespace import after comma") -MSG_DEF(JSMSG_NO_BINDING_NAME, 0, JSEXN_SYNTAXERR, "missing binding name") -MSG_DEF(JSMSG_NO_EXPORT_NAME, 0, JSEXN_SYNTAXERR, "missing export name") -MSG_DEF(JSMSG_NO_IMPORT_NAME, 0, JSEXN_SYNTAXERR, "missing import name") -MSG_DEF(JSMSG_NO_VARIABLE_NAME, 0, JSEXN_SYNTAXERR, "missing variable name") -MSG_DEF(JSMSG_OF_AFTER_FOR_NAME, 0, JSEXN_SYNTAXERR, "missing 'of' after for") -MSG_DEF(JSMSG_PAREN_AFTER_ARGS, 0, JSEXN_SYNTAXERR, "missing ) after argument list") -MSG_DEF(JSMSG_PAREN_AFTER_CATCH, 0, JSEXN_SYNTAXERR, "missing ) after catch") -MSG_DEF(JSMSG_PAREN_AFTER_COND, 0, JSEXN_SYNTAXERR, "missing ) after condition") -MSG_DEF(JSMSG_PAREN_AFTER_FOR, 0, JSEXN_SYNTAXERR, "missing ( after for") -MSG_DEF(JSMSG_PAREN_AFTER_FORMAL, 0, JSEXN_SYNTAXERR, "missing ) after formal parameters") -MSG_DEF(JSMSG_PAREN_AFTER_FOR_CTRL, 0, JSEXN_SYNTAXERR, "missing ) after for-loop control") -MSG_DEF(JSMSG_PAREN_AFTER_FOR_OF_ITERABLE, 0, JSEXN_SYNTAXERR, "missing ) after for-of iterable") -MSG_DEF(JSMSG_PAREN_AFTER_SWITCH, 0, JSEXN_SYNTAXERR, "missing ) after switch expression") -MSG_DEF(JSMSG_PAREN_AFTER_WITH, 0, JSEXN_SYNTAXERR, "missing ) after with-statement object") -MSG_DEF(JSMSG_PAREN_BEFORE_CATCH, 0, JSEXN_SYNTAXERR, "missing ( before catch") -MSG_DEF(JSMSG_PAREN_BEFORE_COND, 0, JSEXN_SYNTAXERR, "missing ( before condition") -MSG_DEF(JSMSG_PAREN_BEFORE_FORMAL, 0, JSEXN_SYNTAXERR, "missing ( before formal parameters") -MSG_DEF(JSMSG_PAREN_BEFORE_SWITCH, 0, JSEXN_SYNTAXERR, "missing ( before switch expression") -MSG_DEF(JSMSG_PAREN_BEFORE_WITH, 0, JSEXN_SYNTAXERR, "missing ( before with-statement object") -MSG_DEF(JSMSG_PAREN_IN_PAREN, 0, JSEXN_SYNTAXERR, "missing ) in parenthetical") -MSG_DEF(JSMSG_RC_AFTER_EXPORT_SPEC_LIST, 0, JSEXN_SYNTAXERR, "missing '}' after export specifier list") -MSG_DEF(JSMSG_RC_AFTER_IMPORT_SPEC_LIST, 0, JSEXN_SYNTAXERR, "missing '}' after module specifier list") -MSG_DEF(JSMSG_REDECLARED_CATCH_IDENTIFIER, 1, JSEXN_SYNTAXERR, "redeclaration of identifier '{0}' in catch") -MSG_DEF(JSMSG_RESERVED_ID, 1, JSEXN_SYNTAXERR, "{0} is a reserved identifier") -MSG_DEF(JSMSG_REST_WITH_COMMA, 0, JSEXN_SYNTAXERR, "rest element may not have a trailing comma") -MSG_DEF(JSMSG_REST_WITH_DEFAULT, 0, JSEXN_SYNTAXERR, "rest parameter may not have a default") -MSG_DEF(JSMSG_SELFHOSTED_TOP_LEVEL_LEXICAL, 1, JSEXN_SYNTAXERR, "self-hosted code cannot contain top-level {0} declarations") -MSG_DEF(JSMSG_SELFHOSTED_METHOD_CALL, 0, JSEXN_SYNTAXERR, "self-hosted code may not contain direct method calls. Use callFunction() or callContentFunction()") -MSG_DEF(JSMSG_SELFHOSTED_UNBOUND_NAME, 0, JSEXN_TYPEERR, "self-hosted code may not contain unbound name lookups") -MSG_DEF(JSMSG_SEMI_AFTER_FOR_COND, 0, JSEXN_SYNTAXERR, "missing ; after for-loop condition") -MSG_DEF(JSMSG_SEMI_AFTER_FOR_INIT, 0, JSEXN_SYNTAXERR, "missing ; after for-loop initializer") -MSG_DEF(JSMSG_SOURCE_TOO_LONG, 0, JSEXN_RANGEERR, "source is too long") -MSG_DEF(JSMSG_STMT_AFTER_RETURN, 0, JSEXN_WARN, "unreachable code after return statement") -MSG_DEF(JSMSG_STRICT_CODE_WITH, 0, JSEXN_SYNTAXERR, "strict mode code may not contain 'with' statements") -MSG_DEF(JSMSG_STRICT_NON_SIMPLE_PARAMS, 1, JSEXN_SYNTAXERR, "\"use strict\" not allowed in function with {0} parameter") -MSG_DEF(JSMSG_TEMPLSTR_UNTERM_EXPR, 0, JSEXN_SYNTAXERR, "missing } in template string") -MSG_DEF(JSMSG_TOO_MANY_CASES, 0, JSEXN_INTERNALERR, "too many switch cases") -MSG_DEF(JSMSG_TOO_MANY_CATCH_VARS, 0, JSEXN_SYNTAXERR, "too many catch variables") -MSG_DEF(JSMSG_TOO_MANY_CON_ARGS, 0, JSEXN_SYNTAXERR, "too many constructor arguments") -MSG_DEF(JSMSG_TOO_MANY_DEFAULTS, 0, JSEXN_SYNTAXERR, "more than one switch default") -MSG_DEF(JSMSG_TOO_MANY_FUN_ARGS, 0, JSEXN_SYNTAXERR, "too many function arguments") -MSG_DEF(JSMSG_TOO_MANY_LOCALS, 0, JSEXN_SYNTAXERR, "too many local variables") -MSG_DEF(JSMSG_TOO_MANY_RESUME_INDEXES, 0, JSEXN_SYNTAXERR, "too many yield/await/finally/case locations") -MSG_DEF(JSMSG_TOUGH_BREAK, 0, JSEXN_SYNTAXERR, "unlabeled break must be inside loop or switch") -MSG_DEF(JSMSG_UNEXPECTED_TOKEN, 2, JSEXN_SYNTAXERR, "expected {0}, got {1}") -MSG_DEF(JSMSG_UNEXPECTED_TOKEN_NO_EXPECT, 1, JSEXN_SYNTAXERR, "unexpected token: {0}") -MSG_DEF(JSMSG_UNEXPECTED_PARAMLIST_END,0, JSEXN_SYNTAXERR, "unexpected end of function parameter list") -MSG_DEF(JSMSG_UNNAMED_CLASS_STMT, 0, JSEXN_SYNTAXERR, "class statement requires a name") -MSG_DEF(JSMSG_UNNAMED_FUNCTION_STMT, 0, JSEXN_SYNTAXERR, "function statement requires a name") -MSG_DEF(JSMSG_UNTERMINATED_COMMENT, 0, JSEXN_SYNTAXERR, "unterminated comment") -MSG_DEF(JSMSG_UNTERMINATED_REGEXP, 0, JSEXN_SYNTAXERR, "unterminated regular expression literal") -MSG_DEF(JSMSG_EOF_BEFORE_END_OF_LITERAL,1,JSEXN_SYNTAXERR, "{0} literal not terminated before end of script") -MSG_DEF(JSMSG_EOL_BEFORE_END_OF_STRING,1, JSEXN_SYNTAXERR, "{0} string literal contains an unescaped line break") -MSG_DEF(JSMSG_EOF_IN_ESCAPE_IN_LITERAL,1, JSEXN_SYNTAXERR, "reached end of script in the middle of an escape sequence in a {0} literal") -MSG_DEF(JSMSG_USE_ASM_DIRECTIVE_FAIL, 0, JSEXN_SYNTAXERR, "\"use asm\" is only meaningful in the Directive Prologue of a function body") -MSG_DEF(JSMSG_VAR_HIDES_ARG, 1, JSEXN_TYPEERR, "variable {0} redeclares argument") -MSG_DEF(JSMSG_WHILE_AFTER_DO, 0, JSEXN_SYNTAXERR, "missing while after do-loop body") -MSG_DEF(JSMSG_YIELD_IN_PARAMETER, 0, JSEXN_SYNTAXERR, "yield expression can't be used in parameter") -MSG_DEF(JSMSG_YIELD_OUTSIDE_GENERATOR, 0, JSEXN_SYNTAXERR, "yield expression is only valid in generators") -MSG_DEF(JSMSG_BAD_COLUMN_NUMBER, 0, JSEXN_RANGEERR, "column number out of range") -MSG_DEF(JSMSG_COMPUTED_NAME_IN_PATTERN,0, JSEXN_SYNTAXERR, "computed property names aren't supported in this destructuring declaration") -MSG_DEF(JSMSG_DEFAULT_IN_PATTERN, 0, JSEXN_SYNTAXERR, "destructuring defaults aren't supported in this destructuring declaration") -MSG_DEF(JSMSG_BAD_NEWTARGET, 0, JSEXN_SYNTAXERR, "new.target only allowed within functions") -MSG_DEF(JSMSG_BAD_NEW_OPTIONAL, 0, JSEXN_SYNTAXERR, "new keyword cannot be used with an optional chain") -MSG_DEF(JSMSG_BAD_OPTIONAL_TEMPLATE, 0, JSEXN_SYNTAXERR, "tagged template cannot be used with optional chain") -MSG_DEF(JSMSG_ESCAPED_KEYWORD, 0, JSEXN_SYNTAXERR, "keywords must be written literally, without embedded escapes") -MSG_DEF(JSMSG_PRIVATE_FIELDS_NOT_SUPPORTED, 0, JSEXN_SYNTAXERR, "private fields are not currently supported") - -// UTF-8 source text encoding errors -MSG_DEF(JSMSG_BAD_LEADING_UTF8_UNIT, 1, JSEXN_SYNTAXERR, "{0} byte doesn't begin a valid UTF-8 code point") -MSG_DEF(JSMSG_NOT_ENOUGH_CODE_UNITS, 5, JSEXN_SYNTAXERR, "{0} byte in UTF-8 must be followed by {1} byte{2}, but {3} byte{4} present") -MSG_DEF(JSMSG_BAD_TRAILING_UTF8_UNIT, 1, JSEXN_SYNTAXERR, "bad trailing UTF-8 byte {0} doesn't match the pattern 0b10xxxxxx") -MSG_DEF(JSMSG_FORBIDDEN_UTF8_CODE_POINT,2,JSEXN_SYNTAXERR, "{0} isn't a valid code point because {1}") -MSG_DEF(JSMSG_BAD_CODE_UNITS, 1, JSEXN_NOTE, "the code units comprising this invalid code point were: {0}") - -// SmooshMonkey -MSG_DEF(JSMSG_SMOOSH_COMPILE_ERROR, 1, JSEXN_SYNTAXERR, "{0}") -MSG_DEF(JSMSG_SMOOSH_UNIMPLEMENTED, 1, JSEXN_INTERNALERR, "{0}") - -// asm.js -MSG_DEF(JSMSG_USE_ASM_TYPE_FAIL, 1, JSEXN_TYPEERR, "asm.js type error: {0}") -MSG_DEF(JSMSG_USE_ASM_LINK_FAIL, 1, JSEXN_TYPEERR, "asm.js link error: {0}") -MSG_DEF(JSMSG_USE_ASM_TYPE_OK, 1, JSEXN_WARN, "Successfully compiled asm.js code (total compilation time {0}ms)") -MSG_DEF(JSMSG_USE_ASM_TYPE_OK_NO_TIME, 0, JSEXN_WARN, "Successfully compiled asm.js code ()") - -// wasm -MSG_DEF(JSMSG_WASM_VERBOSE, 1, JSEXN_WARN, "WebAssembly verbose: {0}") -MSG_DEF(JSMSG_WASM_COMPILE_WARNING, 1, JSEXN_WARN, "WebAssembly module validated with warning: {0}") -MSG_DEF(JSMSG_WASM_HUGE_MEMORY_FAILED, 0, JSEXN_WARN, "WebAssembly.Memory failed to reserve a large virtual memory region. This may be due to low configured virtual memory limits on this system.") -MSG_DEF(JSMSG_WASM_COMPILE_ERROR, 1, JSEXN_WASMCOMPILEERROR, "{0}") -MSG_DEF(JSMSG_WASM_NO_SHMEM_COMPILE, 0, JSEXN_WASMCOMPILEERROR, "shared memory is disabled") -MSG_DEF(JSMSG_WASM_BAD_IMPORT_TYPE, 2, JSEXN_WASMLINKERROR, "import object field '{0}' is not a {1}") -MSG_DEF(JSMSG_WASM_BAD_IMPORT_SIG, 2, JSEXN_WASMLINKERROR, "imported function '{0}.{1}' signature mismatch") -MSG_DEF(JSMSG_WASM_BAD_IMP_SIZE, 1, JSEXN_WASMLINKERROR, "imported {0} with incompatible size") -MSG_DEF(JSMSG_WASM_BAD_IMP_MAX, 1, JSEXN_WASMLINKERROR, "imported {0} with incompatible maximum size") -MSG_DEF(JSMSG_WASM_IMP_SHARED_REQD, 0, JSEXN_WASMLINKERROR, "imported unshared memory but shared required") -MSG_DEF(JSMSG_WASM_IMP_SHARED_BANNED, 0, JSEXN_WASMLINKERROR, "imported shared memory but unshared required") -MSG_DEF(JSMSG_WASM_BAD_FIT, 2, JSEXN_WASMLINKERROR, "{0} segment does not fit in {1}") -MSG_DEF(JSMSG_WASM_NO_SHMEM_LINK, 0, JSEXN_WASMLINKERROR, "shared memory is disabled") -MSG_DEF(JSMSG_WASM_BAD_GLOB_MUT_LINK, 0, JSEXN_WASMLINKERROR, "imported global mutability mismatch") -MSG_DEF(JSMSG_WASM_BAD_GLOB_TYPE_LINK, 0, JSEXN_WASMLINKERROR, "imported global type mismatch") -MSG_DEF(JSMSG_WASM_BAD_TBL_TYPE_LINK, 0, JSEXN_WASMLINKERROR, "imported table type mismatch") -MSG_DEF(JSMSG_WASM_IND_CALL_TO_NULL, 0, JSEXN_WASMRUNTIMEERROR, "indirect call to null") -MSG_DEF(JSMSG_WASM_IND_CALL_BAD_SIG, 0, JSEXN_WASMRUNTIMEERROR, "indirect call signature mismatch") -MSG_DEF(JSMSG_WASM_UNREACHABLE, 0, JSEXN_WASMRUNTIMEERROR, "unreachable executed") -MSG_DEF(JSMSG_WASM_INTEGER_OVERFLOW, 0, JSEXN_WASMRUNTIMEERROR, "integer overflow") -MSG_DEF(JSMSG_WASM_INVALID_CONVERSION, 0, JSEXN_WASMRUNTIMEERROR, "invalid conversion to integer") -MSG_DEF(JSMSG_WASM_INT_DIVIDE_BY_ZERO, 0, JSEXN_WASMRUNTIMEERROR, "integer divide by zero") -MSG_DEF(JSMSG_WASM_OUT_OF_BOUNDS, 0, JSEXN_WASMRUNTIMEERROR, "index out of bounds") -MSG_DEF(JSMSG_WASM_UNALIGNED_ACCESS, 0, JSEXN_WASMRUNTIMEERROR, "unaligned memory access") -MSG_DEF(JSMSG_WASM_WAKE_OVERFLOW, 0, JSEXN_WASMRUNTIMEERROR, "too many woken agents") -MSG_DEF(JSMSG_WASM_DEREF_NULL, 0, JSEXN_WASMRUNTIMEERROR, "dereferencing null pointer") -MSG_DEF(JSMSG_WASM_BAD_RANGE , 2, JSEXN_RANGEERR, "bad {0} {1}") -MSG_DEF(JSMSG_WASM_BAD_GROW, 1, JSEXN_RANGEERR, "failed to grow {0}") -MSG_DEF(JSMSG_WASM_TABLE_OUT_OF_BOUNDS, 0, JSEXN_WASMRUNTIMEERROR, "table index out of bounds") -MSG_DEF(JSMSG_WASM_BAD_UINT32, 2, JSEXN_TYPEERR, "bad {0} {1}") -MSG_DEF(JSMSG_WASM_BAD_BUF_ARG, 0, JSEXN_TYPEERR, "first argument must be an ArrayBuffer or typed array object") -MSG_DEF(JSMSG_WASM_BAD_MOD_ARG, 0, JSEXN_TYPEERR, "first argument must be a WebAssembly.Module") -MSG_DEF(JSMSG_WASM_BAD_BUF_MOD_ARG, 0, JSEXN_TYPEERR, "first argument must be a WebAssembly.Module, ArrayBuffer or typed array object") -MSG_DEF(JSMSG_WASM_BAD_DESC_ARG, 1, JSEXN_TYPEERR, "first argument must be a {0} descriptor") -MSG_DEF(JSMSG_WASM_BAD_ELEMENT, 0, JSEXN_TYPEERR, "\"element\" property of table descriptor must be \"funcref\"") -MSG_DEF(JSMSG_WASM_BAD_ELEMENT_GENERALIZED, 0, JSEXN_TYPEERR, "\"element\" property of table descriptor must be \"funcref\" or \"externref\"") -MSG_DEF(JSMSG_WASM_BAD_IMPORT_ARG, 0, JSEXN_TYPEERR, "second argument must be an object") -MSG_DEF(JSMSG_WASM_BAD_IMPORT_FIELD, 1, JSEXN_TYPEERR, "import object field '{0}' is not an Object") -MSG_DEF(JSMSG_WASM_BAD_FUNCREF_VALUE, 0, JSEXN_TYPEERR, "can only pass WebAssembly exported functions to funcref") -MSG_DEF(JSMSG_WASM_BAD_VAL_TYPE, 0, JSEXN_TYPEERR, "cannot pass v128 to or from JS") -MSG_DEF(JSMSG_WASM_BAD_GLOBAL_TYPE, 0, JSEXN_TYPEERR, "bad type for a WebAssembly.Global") -MSG_DEF(JSMSG_WASM_NO_TRANSFER, 0, JSEXN_TYPEERR, "cannot transfer WebAssembly/asm.js ArrayBuffer") -MSG_DEF(JSMSG_WASM_TEXT_FAIL, 1, JSEXN_SYNTAXERR, "wasm text error: {0}") -MSG_DEF(JSMSG_WASM_MISSING_MAXIMUM, 0, JSEXN_TYPEERR, "'shared' is true but maximum is not specified") -MSG_DEF(JSMSG_WASM_GLOBAL_IMMUTABLE, 0, JSEXN_TYPEERR, "can't set value of immutable global") -MSG_DEF(JSMSG_WASM_TYPEREF_FROM_JS, 0, JSEXN_TYPEERR, "conversion from JavaScript value to WebAssembly typed ref unimplemented") -MSG_DEF(JSMSG_WASM_TYPEREF_TO_JS, 0, JSEXN_TYPEERR, "conversion from WebAssembly typed ref to JavaScript value unimplemented") -MSG_DEF(JSMSG_WASM_WRONG_NUMBER_OF_VALUES, 2, JSEXN_TYPEERR, "wrong number of values returned by JavaScript to WebAssembly (expected {0}, got {1})") - -// Proxy -MSG_DEF(JSMSG_BAD_TRAP_RETURN_VALUE, 2, JSEXN_TYPEERR,"trap {1} for {0} returned a primitive value") -MSG_DEF(JSMSG_BAD_GETPROTOTYPEOF_TRAP_RETURN,0,JSEXN_TYPEERR,"proxy getPrototypeOf handler returned a non-object, non-null value") -MSG_DEF(JSMSG_INCONSISTENT_GETPROTOTYPEOF_TRAP,0,JSEXN_TYPEERR,"proxy getPrototypeOf handler didn't return the target object's prototype") -MSG_DEF(JSMSG_PROXY_SETPROTOTYPEOF_RETURNED_FALSE, 0, JSEXN_TYPEERR, "proxy setPrototypeOf handler returned false") -MSG_DEF(JSMSG_PROXY_ISEXTENSIBLE_RETURNED_FALSE,0,JSEXN_TYPEERR,"proxy isExtensible handler must return the same extensibility as target") -MSG_DEF(JSMSG_INCONSISTENT_SETPROTOTYPEOF_TRAP,0,JSEXN_TYPEERR,"proxy setPrototypeOf handler returned true, even though the target's prototype is immutable because the target is non-extensible") -MSG_DEF(JSMSG_CANT_CHANGE_EXTENSIBILITY, 0, JSEXN_TYPEERR, "can't change object's extensibility") -MSG_DEF(JSMSG_CANT_DEFINE_INVALID, 2, JSEXN_TYPEERR, "proxy can't define an incompatible property descriptor ('{0}', {1})") -MSG_DEF(JSMSG_CANT_DEFINE_NEW, 1, JSEXN_TYPEERR, "proxy can't define a new property '{0}' on a non-extensible object") -MSG_DEF(JSMSG_CANT_DEFINE_NE_AS_NC, 1, JSEXN_TYPEERR, "proxy can't define a non-existent '{0}' property as non-configurable") -MSG_DEF(JSMSG_PROXY_DEFINE_RETURNED_FALSE, 1, JSEXN_TYPEERR, "proxy defineProperty handler returned false for property '{0}'") -MSG_DEF(JSMSG_PROXY_DELETE_RETURNED_FALSE, 1, JSEXN_TYPEERR, "can't delete property '{0}': proxy deleteProperty handler returned false") -MSG_DEF(JSMSG_PROXY_PREVENTEXTENSIONS_RETURNED_FALSE, 0, JSEXN_TYPEERR, "proxy preventExtensions handler returned false") -MSG_DEF(JSMSG_PROXY_SET_RETURNED_FALSE, 1, JSEXN_TYPEERR, "proxy set handler returned false for property '{0}'") -MSG_DEF(JSMSG_CANT_REPORT_AS_NON_EXTENSIBLE, 0, JSEXN_TYPEERR, "proxy can't report an extensible object as non-extensible") -MSG_DEF(JSMSG_CANT_DELETE_NON_EXTENSIBLE, 1, JSEXN_TYPEERR, "proxy can't delete property '{0}' on a non-extensible object") -MSG_DEF(JSMSG_CANT_REPORT_C_AS_NC, 1, JSEXN_TYPEERR, "proxy can't report existing configurable property '{0}' as non-configurable") -MSG_DEF(JSMSG_CANT_REPORT_E_AS_NE, 1, JSEXN_TYPEERR, "proxy can't report an existing own property '{0}' as non-existent on a non-extensible object") -MSG_DEF(JSMSG_CANT_REPORT_INVALID, 2, JSEXN_TYPEERR, "proxy can't report an incompatible property descriptor ('{0}', {1})") -MSG_DEF(JSMSG_CANT_REPORT_NC_AS_NE, 1, JSEXN_TYPEERR, "proxy can't report a non-configurable own property '{0}' as non-existent") -MSG_DEF(JSMSG_CANT_REPORT_NEW, 1, JSEXN_TYPEERR, "proxy can't report a new property '{0}' on a non-extensible object") -MSG_DEF(JSMSG_CANT_REPORT_NE_AS_NC, 1, JSEXN_TYPEERR, "proxy can't report a non-existent property '{0}' as non-configurable") -MSG_DEF(JSMSG_CANT_REPORT_W_AS_NW, 1, JSEXN_TYPEERR, "proxy can't report existing writable property '{0}' as non-writable") -MSG_DEF(JSMSG_CANT_SET_NW_NC, 1, JSEXN_TYPEERR, "proxy can't successfully set a non-writable, non-configurable property '{0}'") -MSG_DEF(JSMSG_CANT_SET_WO_SETTER, 1, JSEXN_TYPEERR, "proxy can't succesfully set an accessor property '{0}' without a setter") -MSG_DEF(JSMSG_CANT_SKIP_NC, 1, JSEXN_TYPEERR, "proxy can't skip a non-configurable property '{0}'") -MSG_DEF(JSMSG_OWNKEYS_STR_SYM, 0, JSEXN_TYPEERR, "proxy [[OwnPropertyKeys]] must return an array with only string and symbol elements") -MSG_DEF(JSMSG_OWNKEYS_DUPLICATE, 1, JSEXN_TYPEERR, "proxy [[OwnPropertyKeys]] can't report property '{0}' more than once") -MSG_DEF(JSMSG_MUST_REPORT_SAME_VALUE, 1, JSEXN_TYPEERR, "proxy must report the same value for the non-writable, non-configurable property '{0}'") -MSG_DEF(JSMSG_MUST_REPORT_UNDEFINED, 1, JSEXN_TYPEERR, "proxy must report undefined for a non-configurable accessor property '{0}' without a getter") -MSG_DEF(JSMSG_PROXY_CONSTRUCT_OBJECT, 0, JSEXN_TYPEERR, "proxy [[Construct]] must return an object") -MSG_DEF(JSMSG_PROXY_EXTENSIBILITY, 0, JSEXN_TYPEERR, "proxy must report same extensiblitity as target") -MSG_DEF(JSMSG_PROXY_GETOWN_OBJORUNDEF, 1, JSEXN_TYPEERR, "proxy [[GetOwnProperty]] must return an object or undefined for property '{0}'") -MSG_DEF(JSMSG_PROXY_REVOKED, 0, JSEXN_TYPEERR, "illegal operation attempted on a revoked proxy") -MSG_DEF(JSMSG_PROXY_ARG_REVOKED, 1, JSEXN_TYPEERR, "argument {0} cannot be a revoked proxy") -MSG_DEF(JSMSG_BAD_TRAP, 1, JSEXN_TYPEERR, "proxy handler's {0} trap wasn't undefined, null, or callable") - -// Structured cloning -MSG_DEF(JSMSG_SC_BAD_CLONE_VERSION, 0, JSEXN_ERR, "unsupported structured clone version") -MSG_DEF(JSMSG_SC_BAD_SERIALIZED_DATA, 1, JSEXN_INTERNALERR, "bad serialized structured data ({0})") -MSG_DEF(JSMSG_SC_DUP_TRANSFERABLE, 0, JSEXN_TYPEERR, "duplicate transferable for structured clone") -MSG_DEF(JSMSG_SC_NOT_TRANSFERABLE, 0, JSEXN_TYPEERR, "invalid transferable array for structured clone") -MSG_DEF(JSMSG_SC_UNSUPPORTED_TYPE, 0, JSEXN_TYPEERR, "unsupported type for structured data") -MSG_DEF(JSMSG_SC_NOT_CLONABLE, 1, JSEXN_TYPEERR, "The {0} object cannot be serialized. The Cross-Origin-Opener-Policy and Cross-Origin-Embedder-Policy HTTP headers will enable this in the future.") -MSG_DEF(JSMSG_SC_NOT_CLONABLE_WITH_COOP_COEP, 1, JSEXN_TYPEERR, "The {0} object cannot be serialized. The Cross-Origin-Opener-Policy and Cross-Origin-Embedder-Policy HTTP headers can be used to enable this.") -MSG_DEF(JSMSG_SC_SAB_DISABLED, 0, JSEXN_TYPEERR, "SharedArrayBuffer not cloned - shared memory disabled in receiver") -MSG_DEF(JSMSG_SC_SAB_REFCNT_OFLO, 0, JSEXN_TYPEERR, "SharedArrayBuffer has too many references") -MSG_DEF(JSMSG_SC_SHMEM_TRANSFERABLE, 0, JSEXN_TYPEERR, "Shared memory objects must not be in the transfer list") -MSG_DEF(JSMSG_SC_SHMEM_POLICY, 0, JSEXN_TYPEERR, "Policy object must forbid cloning shared memory objects cross-process") - -// Debugger -MSG_DEF(JSMSG_ASSIGN_FUNCTION_OR_NULL, 1, JSEXN_TYPEERR, "value assigned to {0} must be a function or null") -MSG_DEF(JSMSG_DEBUG_BAD_LINE, 0, JSEXN_TYPEERR, "invalid line number") -MSG_DEF(JSMSG_DEBUG_BAD_OFFSET, 0, JSEXN_TYPEERR, "invalid script offset") -MSG_DEF(JSMSG_DEBUG_BAD_REFERENT, 2, JSEXN_TYPEERR, "{0} does not refer to {1}") -MSG_DEF(JSMSG_DEBUG_BAD_RESUMPTION, 0, JSEXN_TYPEERR, "debugger resumption value must be undefined, {throw: val}, {return: val}, or null") -MSG_DEF(JSMSG_DEBUG_RESUMPTION_CONFLICT, 0, JSEXN_TYPEERR, "debugger hook returned a resumption, but an earlier hook already did") -MSG_DEF(JSMSG_DEBUG_BAD_YIELD, 0, JSEXN_TYPEERR, "generator yielded invalid value") -MSG_DEF(JSMSG_DEBUG_CANT_DEBUG_GLOBAL, 0, JSEXN_TYPEERR, "passing non-debuggable global to addDebuggee") -MSG_DEF(JSMSG_DEBUG_SAME_COMPARTMENT, 0, JSEXN_TYPEERR, "debugger and debuggee must be in different compartments") -MSG_DEF(JSMSG_DEBUG_CCW_REQUIRED, 1, JSEXN_TYPEERR, "{0}: argument must be an object from a different compartment") -MSG_DEF(JSMSG_DEBUG_COMPARTMENT_MISMATCH, 2, JSEXN_TYPEERR, "{0}: descriptor .{1} property is an object in a different compartment than the target object") -MSG_DEF(JSMSG_DEBUG_LOOP, 0, JSEXN_TYPEERR, "cannot debug an object in same compartment as debugger or a compartment that is already debugging the debugger") -MSG_DEF(JSMSG_DEBUG_NOT_DEBUGGEE, 2, JSEXN_ERR, "{0} is not a debuggee {1}") -MSG_DEF(JSMSG_DEBUG_NOT_DEBUGGING, 0, JSEXN_ERR, "can't set breakpoint: script global is not a debuggee") -MSG_DEF(JSMSG_DEBUG_NOT_IDLE, 0, JSEXN_ERR, "can't start debugging: a debuggee script is on the stack") -MSG_DEF(JSMSG_DEBUG_NOT_ON_STACK, 1, JSEXN_ERR, "{0} is not on stack") -MSG_DEF(JSMSG_DEBUG_NOT_ON_STACK_OR_SUSPENDED, 1, JSEXN_ERR, "{0} is not on stack or suspended") -MSG_DEF(JSMSG_DEBUG_NO_ENV_OBJECT, 0, JSEXN_TYPEERR, "declarative Environments don't have binding objects") -MSG_DEF(JSMSG_DEBUG_PROTO, 2, JSEXN_TYPEERR, "{0}.prototype is not a valid {1} instance") -MSG_DEF(JSMSG_DEBUG_WRONG_OWNER, 1, JSEXN_TYPEERR, "{0} belongs to a different Debugger") -MSG_DEF(JSMSG_DEBUG_OPTIMIZED_OUT, 1, JSEXN_ERR, "variable '{0}' has been optimized out") -MSG_DEF(JSMSG_DEBUG_OPTIMIZED_OUT_FUN, 0, JSEXN_ERR, "function is optimized out") -MSG_DEF(JSMSG_DEBUG_FORCED_RETURN_DISALLOWED, 0, JSEXN_TYPEERR, "can't force return from a generator before the initial yield") -MSG_DEF(JSMSG_DEBUG_RESUMPTION_VALUE_DISALLOWED, 0, JSEXN_TYPEERR, "resumption values are disallowed in this hook") -MSG_DEF(JSMSG_DEBUG_VARIABLE_NOT_FOUND,0, JSEXN_TYPEERR, "variable not found in environment") -MSG_DEF(JSMSG_DEBUG_WRAPPER_IN_WAY, 3, JSEXN_TYPEERR, "{0} is {1}{2}a global object, but a direct reference is required") -MSG_DEF(JSMSG_DEBUGGEE_WOULD_RUN, 2, JSEXN_DEBUGGEEWOULDRUN, "debuggee '{0}:{1}' would run") -MSG_DEF(JSMSG_NOT_CALLABLE_OR_UNDEFINED, 0, JSEXN_TYPEERR, "value is not a function or undefined") -MSG_DEF(JSMSG_NOT_TRACKING_ALLOCATIONS, 1, JSEXN_ERR, "Cannot call {0} without setting trackingAllocationSites to true") -MSG_DEF(JSMSG_OBJECT_METADATA_CALLBACK_ALREADY_SET, 0, JSEXN_ERR, "Cannot track object allocation, because other tools are already doing so") -MSG_DEF(JSMSG_QUERY_INNERMOST_WITHOUT_LINE_URL, 0, JSEXN_TYPEERR, "findScripts query object with 'innermost' property must have 'line' and either 'displayURL', 'url', or 'source'") -MSG_DEF(JSMSG_QUERY_LINE_WITHOUT_URL, 0, JSEXN_TYPEERR, "findScripts query object has 'line' property, but no 'displayURL', 'url', or 'source' property") -MSG_DEF(JSMSG_DEBUG_CANT_SET_OPT_ENV, 1, JSEXN_REFERENCEERR, "can't set '{0}' in an optimized-out environment") -MSG_DEF(JSMSG_DEBUG_INVISIBLE_COMPARTMENT, 0, JSEXN_TYPEERR, "object in compartment marked as invisible to Debugger") -MSG_DEF(JSMSG_DEBUG_CENSUS_BREAKDOWN, 1, JSEXN_TYPEERR, "unrecognized 'by' value in takeCensus breakdown: {0}") -MSG_DEF(JSMSG_DEBUG_PROMISE_NOT_RESOLVED, 0, JSEXN_TYPEERR, "Promise hasn't been resolved") -MSG_DEF(JSMSG_DEBUG_PROMISE_NOT_FULFILLED, 0, JSEXN_TYPEERR, "Promise hasn't been fulfilled") -MSG_DEF(JSMSG_DEBUG_PROMISE_NOT_REJECTED, 0, JSEXN_TYPEERR, "Promise hasn't been rejected") -MSG_DEF(JSMSG_DEBUG_NO_BINARY_SOURCE, 0, JSEXN_ERR, "WebAssembly binary source is not available") - -// Testing functions -MSG_DEF(JSMSG_TESTING_SCRIPTS_ONLY, 0, JSEXN_TYPEERR, "only works on scripts") - -// Tracelogger -MSG_DEF(JSMSG_TRACELOGGER_ENABLE_FAIL, 1, JSEXN_ERR, "enabling tracelogger failed: {0}") - -// Intl -MSG_DEF(JSMSG_DATE_NOT_FINITE, 2, JSEXN_RANGEERR, "date value is not finite in {0}.{1}()") -MSG_DEF(JSMSG_DUPLICATE_VARIANT_SUBTAG, 1, JSEXN_RANGEERR, "duplicate variant subtag: {0}") -MSG_DEF(JSMSG_INTERNAL_INTL_ERROR, 0, JSEXN_ERR, "internal error while computing Intl data") -MSG_DEF(JSMSG_INVALID_CURRENCY_CODE, 1, JSEXN_RANGEERR, "invalid currency code in NumberFormat(): {0}") -MSG_DEF(JSMSG_INVALID_UNIT_IDENTIFIER, 1, JSEXN_RANGEERR, "invalid unit identifier in NumberFormat(): {0}") -MSG_DEF(JSMSG_INVALID_DIGITS_VALUE, 1, JSEXN_RANGEERR, "invalid digits value: {0}") -MSG_DEF(JSMSG_INVALID_KEYS_TYPE, 0, JSEXN_TYPEERR, "calendar info keys must be an object or undefined") -MSG_DEF(JSMSG_INVALID_KEY, 1, JSEXN_RANGEERR, "invalid key: {0}") -MSG_DEF(JSMSG_INVALID_LANGUAGE_TAG, 1, JSEXN_RANGEERR, "invalid language tag: {0}") -MSG_DEF(JSMSG_INVALID_LOCALES_ELEMENT, 0, JSEXN_TYPEERR, "invalid element in locales argument") -MSG_DEF(JSMSG_INVALID_LOCALE_MATCHER, 1, JSEXN_RANGEERR, "invalid locale matcher in supportedLocalesOf(): {0}") -MSG_DEF(JSMSG_INVALID_OPTION_VALUE, 2, JSEXN_RANGEERR, "invalid value {1} for option {0}") -MSG_DEF(JSMSG_INVALID_TIME_ZONE, 1, JSEXN_RANGEERR, "invalid time zone in DateTimeFormat(): {0}") -MSG_DEF(JSMSG_UNDEFINED_CURRENCY, 0, JSEXN_TYPEERR, "undefined currency in NumberFormat() with currency style") -MSG_DEF(JSMSG_UNDEFINED_UNIT, 0, JSEXN_TYPEERR, "undefined unit in NumberFormat() with unit style") - -// RegExp -MSG_DEF(JSMSG_BACK_REF_OUT_OF_RANGE, 0, JSEXN_SYNTAXERR, "back reference out of range in regular expression") -MSG_DEF(JSMSG_BAD_CLASS_RANGE, 0, JSEXN_SYNTAXERR, "invalid range in character class") -MSG_DEF(JSMSG_ESCAPE_AT_END_OF_REGEXP, 0, JSEXN_SYNTAXERR, "\\ at end of pattern") -MSG_DEF(JSMSG_EXEC_NOT_OBJORNULL, 0, JSEXN_TYPEERR, "RegExp exec method should return object or null") -MSG_DEF(JSMSG_INVALID_DECIMAL_ESCAPE, 0, JSEXN_SYNTAXERR, "invalid decimal escape in regular expression") -MSG_DEF(JSMSG_INVALID_GROUP, 0, JSEXN_SYNTAXERR, "invalid regexp group") -MSG_DEF(JSMSG_INVALID_IDENTITY_ESCAPE, 0, JSEXN_SYNTAXERR, "invalid identity escape in regular expression") -MSG_DEF(JSMSG_INVALID_UNICODE_ESCAPE, 0, JSEXN_SYNTAXERR, "invalid unicode escape in regular expression") -MSG_DEF(JSMSG_MISSING_PAREN, 0, JSEXN_SYNTAXERR, "unterminated parenthetical") -MSG_DEF(JSMSG_NEWREGEXP_FLAGGED, 0, JSEXN_TYPEERR, "can't supply flags when constructing one RegExp from another") -MSG_DEF(JSMSG_NOTHING_TO_REPEAT, 0, JSEXN_SYNTAXERR, "nothing to repeat") -MSG_DEF(JSMSG_NUMBERS_OUT_OF_ORDER, 0, JSEXN_SYNTAXERR, "numbers out of order in {} quantifier.") -MSG_DEF(JSMSG_RANGE_WITH_CLASS_ESCAPE, 0, JSEXN_SYNTAXERR, "character class escape cannot be used in class range in regular expression") -MSG_DEF(JSMSG_RAW_BRACE_IN_REGEXP, 0, JSEXN_SYNTAXERR, "raw brace is not allowed in regular expression with unicode flag") -MSG_DEF(JSMSG_RAW_BRACKET_IN_REGEXP, 0, JSEXN_SYNTAXERR, "raw bracket is not allowed in regular expression with unicode flag") -MSG_DEF(JSMSG_TOO_MANY_PARENS, 0, JSEXN_INTERNALERR, "too many parentheses in regular expression") -MSG_DEF(JSMSG_UNICODE_OVERFLOW, 1, JSEXN_SYNTAXERR, "Unicode codepoint must not be greater than 0x10FFFF in {0}") -MSG_DEF(JSMSG_UNMATCHED_RIGHT_PAREN, 0, JSEXN_SYNTAXERR, "unmatched ) in regular expression") -MSG_DEF(JSMSG_UNTERM_CLASS, 0, JSEXN_SYNTAXERR, "unterminated character class") -MSG_DEF(JSMSG_INVALID_PROPERTY_NAME, 0, JSEXN_SYNTAXERR, "invalid property name in regular expression") -MSG_DEF(JSMSG_INVALID_CLASS_PROPERTY_NAME, 0, JSEXN_SYNTAXERR, "invalid class property name in regular expression") -MSG_DEF(JSMSG_INCOMPLETE_QUANTIFIER, 0, JSEXN_SYNTAXERR, "incomplete quantifier in regular expression") -MSG_DEF(JSMSG_INVALID_QUANTIFIER, 0, JSEXN_SYNTAXERR, "invalid quantifier in regular expression") -MSG_DEF(JSMSG_INVALID_CAPTURE_NAME, 0, JSEXN_SYNTAXERR, "invalid capture group name in regular expression") -MSG_DEF(JSMSG_DUPLICATE_CAPTURE_NAME, 0, JSEXN_SYNTAXERR, "duplicate capture group name in regular expression") -MSG_DEF(JSMSG_INVALID_NAMED_REF, 0, JSEXN_SYNTAXERR, "invalid named reference in regular expression") -MSG_DEF(JSMSG_INVALID_NAMED_CAPTURE_REF, 0, JSEXN_SYNTAXERR, "invalid named capture reference in regular expression") - -// Self-hosting -MSG_DEF(JSMSG_DEFAULT_LOCALE_ERROR, 0, JSEXN_ERR, "internal error getting the default locale") -MSG_DEF(JSMSG_NO_SUCH_SELF_HOSTED_PROP,1, JSEXN_ERR, "No such property on self-hosted object: {0}") - -// Typed object -MSG_DEF(JSMSG_INVALID_PROTOTYPE, 0, JSEXN_TYPEERR, "prototype field is not an object") -MSG_DEF(JSMSG_TYPEDOBJECT_BAD_ARGS, 0, JSEXN_TYPEERR, "invalid arguments") -MSG_DEF(JSMSG_TYPEDOBJECT_BINARYARRAY_BAD_INDEX, 0, JSEXN_RANGEERR, "invalid or out-of-range index") -MSG_DEF(JSMSG_TYPEDOBJECT_HANDLE_UNATTACHED, 0, JSEXN_TYPEERR, "handle unattached") -MSG_DEF(JSMSG_TYPEDOBJECT_STRUCTTYPE_BAD_ARGS, 0, JSEXN_RANGEERR, "invalid field descriptor") -MSG_DEF(JSMSG_TYPEDOBJECT_STRUCTTYPE_NOT_CALLABLE, 0, JSEXN_TYPEERR, "not callable") -MSG_DEF(JSMSG_TYPEDOBJECT_TOO_BIG, 0, JSEXN_ERR, "Type is too large to allocate") -MSG_DEF(JSMSG_TYPEDOBJECT_SETTING_IMMUTABLE, 0, JSEXN_ERR, "setting immutable field") -MSG_DEF(JSMSG_TYPEDOBJECT_NOT_CONSTRUCTIBLE, 0, JSEXN_TYPEERR, "not constructible") - -// Array -MSG_DEF(JSMSG_TOO_LONG_ARRAY, 0, JSEXN_TYPEERR, "Too long array") - -// Typed array -MSG_DEF(JSMSG_BAD_INDEX, 0, JSEXN_RANGEERR, "invalid or out-of-range index") -MSG_DEF(JSMSG_NON_ARRAY_BUFFER_RETURNED, 0, JSEXN_TYPEERR, "expected ArrayBuffer, but species constructor returned non-ArrayBuffer") -MSG_DEF(JSMSG_SAME_ARRAY_BUFFER_RETURNED, 0, JSEXN_TYPEERR, "expected different ArrayBuffer, but species constructor returned same ArrayBuffer") -MSG_DEF(JSMSG_SHORT_ARRAY_BUFFER_RETURNED, 2, JSEXN_TYPEERR, "expected ArrayBuffer with at least {0} bytes, but species constructor returns ArrayBuffer with {1} bytes") -MSG_DEF(JSMSG_TYPED_ARRAY_BAD_ARGS, 0, JSEXN_TYPEERR, "invalid arguments") -MSG_DEF(JSMSG_TYPED_ARRAY_NEGATIVE_ARG,1, JSEXN_RANGEERR, "argument {0} must be >= 0") -MSG_DEF(JSMSG_TYPED_ARRAY_DETACHED, 0, JSEXN_TYPEERR, "attempting to access detached ArrayBuffer") -MSG_DEF(JSMSG_TYPED_ARRAY_CONSTRUCT_BOUNDS, 0, JSEXN_RANGEERR, "attempting to construct out-of-bounds TypedArray on ArrayBuffer") -MSG_DEF(JSMSG_TYPED_ARRAY_CALL_OR_CONSTRUCT, 1, JSEXN_TYPEERR, "cannot directly {0} builtin %TypedArray%") -MSG_DEF(JSMSG_NON_TYPED_ARRAY_RETURNED, 0, JSEXN_TYPEERR, "constructor didn't return TypedArray object") -MSG_DEF(JSMSG_SHORT_TYPED_ARRAY_RETURNED, 2, JSEXN_TYPEERR, "expected TypedArray of at least length {0}, but constructor returned TypedArray of length {1}") -MSG_DEF(JSMSG_TYPED_ARRAY_NOT_COMPATIBLE, 2, JSEXN_TYPEERR, "{0} elements are incompatible with {1}") - -// Shared array buffer -MSG_DEF(JSMSG_SHARED_ARRAY_BAD_LENGTH, 0, JSEXN_RANGEERR, "length argument out of range") -MSG_DEF(JSMSG_NON_SHARED_ARRAY_BUFFER_RETURNED, 0, JSEXN_TYPEERR, "expected SharedArrayBuffer, but species constructor returned non-SharedArrayBuffer") -MSG_DEF(JSMSG_SAME_SHARED_ARRAY_BUFFER_RETURNED, 0, JSEXN_TYPEERR, "expected different SharedArrayBuffer, but species constructor returned same SharedArrayBuffer") -MSG_DEF(JSMSG_SHORT_SHARED_ARRAY_BUFFER_RETURNED, 2, JSEXN_TYPEERR, "expected SharedArrayBuffer with at least {0} bytes, but species constructor returns SharedArrayBuffer with {1} bytes") - -// Reflect -MSG_DEF(JSMSG_BAD_PARSE_NODE, 0, JSEXN_INTERNALERR, "bad parse node") - -// Symbol -MSG_DEF(JSMSG_SYMBOL_TO_STRING, 0, JSEXN_TYPEERR, "can't convert symbol to string") -MSG_DEF(JSMSG_SYMBOL_TO_NUMBER, 0, JSEXN_TYPEERR, "can't convert symbol to number") - -// Atomics and futexes -MSG_DEF(JSMSG_ATOMICS_BAD_ARRAY, 0, JSEXN_TYPEERR, "invalid array type for the operation") -MSG_DEF(JSMSG_ATOMICS_TOO_LONG, 0, JSEXN_RANGEERR, "timeout value too large") -MSG_DEF(JSMSG_ATOMICS_WAIT_NOT_ALLOWED, 0, JSEXN_TYPEERR, "waiting is not allowed on this thread") - -// XPConnect wrappers and DOM bindings -MSG_DEF(JSMSG_CANT_SET_INTERPOSED, 1, JSEXN_TYPEERR, "unable to set interposed data property '{0}'") -MSG_DEF(JSMSG_CANT_DEFINE_WINDOW_ELEMENT, 0, JSEXN_TYPEERR, "can't define elements on a Window object") -MSG_DEF(JSMSG_CANT_DELETE_WINDOW_ELEMENT, 0, JSEXN_TYPEERR, "can't delete elements from a Window object") -MSG_DEF(JSMSG_CANT_DELETE_WINDOW_NAMED_PROPERTY, 1, JSEXN_TYPEERR, "can't delete property {0} from window's named properties object") -MSG_DEF(JSMSG_CANT_PREVENT_EXTENSIONS, 0, JSEXN_TYPEERR, "can't prevent extensions on this proxy object") -MSG_DEF(JSMSG_CANT_DEFINE_WINDOW_NC, 0, JSEXN_TYPEERR, "can't define non-configurable property on WindowProxy") -MSG_DEF(JSMSG_NO_NAMED_SETTER, 2, JSEXN_TYPEERR, "{0} doesn't have a named property setter for '{1}'") -MSG_DEF(JSMSG_NO_INDEXED_SETTER, 2, JSEXN_TYPEERR, "{0} doesn't have an indexed property setter for '{1}'") -MSG_DEF(JSMSG_NOT_DATA_DESCRIPTOR, 2, JSEXN_TYPEERR, "can't define a getter/setter for element '{1}' of {0} object") - -// Super -MSG_DEF(JSMSG_CANT_DELETE_SUPER, 0, JSEXN_REFERENCEERR, "invalid delete involving 'super'") -MSG_DEF(JSMSG_REINIT_THIS, 0, JSEXN_REFERENCEERR, "super() called twice in derived class constructor") - -// Modules -MSG_DEF(JSMSG_BAD_DEFAULT_EXPORT, 0, JSEXN_SYNTAXERR, "default export cannot be provided by export *") -MSG_DEF(JSMSG_MISSING_INDIRECT_EXPORT, 0, JSEXN_SYNTAXERR, "indirect export not found") -MSG_DEF(JSMSG_AMBIGUOUS_INDIRECT_EXPORT, 0, JSEXN_SYNTAXERR, "ambiguous indirect export") -MSG_DEF(JSMSG_MISSING_IMPORT, 0, JSEXN_SYNTAXERR, "import not found") -MSG_DEF(JSMSG_AMBIGUOUS_IMPORT, 0, JSEXN_SYNTAXERR, "ambiguous import") -MSG_DEF(JSMSG_MISSING_NAMESPACE_EXPORT, 0, JSEXN_SYNTAXERR, "export not found for namespace") -MSG_DEF(JSMSG_MISSING_EXPORT, 1, JSEXN_SYNTAXERR, "local binding for export '{0}' not found") -MSG_DEF(JSMSG_BAD_MODULE_STATUS, 0, JSEXN_INTERNALERR, "module record has unexpected status") -MSG_DEF(JSMSG_DYNAMIC_IMPORT_FAILED, 0, JSEXN_TYPEERR, "error loading dynamically imported module") -MSG_DEF(JSMSG_BAD_MODULE_SPECIFIER, 1, JSEXN_TYPEERR, "error resolving module specifier '{0}'") - -// Promise -MSG_DEF(JSMSG_CANNOT_RESOLVE_PROMISE_WITH_ITSELF, 0, JSEXN_TYPEERR, "A promise cannot be resolved with itself.") -MSG_DEF(JSMSG_PROMISE_CAPABILITY_HAS_SOMETHING_ALREADY, 0, JSEXN_TYPEERR, "GetCapabilitiesExecutor function already invoked with non-undefined values.") -MSG_DEF(JSMSG_PROMISE_RESOLVE_FUNCTION_NOT_CALLABLE, 0, JSEXN_TYPEERR, "A Promise subclass passed a non-callable value as the resolve function.") -MSG_DEF(JSMSG_PROMISE_REJECT_FUNCTION_NOT_CALLABLE, 0, JSEXN_TYPEERR, "A Promise subclass passed a non-callable value as the reject function.") -MSG_DEF(JSMSG_PROMISE_ERROR_IN_WRAPPED_REJECTION_REASON,0, JSEXN_INTERNALERR, "Promise rejection value is a non-unwrappable cross-compartment wrapper.") -MSG_DEF(JSMSG_PROMISE_ANY_REJECTION, 0, JSEXN_AGGREGATEERR, "No Promise in Promise.any was resolved") - -// Iterator -MSG_DEF(JSMSG_RETURN_NOT_CALLABLE, 0, JSEXN_TYPEERR, "property 'return' of iterator is not callable") -MSG_DEF(JSMSG_ITERATOR_NO_THROW, 0, JSEXN_TYPEERR, "iterator does not have a 'throw' method") - -// Async Function -MSG_DEF(JSMSG_UNHANDLABLE_PROMISE_REJECTION_WARNING, 0, JSEXN_WARN, "unhandlable error after resolving async function's promise") - -// Async Iteration -MSG_DEF(JSMSG_FOR_AWAIT_NOT_OF, 0, JSEXN_SYNTAXERR, "'for await' loop should be used with 'of'") -MSG_DEF(JSMSG_NOT_AN_ASYNC_GENERATOR, 0, JSEXN_TYPEERR, "Not an async generator") -MSG_DEF(JSMSG_NOT_AN_ASYNC_ITERATOR, 0, JSEXN_TYPEERR, "Not an async from sync iterator") -MSG_DEF(JSMSG_GET_ASYNC_ITER_RETURNED_PRIMITIVE, 0, JSEXN_TYPEERR, "[Symbol.asyncIterator]() returned a non-object value") - -// ReadableStream -MSG_DEF(JSMSG_READABLESTREAM_UNDERLYINGSOURCE_TYPE_WRONG,0, JSEXN_RANGEERR,"'underlyingSource.type' must be \"bytes\" or undefined.") -MSG_DEF(JSMSG_READABLESTREAM_BYTES_TYPE_NOT_IMPLEMENTED, 0, JSEXN_RANGEERR,"support for 'new ReadableStream({ type: \"bytes\" })' is not yet implemented") -MSG_DEF(JSMSG_READABLESTREAM_BYOB_READER_FOR_NON_BYTE_STREAM,0,JSEXN_TYPEERR,"can't get a BYOB reader for a non-byte stream") -MSG_DEF(JSMSG_READABLESTREAM_INVALID_READER_MODE, 0, JSEXN_RANGEERR,"'mode' must be \"byob\" or undefined.") -MSG_DEF(JSMSG_NUMBER_MUST_BE_FINITE_NON_NEGATIVE, 1, JSEXN_RANGEERR, "'{0}' must be a finite, non-negative number.") -MSG_DEF(JSMSG_READABLEBYTESTREAMCONTROLLER_INVALID_BYTESWRITTEN, 0, JSEXN_RANGEERR, "'bytesWritten' exceeds remaining length.") -MSG_DEF(JSMSG_READABLEBYTESTREAMCONTROLLER_INVALID_VIEW_SIZE, 0, JSEXN_RANGEERR, "view size does not match requested data.") -MSG_DEF(JSMSG_READABLEBYTESTREAMCONTROLLER_INVALID_VIEW_OFFSET, 0, JSEXN_RANGEERR, "view offset does not match requested position.") -MSG_DEF(JSMSG_READABLESTREAM_LOCKED_METHOD, 1, JSEXN_TYPEERR, "'{0}' can't be called on a locked stream.") -MSG_DEF(JSMSG_READABLESTREAM_LOCKED, 0, JSEXN_TYPEERR, "A Reader may only be created for an unlocked ReadableStream.") -MSG_DEF(JSMSG_READABLESTREAM_NOT_BYTE_STREAM_CONTROLLER, 1, JSEXN_TYPEERR, "{0} requires a ReadableByteStreamController.") -MSG_DEF(JSMSG_READABLESTREAM_NOT_DEFAULT_CONTROLLER, 1, JSEXN_TYPEERR, "{0} requires a ReadableStreamDefaultController.") -MSG_DEF(JSMSG_READABLESTREAM_CONTROLLER_SET, 0, JSEXN_TYPEERR, "The ReadableStream already has a controller defined.") -MSG_DEF(JSMSG_READABLESTREAMREADER_NOT_OWNED, 1, JSEXN_TYPEERR, "The ReadableStream reader method '{0}' may only be called on a reader owned by a stream.") -MSG_DEF(JSMSG_READABLESTREAMREADER_NOT_EMPTY, 1, JSEXN_TYPEERR, "The ReadableStream reader method '{0}' may not be called on a reader with read requests.") -MSG_DEF(JSMSG_READABLESTREAMBYOBREADER_READ_EMPTY_VIEW, 0, JSEXN_TYPEERR, "ReadableStreamBYOBReader.read() was passed an empty TypedArrayBuffer view.") -MSG_DEF(JSMSG_READABLESTREAMREADER_RELEASED, 0, JSEXN_TYPEERR, "The ReadableStream reader was released.") -MSG_DEF(JSMSG_READABLESTREAMCONTROLLER_CLOSED, 1, JSEXN_TYPEERR, "'{0}' called on a stream already closing.") -MSG_DEF(JSMSG_READABLESTREAMCONTROLLER_NOT_READABLE, 1, JSEXN_TYPEERR, "'{0}' may only be called on a stream in the 'readable' state.") -MSG_DEF(JSMSG_READABLEBYTESTREAMCONTROLLER_BAD_CHUNKSIZE,0, JSEXN_RANGEERR, "ReadableByteStreamController requires a positive integer or undefined for 'autoAllocateChunkSize'.") -MSG_DEF(JSMSG_READABLEBYTESTREAMCONTROLLER_BAD_CHUNK, 1, JSEXN_TYPEERR, "{0} passed a bad chunk.") -MSG_DEF(JSMSG_READABLEBYTESTREAMCONTROLLER_CLOSE_PENDING_PULL, 0, JSEXN_TYPEERR, "The ReadableByteStreamController cannot be closed while the buffer is being filled.") -MSG_DEF(JSMSG_READABLESTREAMBYOBREQUEST_NO_CONTROLLER, 1, JSEXN_TYPEERR, "ReadableStreamBYOBRequest method '{0}' called on a request with no controller.") -MSG_DEF(JSMSG_READABLESTREAMBYOBREQUEST_RESPOND_CLOSED, 0, JSEXN_TYPEERR, "ReadableStreamBYOBRequest method 'respond' called with non-zero number of bytes with a closed controller.") -MSG_DEF(JSMSG_READABLESTREAM_METHOD_NOT_IMPLEMENTED, 1, JSEXN_TYPEERR, "ReadableStream method {0} not yet implemented") -MSG_DEF(JSMSG_READABLESTREAM_PIPETO_BAD_SIGNAL, 0, JSEXN_TYPEERR, "signal must be either undefined or an AbortSignal") - -// WritableStream -MSG_DEF(JSMSG_READABLESTREAM_UNDERLYINGSINK_TYPE_WRONG, 0, JSEXN_RANGEERR,"'underlyingSink.type' must be undefined.") -MSG_DEF(JSMSG_WRITABLESTREAMWRITER_NOT_OWNED, 1, JSEXN_TYPEERR, "the WritableStream writer method '{0}' may only be called on a writer owned by a stream") -MSG_DEF(JSMSG_WRITABLESTREAM_CLOSED_OR_ERRORED, 0, JSEXN_TYPEERR, "writable stream is already closed or errored") -MSG_DEF(JSMSG_WRITABLESTREAM_RELEASED_DURING_WRITE, 0, JSEXN_TYPEERR, "writer's lock on the stream was released before writing completed") -MSG_DEF(JSMSG_WRITABLESTREAM_WRITE_CLOSING_OR_CLOSED, 0, JSEXN_TYPEERR, "can't write to a stream that's currently closing or already closed") -MSG_DEF(JSMSG_CANT_USE_LOCKED_WRITABLESTREAM, 1, JSEXN_TYPEERR, "can't {0} a WritableStream that's locked to a writer") -MSG_DEF(JSMSG_WRITABLESTREAM_CLOSE_CLOSING_OR_CLOSED, 0, JSEXN_TYPEERR, "can't close a stream that's currently closing or already closed") -MSG_DEF(JSMSG_WRITABLESTREAM_CANT_RELEASE_ALREADY_CLOSED,0, JSEXN_TYPEERR, "writer has already been released and can't be closed") -MSG_DEF(JSMSG_WRITABLESTREAM_ALREADY_LOCKED, 0, JSEXN_TYPEERR, "writable stream is already locked by another writer") -MSG_DEF(JSMSG_READABLESTREAM_NYI, 0, JSEXN_ERR, "full WritableStream support is not yet implemented") - -// Other Stream-related -MSG_DEF(JSMSG_STREAM_INVALID_HIGHWATERMARK, 0, JSEXN_RANGEERR, "'highWaterMark' must be a non-negative, non-NaN number.") -MSG_DEF(JSMSG_STREAM_CONSUME_ERROR, 0, JSEXN_TYPEERR, "error consuming stream body") - -// Response-related -MSG_DEF(JSMSG_ERROR_CONSUMING_RESPONSE, 0, JSEXN_TYPEERR, "there was an error consuming the Response") -MSG_DEF(JSMSG_BAD_RESPONSE_VALUE, 0, JSEXN_TYPEERR, "expected Response or Promise resolving to Response") -MSG_DEF(JSMSG_BAD_RESPONSE_MIME_TYPE, 0, JSEXN_TYPEERR, "Response has unsupported MIME type") -MSG_DEF(JSMSG_BAD_RESPONSE_CORS_SAME_ORIGIN, 0, JSEXN_TYPEERR, "Response.type must be 'basic', 'cors' or 'default'") -MSG_DEF(JSMSG_BAD_RESPONSE_STATUS, 0, JSEXN_TYPEERR, "Response does not have ok status") -MSG_DEF(JSMSG_RESPONSE_ALREADY_CONSUMED, 0, JSEXN_TYPEERR, "Response already consumed") - -// BigInt -MSG_DEF(JSMSG_BIGINT_TO_NUMBER, 0, JSEXN_TYPEERR, "can't convert BigInt to number") -MSG_DEF(JSMSG_NONINTEGER_NUMBER_TO_BIGINT, 1, JSEXN_RANGEERR, "{0} can't be converted to BigInt because it isn't an integer") -MSG_DEF(JSMSG_BIGINT_TOO_LARGE, 0, JSEXN_RANGEERR, "BigInt is too large to allocate") -MSG_DEF(JSMSG_BIGINT_DIVISION_BY_ZERO, 0, JSEXN_RANGEERR, "BigInt division by zero") -MSG_DEF(JSMSG_BIGINT_NEGATIVE_EXPONENT, 0, JSEXN_RANGEERR, "BigInt negative exponent") -MSG_DEF(JSMSG_BIGINT_INVALID_SYNTAX, 0, JSEXN_SYNTAXERR, "invalid BigInt syntax") -MSG_DEF(JSMSG_BIGINT_NOT_SERIALIZABLE, 0, JSEXN_TYPEERR, "BigInt value can't be serialized in JSON") -MSG_DEF(JSMSG_SC_BIGINT_DISABLED, 0, JSEXN_ERR, "BigInt not cloned - feature disabled in receiver") - -// BinAST -MSG_DEF(JSMSG_BINAST, 1, JSEXN_SYNTAXERR, "BinAST Parsing Error: {0}") - -// FinalizationRegistry -MSG_DEF(JSMSG_NOT_A_FINALIZATION_REGISTRY, 1, JSEXN_TYPEERR, "{0} is not a FinalizationRegistry") -MSG_DEF(JSMSG_NOT_A_FINALIZATION_ITERATOR, 1, JSEXN_TYPEERR, "{0} is not a FinalizationRegistryCleanupIterator") -MSG_DEF(JSMSG_BAD_HELD_VALUE, 0, JSEXN_TYPEERR, "The heldValue parameter passed to FinalizationRegistry.register must not be the same as the target parameter") -MSG_DEF(JSMSG_BAD_UNREGISTER_TOKEN, 1, JSEXN_TYPEERR, "Invalid unregister token passed to {0}") -MSG_DEF(JSMSG_STALE_FINALIZATION_REGISTRY_ITERATOR, 0, JSEXN_TYPEERR, "Can't use stale finalization registry iterator") -MSG_DEF(JSMSG_BAD_CLEANUP_STATE, 0, JSEXN_TYPEERR, "Can't call FinalizeRegistry.cleanupSome while cleanup is in progress") - -// WeakRef -MSG_DEF(JSMSG_NOT_A_WEAK_REF, 1, JSEXN_TYPEERR, "{0} is not a WeakRef") Index: libraries/source/spidermonkey/include-win32-debug/js/AllocPolicy.h =================================================================== --- /dev/null +++ libraries/source/spidermonkey/include-win32-debug/js/AllocPolicy.h @@ -1,192 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- - * vim: set ts=8 sts=2 et sw=2 tw=80: - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* - * JS allocation policies. - * - * The allocators here are for system memory with lifetimes which are not - * managed by the GC. See the comment at the top of vm/MallocProvider.h. - */ - -#ifndef js_AllocPolicy_h -#define js_AllocPolicy_h - -#include "js/TypeDecls.h" -#include "js/Utility.h" - -extern MOZ_COLD JS_PUBLIC_API void JS_ReportOutOfMemory(JSContext* cx); - -namespace js { - -enum class AllocFunction { Malloc, Calloc, Realloc }; - -/* Base class allocation policies providing allocation methods. */ -class AllocPolicyBase { - public: - template - T* maybe_pod_arena_malloc(arena_id_t arenaId, size_t numElems) { - return js_pod_arena_malloc(arenaId, numElems); - } - template - T* maybe_pod_arena_calloc(arena_id_t arenaId, size_t numElems) { - return js_pod_arena_calloc(arenaId, numElems); - } - template - T* maybe_pod_arena_realloc(arena_id_t arenaId, T* p, size_t oldSize, - size_t newSize) { - return js_pod_arena_realloc(arenaId, p, oldSize, newSize); - } - template - T* pod_arena_malloc(arena_id_t arenaId, size_t numElems) { - return maybe_pod_arena_malloc(arenaId, numElems); - } - template - T* pod_arena_calloc(arena_id_t arenaId, size_t numElems) { - return maybe_pod_arena_calloc(arenaId, numElems); - } - template - T* pod_arena_realloc(arena_id_t arenaId, T* p, size_t oldSize, - size_t newSize) { - return maybe_pod_arena_realloc(arenaId, p, oldSize, newSize); - } - - template - T* maybe_pod_malloc(size_t numElems) { - return maybe_pod_arena_malloc(js::MallocArena, numElems); - } - template - T* maybe_pod_calloc(size_t numElems) { - return maybe_pod_arena_calloc(js::MallocArena, numElems); - } - template - T* maybe_pod_realloc(T* p, size_t oldSize, size_t newSize) { - return maybe_pod_arena_realloc(js::MallocArena, p, oldSize, newSize); - } - template - T* pod_malloc(size_t numElems) { - return pod_arena_malloc(js::MallocArena, numElems); - } - template - T* pod_calloc(size_t numElems) { - return pod_arena_calloc(js::MallocArena, numElems); - } - template - T* pod_realloc(T* p, size_t oldSize, size_t newSize) { - return pod_arena_realloc(js::MallocArena, p, oldSize, newSize); - } - - template - void free_(T* p, size_t numElems = 0) { - js_free(p); - } -}; - -/* Policy for using system memory functions and doing no error reporting. */ -class SystemAllocPolicy : public AllocPolicyBase { - public: - void reportAllocOverflow() const {} - bool checkSimulatedOOM() const { return !js::oom::ShouldFailWithOOM(); } -}; - -MOZ_COLD JS_FRIEND_API void ReportOutOfMemory(JSContext* cx); - -/* - * Allocation policy that calls the system memory functions and reports errors - * to the context. Since the JSContext given on construction is stored for - * the lifetime of the container, this policy may only be used for containers - * whose lifetime is a shorter than the given JSContext. - * - * FIXME bug 647103 - rewrite this in terms of temporary allocation functions, - * not the system ones. - */ -class TempAllocPolicy : public AllocPolicyBase { - JSContext* const cx_; - - /* - * Non-inline helper to call JSRuntime::onOutOfMemory with minimal - * code bloat. - */ - void* onOutOfMemory(arena_id_t arenaId, AllocFunction allocFunc, - size_t nbytes, void* reallocPtr = nullptr); - - template - T* onOutOfMemoryTyped(arena_id_t arenaId, AllocFunction allocFunc, - size_t numElems, void* reallocPtr = nullptr) { - size_t bytes; - if (MOZ_UNLIKELY(!CalculateAllocSize(numElems, &bytes))) { - return nullptr; - } - return static_cast( - onOutOfMemory(arenaId, allocFunc, bytes, reallocPtr)); - } - - public: - MOZ_IMPLICIT TempAllocPolicy(JSContext* cx) : cx_(cx) {} - - template - T* pod_arena_malloc(arena_id_t arenaId, size_t numElems) { - T* p = this->maybe_pod_arena_malloc(arenaId, numElems); - if (MOZ_UNLIKELY(!p)) { - p = onOutOfMemoryTyped(arenaId, AllocFunction::Malloc, numElems); - } - return p; - } - - template - T* pod_arena_calloc(arena_id_t arenaId, size_t numElems) { - T* p = this->maybe_pod_arena_calloc(arenaId, numElems); - if (MOZ_UNLIKELY(!p)) { - p = onOutOfMemoryTyped(arenaId, AllocFunction::Calloc, numElems); - } - return p; - } - - template - T* pod_arena_realloc(arena_id_t arenaId, T* prior, size_t oldSize, - size_t newSize) { - T* p2 = this->maybe_pod_arena_realloc(arenaId, prior, oldSize, newSize); - if (MOZ_UNLIKELY(!p2)) { - p2 = onOutOfMemoryTyped(arenaId, AllocFunction::Realloc, newSize, - prior); - } - return p2; - } - - template - T* pod_malloc(size_t numElems) { - return pod_arena_malloc(js::MallocArena, numElems); - } - - template - T* pod_calloc(size_t numElems) { - return pod_arena_calloc(js::MallocArena, numElems); - } - - template - T* pod_realloc(T* prior, size_t oldSize, size_t newSize) { - return pod_arena_realloc(js::MallocArena, prior, oldSize, newSize); - } - - template - void free_(T* p, size_t numElems = 0) { - js_free(p); - } - - void reportAllocOverflow() const; - - bool checkSimulatedOOM() const { - if (js::oom::ShouldFailWithOOM()) { - ReportOutOfMemory(cx_); - return false; - } - - return true; - } -}; - -} /* namespace js */ - -#endif /* js_AllocPolicy_h */ Index: libraries/source/spidermonkey/include-win32-debug/js/AllocationRecording.h =================================================================== --- /dev/null +++ libraries/source/spidermonkey/include-win32-debug/js/AllocationRecording.h @@ -1,72 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- - * vim: set ts=8 sts=2 et sw=2 tw=80: - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef js_AllocationRecording_h -#define js_AllocationRecording_h - -#include "js/TypeDecls.h" -#include "js/Utility.h" - -namespace JS { - -/** - * This struct holds the information needed to create a profiler marker payload - * that can represent a JS allocation. It translates JS engine specific classes, - * into something that can be used in the profiler. - */ -struct RecordAllocationInfo { - RecordAllocationInfo(const char16_t* typeName, const char* className, - const char16_t* descriptiveTypeName, - const char* coarseType, uint64_t size, bool inNursery) - : typeName(typeName), - className(className), - descriptiveTypeName(descriptiveTypeName), - coarseType(coarseType), - size(size), - inNursery(inNursery) {} - - // These pointers are borrowed from the UbiNode, and can point to live data. - // It is important for the consumers of this struct to correctly - // duplicate the strings to take ownership of them. - const char16_t* typeName; - const char* className; - const char16_t* descriptiveTypeName; - - // The coarseType points to a string literal, so does not need to be - // duplicated. - const char* coarseType; - - // The size in bytes of the allocation. - uint64_t size; - - // Whether or not the allocation is in the nursery or not. - bool inNursery; -}; - -typedef void (*RecordAllocationsCallback)(RecordAllocationInfo&& info); - -/** - * Enable recording JS allocations. This feature hooks into the object creation - * in the JavaScript engine, and reports back the allocation info through the - * callback. This allocation tracking is turned on for all encountered realms. - * The JS Debugger API can also turn on allocation tracking with its own - * probability. If both allocation tracking mechanisms are turned on at the same - * time, the Debugger's probability defers to the EnableRecordingAllocations's - * probability setting. - */ -JS_FRIEND_API void EnableRecordingAllocations( - JSContext* cx, RecordAllocationsCallback callback, double probability); - -/** - * Turn off JS allocation recording. If any JS Debuggers are also recording - * allocations, then the probability will be reset to the Debugger's desired - * setting. - */ -JS_FRIEND_API void DisableRecordingAllocations(JSContext* cx); - -} // namespace JS - -#endif /* js_AllocationRecording_h */ Index: libraries/source/spidermonkey/include-win32-debug/js/Array.h =================================================================== --- /dev/null +++ libraries/source/spidermonkey/include-win32-debug/js/Array.h @@ -1,121 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* Array-related operations. */ - -#ifndef js_Array_h -#define js_Array_h - -#include // size_t -#include // uint32_t - -#include "jstypes.h" // JS_PUBLIC_API - -#include "js/RootingAPI.h" // JS::Handle -#include "js/Value.h" // JS::Value - -struct JS_PUBLIC_API JSContext; -class JS_PUBLIC_API JSObject; - -namespace JS { - -class HandleValueArray; - -/** - * Create an Array from the current realm with the given contents. - */ -extern JS_PUBLIC_API JSObject* NewArrayObject(JSContext* cx, - const HandleValueArray& contents); - -/** - * Create an Array from the current realm with the given length and allocate - * memory for all its elements. (The elements nonetheless will not exist as - * properties on the returned array until values have been assigned to them.) - */ -extern JS_PUBLIC_API JSObject* NewArrayObject(JSContext* cx, size_t length); - -/** - * Determine whether |value| is an Array object or a wrapper around one. (An - * ES6 proxy whose target is an Array object, e.g. - * |var target = [], handler = {}; Proxy.revocable(target, handler).proxy|, is - * not considered to be an Array.) - * - * On success set |*isArray| accordingly and return true; on failure return - * false. - */ -extern JS_PUBLIC_API bool IsArrayObject(JSContext* cx, Handle value, - bool* isArray); - -/** - * Determine whether |obj| is an Array object or a wrapper around one. (An - * ES6 proxy whose target is an Array object, e.g. - * |var target = [], handler = {}; Proxy.revocable(target, handler).proxy|, is - * not considered to be an Array.) - * - * On success set |*isArray| accordingly and return true; on failure return - * false. - */ -extern JS_PUBLIC_API bool IsArrayObject(JSContext* cx, Handle obj, - bool* isArray); - -/** - * Store |*lengthp = ToLength(obj.length)| and return true on success, else - * return false. - * - * |ToLength| converts its input to an integer usable to index an - * array-like object. - * - * If |obj| is an Array, this overall operation is the same as getting - * |obj.length|. - */ -extern JS_PUBLIC_API bool GetArrayLength(JSContext* cx, Handle obj, - uint32_t* lengthp); - -/** - * Perform |obj.length = length| as if in strict mode code, with a fast path for - * the case where |obj| is an Array. - * - * This operation is exactly and only assigning to a "length" property. In - * general, it can invoke an existing "length" setter, throw if the property is - * non-writable, or do anything else a property-set operation might do. - */ -extern JS_PUBLIC_API bool SetArrayLength(JSContext* cx, Handle obj, - uint32_t length); - -/** - * The answer to a successful query as to whether an object is an Array per - * ES6's internal |IsArray| operation (as exposed by |Array.isArray|). - */ -enum class IsArrayAnswer { Array, NotArray, RevokedProxy }; - -/** - * ES6 7.2.2. - * - * Returns false on failure, otherwise returns true and sets |*isArray| - * indicating whether the object passes ECMAScript's IsArray test. This is the - * same test performed by |Array.isArray|. - * - * This is NOT the same as asking whether |obj| is an Array or a wrapper around - * one. If |obj| is a proxy created by |Proxy.revocable()| and has been - * revoked, or if |obj| is a proxy whose target (at any number of hops) is a - * revoked proxy, this method throws a TypeError and returns false. - */ -extern JS_PUBLIC_API bool IsArray(JSContext* cx, Handle obj, - bool* isArray); - -/** - * Identical to IsArray above, but the nature of the object (if successfully - * determined) is communicated via |*answer|. In particular this method - * returns true and sets |*answer = IsArrayAnswer::RevokedProxy| when called on - * a revoked proxy. - * - * Most users will want the overload above, not this one. - */ -extern JS_PUBLIC_API bool IsArray(JSContext* cx, Handle obj, - IsArrayAnswer* answer); - -} // namespace JS - -#endif // js_Array_h Index: libraries/source/spidermonkey/include-win32-debug/js/ArrayBuffer.h =================================================================== --- /dev/null +++ libraries/source/spidermonkey/include-win32-debug/js/ArrayBuffer.h @@ -1,264 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* ArrayBuffer functionality. */ - -#ifndef js_ArrayBuffer_h -#define js_ArrayBuffer_h - -#include // size_t -#include // uint32_t - -#include "jstypes.h" // JS_PUBLIC_API - -#include "js/GCAPI.h" // JS::AutoRequireNoGC -#include "js/RootingAPI.h" // JS::Handle - -struct JS_PUBLIC_API JSContext; -class JS_PUBLIC_API JSObject; - -namespace JS { - -// CREATION - -/** - * Create a new ArrayBuffer with the given byte length. - */ -extern JS_PUBLIC_API JSObject* NewArrayBuffer(JSContext* cx, uint32_t nbytes); - -/** - * Create a new ArrayBuffer with the given |contents|, which may be null only - * if |nbytes == 0|. |contents| must be allocated compatible with deallocation - * by |JS_free|. - * - * If and only if an ArrayBuffer is successfully created and returned, - * ownership of |contents| is transferred to the new ArrayBuffer. - * - * Care must be taken that |nbytes| bytes of |content| remain valid for the - * duration of this call. In particular, passing the length/pointer of existing - * typed array or ArrayBuffer data is generally unsafe: if a GC occurs during a - * call to this function, it could move those contents to a different location - * and invalidate the provided pointer. - */ -extern JS_PUBLIC_API JSObject* NewArrayBufferWithContents(JSContext* cx, - size_t nbytes, - void* contents); - -/** - * Create a new ArrayBuffer, whose bytes are set to the values of the bytes in - * the provided ArrayBuffer. - * - * |maybeArrayBuffer| is asserted to be non-null. An error is thrown if - * |maybeArrayBuffer| would fail the |IsArrayBufferObject| test given further - * below or if |maybeArrayBuffer| is detached. - * - * |maybeArrayBuffer| may store its contents in any fashion (i.e. it doesn't - * matter whether |maybeArrayBuffer| was allocated using |JS::NewArrayBuffer|, - * |JS::NewExternalArrayBuffer|, or any other ArrayBuffer-allocating function). - * - * The newly-created ArrayBuffer is effectively creatd as if by - * |JS::NewArrayBufferWithContents| passing in |maybeArrayBuffer|'s internal - * data pointer and length, in a manner safe against |maybeArrayBuffer|'s data - * being moved around by the GC. In particular, the new ArrayBuffer will not - * behave like one created for WASM or asm.js, so it *can* be detached. - */ -extern JS_PUBLIC_API JSObject* CopyArrayBuffer( - JSContext* cx, JS::Handle maybeArrayBuffer); - -using BufferContentsFreeFunc = void (*)(void* contents, void* userData); - -/** - * Create a new ArrayBuffer with the given contents. The contents must not be - * modified by any other code, internal or external. - * - * When the ArrayBuffer is ready to be disposed of, `freeFunc(contents, - * freeUserData)` will be called to release the ArrayBuffer's reference on the - * contents. - * - * `freeFunc()` must not call any JSAPI functions that could cause a garbage - * collection. - * - * The caller must keep the buffer alive until `freeFunc()` is called, or, if - * `freeFunc` is null, until the JSRuntime is destroyed. - * - * The caller must not access the buffer on other threads. The JS engine will - * not allow the buffer to be transferred to other threads. If you try to - * transfer an external ArrayBuffer to another thread, the data is copied to a - * new malloc buffer. `freeFunc()` must be threadsafe, and may be called from - * any thread. - * - * This allows ArrayBuffers to be used with embedder objects that use reference - * counting, for example. In that case the caller is responsible - * for incrementing the reference count before passing the contents to this - * function. This also allows using non-reference-counted contents that must be - * freed with some function other than free(). - */ -extern JS_PUBLIC_API JSObject* NewExternalArrayBuffer( - JSContext* cx, size_t nbytes, void* contents, - BufferContentsFreeFunc freeFunc, void* freeUserData = nullptr); - -/** - * Create a new ArrayBuffer with the given non-null |contents|. - * - * Ownership of |contents| remains with the caller: it isn't transferred to the - * returned ArrayBuffer. Callers of this function *must* ensure that they - * perform these two steps, in this order, to properly relinquish ownership of - * |contents|: - * - * 1. Call |JS::DetachArrayBuffer| on the buffer returned by this function. - * (|JS::DetachArrayBuffer| is generally fallible, but a call under these - * circumstances is guaranteed to succeed.) - * 2. |contents| may be deallocated or discarded consistent with the manner - * in which it was allocated. - * - * Do not simply allow the returned buffer to be garbage-collected before - * deallocating |contents|, because in general there is no way to know *when* - * an object is fully garbage-collected to the point where this would be safe. - */ -extern JS_PUBLIC_API JSObject* NewArrayBufferWithUserOwnedContents( - JSContext* cx, size_t nbytes, void* contents); - -/** - * Create a new mapped ArrayBuffer with the given memory mapped contents. It - * must be legal to free the contents pointer by unmapping it. On success, - * ownership is transferred to the new mapped ArrayBuffer. - */ -extern JS_PUBLIC_API JSObject* NewMappedArrayBufferWithContents(JSContext* cx, - size_t nbytes, - void* contents); - -/** - * Create memory mapped ArrayBuffer contents. - * Caller must take care of closing fd after calling this function. - */ -extern JS_PUBLIC_API void* CreateMappedArrayBufferContents(int fd, - size_t offset, - size_t length); - -/** - * Release the allocated resource of mapped ArrayBuffer contents before the - * object is created. - * If a new object has been created by JS::NewMappedArrayBufferWithContents() - * with this content, then JS::DetachArrayBuffer() should be used instead to - * release the resource used by the object. - */ -extern JS_PUBLIC_API void ReleaseMappedArrayBufferContents(void* contents, - size_t length); - -// TYPE TESTING - -/* - * Check whether obj supports the JS::GetArrayBuffer* APIs. Note that this may - * return false if a security wrapper is encountered that denies the unwrapping. - * If this test succeeds, then it is safe to call the various predicate and - * accessor JSAPI calls defined below. - */ -extern JS_PUBLIC_API bool IsArrayBufferObject(JSObject* obj); - -// PREDICATES - -/** - * Check whether the obj is a detached ArrayBufferObject. Note that this may - * return false if a security wrapper is encountered that denies the - * unwrapping. - */ -extern JS_PUBLIC_API bool IsDetachedArrayBufferObject(JSObject* obj); - -/** - * Check whether the obj is ArrayBufferObject and memory mapped. Note that this - * may return false if a security wrapper is encountered that denies the - * unwrapping. - */ -extern JS_PUBLIC_API bool IsMappedArrayBufferObject(JSObject* obj); - -/** - * Return true if the ArrayBuffer |obj| contains any data, i.e. it is not a - * detached ArrayBuffer. (ArrayBuffer.prototype is not an ArrayBuffer.) - * - * |obj| must have passed a JS::IsArrayBufferObject test, or somehow be known - * that it would pass such a test: it is an ArrayBuffer or a wrapper of an - * ArrayBuffer, and the unwrapping will succeed. - */ -extern JS_PUBLIC_API bool ArrayBufferHasData(JSObject* obj); - -// ACCESSORS - -extern JS_PUBLIC_API JSObject* UnwrapArrayBuffer(JSObject* obj); - -/** - * Attempt to unwrap |obj| as an ArrayBuffer. - * - * If |obj| *is* an ArrayBuffer, return it unwrapped and set |*length| and - * |*data| to weakly refer to the ArrayBuffer's contents. - * - * If |obj| isn't an ArrayBuffer, return nullptr and do not modify |*length| or - * |*data|. - */ -extern JS_PUBLIC_API JSObject* GetObjectAsArrayBuffer(JSObject* obj, - uint32_t* length, - uint8_t** data); - -/** - * Return the available byte length of an ArrayBuffer. - * - * |obj| must have passed a JS::IsArrayBufferObject test, or somehow be known - * that it would pass such a test: it is an ArrayBuffer or a wrapper of an - * ArrayBuffer, and the unwrapping will succeed. - */ -extern JS_PUBLIC_API uint32_t GetArrayBufferByteLength(JSObject* obj); - -// This one isn't inlined because there are a bunch of different ArrayBuffer -// classes that would have to be individually handled here. -// -// There is an isShared out argument for API consistency (eases use from DOM). -// It will always be set to false. -extern JS_PUBLIC_API void GetArrayBufferLengthAndData(JSObject* obj, - uint32_t* length, - bool* isSharedMemory, - uint8_t** data); - -/** - * Return a pointer to the start of the data referenced by a typed array. The - * data is still owned by the typed array, and should not be modified on - * another thread. Furthermore, the pointer can become invalid on GC (if the - * data is small and fits inside the array's GC header), so callers must take - * care not to hold on across anything that could GC. - * - * |obj| must have passed a JS::IsArrayBufferObject test, or somehow be known - * that it would pass such a test: it is an ArrayBuffer or a wrapper of an - * ArrayBuffer, and the unwrapping will succeed. - * - * |*isSharedMemory| is always set to false. The argument is present to - * simplify its use from code that also interacts with SharedArrayBuffer. - */ -extern JS_PUBLIC_API uint8_t* GetArrayBufferData(JSObject* obj, - bool* isSharedMemory, - const AutoRequireNoGC&); - -// MUTATORS - -/** - * Detach an ArrayBuffer, causing all associated views to no longer refer to - * the ArrayBuffer's original attached memory. - * - * This function throws only if it is provided a non-ArrayBuffer object or if - * the provided ArrayBuffer is a WASM-backed ArrayBuffer or an ArrayBuffer used - * in asm.js code. - */ -extern JS_PUBLIC_API bool DetachArrayBuffer(JSContext* cx, - Handle obj); - -/** - * Steal the contents of the given ArrayBuffer. The ArrayBuffer has its length - * set to 0 and its contents array cleared. The caller takes ownership of the - * return value and must free it or transfer ownership via - * JS::NewArrayBufferWithContents when done using it. - */ -extern JS_PUBLIC_API void* StealArrayBufferContents(JSContext* cx, - Handle obj); - -} // namespace JS - -#endif /* js_ArrayBuffer_h */ Index: libraries/source/spidermonkey/include-win32-debug/js/ArrayBufferMaybeShared.h =================================================================== --- /dev/null +++ libraries/source/spidermonkey/include-win32-debug/js/ArrayBufferMaybeShared.h @@ -1,94 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/** - * Functions for working with either ArrayBuffer or SharedArrayBuffer objects - * in agnostic fashion. - */ - -#ifndef js_ArrayBufferMaybeShared_h -#define js_ArrayBufferMaybeShared_h - -#include // uint8_t, uint32_t - -#include "jstypes.h" // JS_PUBLIC_API - -struct JS_PUBLIC_API JSContext; -class JS_PUBLIC_API JSObject; - -namespace JS { - -class JS_PUBLIC_API AutoRequireNoGC; - -// TYPE TESTING - -/** - * Check whether obj supports the JS::GetArrayBufferMaybeShared* APIs. Note - * that this may return false if a security wrapper is encountered that denies - * the unwrapping. If this test succeeds, then it is safe to call the various - * predicate and accessor JSAPI calls defined below. - */ -extern JS_PUBLIC_API bool IsArrayBufferObjectMaybeShared(JSObject* obj); - -// ACCESSORS - -/* - * Test for ArrayBufferMaybeShared subtypes and return the unwrapped object if - * so, else nullptr. Never throws. - */ -extern JS_PUBLIC_API JSObject* UnwrapArrayBufferMaybeShared(JSObject* obj); - -/** - * Get the length, sharedness, and data from an ArrayBufferMaybeShared subtypes. - * - * The computed length and data pointer may be invalidated by a GC or by an - * unshared array buffer becoming detached. Callers must take care not to - * perform any actions that could trigger a GC or result in an unshared array - * buffer becoming detached. If such actions nonetheless must be performed, - * callers should perform this call a second time (and sensibly handle results - * that may be different from those returned the first time). (Sharedness is an - * immutable characteristic of an array buffer or shared array buffer, so that - * boolean remains valid across GC or detaching.) - * - * |obj| must be an ArrayBufferMaybeShared subtype: an ArrayBuffer or a - * SharedArrayBuffer. - * - * |*length| will be set to bytes in the buffer. - * - * |*isSharedMemory| will be set to true if it is a SharedArrayBuffer, otherwise - * to false. - * - * |*data| will be set to a pointer to the bytes in the buffer. - */ -extern JS_PUBLIC_API void GetArrayBufferMaybeSharedLengthAndData( - JSObject* obj, uint32_t* length, bool* isSharedMemory, uint8_t** data); - -/** - * Return a pointer to the start of the array buffer's data, and indicate - * whether the data is from a shared array buffer through an outparam. - * - * The returned data pointer may be invalidated by a GC or by an unshared array - * buffer becoming detached. Callers must take care not to perform any actions - * that could trigger a GC or result in an unshared array buffer becoming - * detached. If such actions nonetheless must be performed, callers should - * perform this call a second time (and sensibly handle results that may be - * different from those returned the first time). (Sharedness is an immutable - * characteristic of an array buffer or shared array buffer, so that boolean - * remains valid across GC or detaching.) - * - * |obj| must have passed a JS::IsArrayBufferObjectMaybeShared test, or somehow - * be known that it would pass such a test: it is an ArrayBuffer or - * SharedArrayBuffer or a wrapper of an ArrayBuffer/SharedArrayBuffer, and the - * unwrapping will succeed. - * - * |*isSharedMemory| will be set to true if the typed array maps a - * SharedArrayBuffer, otherwise to false. - */ -extern JS_PUBLIC_API uint8_t* GetArrayBufferMaybeSharedData( - JSObject* obj, bool* isSharedMemory, const AutoRequireNoGC&); - -} // namespace JS - -#endif /* js_ArrayBufferMaybeShared_h */ Index: libraries/source/spidermonkey/include-win32-debug/js/BigInt.h =================================================================== --- /dev/null +++ libraries/source/spidermonkey/include-win32-debug/js/BigInt.h @@ -1,139 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* BigInt. */ - -#ifndef js_BigInt_h -#define js_BigInt_h - -#include "mozilla/Range.h" // mozilla::Range - -#include // std::numeric_limits -#include // int64_t, uint64_t -#include // std::enable_if_t, std::{true,false}_type, std::is_{integral,signed,unsigned}_v -#include // std::declval - -#include "jstypes.h" // JS_PUBLIC_API -#include "js/RootingAPI.h" // JS::Handle -#include "js/Value.h" // JS::Value - -struct JS_PUBLIC_API JSContext; - -namespace JS { - -class JS_PUBLIC_API BigInt; - -namespace detail { - -extern JS_PUBLIC_API BigInt* BigIntFromInt64(JSContext* cx, int64_t num); -extern JS_PUBLIC_API BigInt* BigIntFromUint64(JSContext* cx, uint64_t num); -extern JS_PUBLIC_API BigInt* BigIntFromBool(JSContext* cx, bool b); - -template -struct NumberToBigIntConverter; - -template -struct NumberToBigIntConverter< - SignedIntT, - std::enable_if_t && - std::is_signed_v && - std::numeric_limits::digits <= 64>> { - static BigInt* convert(JSContext* cx, SignedIntT num) { - return BigIntFromInt64(cx, num); - } -}; - -template -struct NumberToBigIntConverter< - UnsignedIntT, - std::enable_if_t && - std::is_unsigned_v && - std::numeric_limits::digits <= 64>> { - static BigInt* convert(JSContext* cx, UnsignedIntT num) { - return BigIntFromUint64(cx, num); - } -}; - -template <> -struct NumberToBigIntConverter { - static BigInt* convert(JSContext* cx, bool b) { - return BigIntFromBool(cx, b); - } -}; - -} // namespace detail - -/** - * Create a BigInt from an integer value. All integral types not larger than 64 - * bits in size are supported. - */ -template -extern JS_PUBLIC_API BigInt* NumberToBigInt(JSContext* cx, NumericT val) { - return detail::NumberToBigIntConverter::convert(cx, val); -} - -/** - * Create a BigInt from a floating-point value. If the number isn't integral - * (that is, if it's NaN, an infinity, or contains a fractional component), - * this function returns null and throws an exception. - * - * Passing -0.0 will produce the bigint 0n. - */ -extern JS_PUBLIC_API BigInt* NumberToBigInt(JSContext* cx, double num); - -/** - * Create a BigInt by parsing a string using the ECMAScript StringToBigInt - * algorithm (https://tc39.es/ecma262/#sec-stringtobigint). Latin1 and two-byte - * character ranges are supported. It may be convenient to use - * JS::ConstLatin1Chars or JS::ConstTwoByteChars. - * - * (StringToBigInt performs parsing similar to that performed by the |Number| - * global function when passed a string, but it doesn't allow infinities, - * decimal points, or exponential notation, and neither algorithm allows numeric - * separators or an 'n' suffix character. This fast-and-loose description is - * offered purely as a convenience to the reader: see the specification - * algorithm for exact behavior.) - * - * If parsing fails, this function returns null and throws an exception. - */ -extern JS_PUBLIC_API BigInt* StringToBigInt( - JSContext* cx, mozilla::Range chars); - -extern JS_PUBLIC_API BigInt* StringToBigInt( - JSContext* cx, mozilla::Range chars); - -/** - * Create a BigInt by parsing a string consisting of an optional sign character - * followed by one or more alphanumeric ASCII digits in the provided radix. - * - * If the radix is not in the range [2, 36], or the string fails to parse, this - * function returns null and throws an exception. - */ -extern JS_PUBLIC_API BigInt* SimpleStringToBigInt( - JSContext* cx, mozilla::Span chars, unsigned radix); - -/** - * Convert a JS::Value to a BigInt using the ECMAScript ToBigInt algorithm - * (https://tc39.es/ecma262/#sec-tobigint). - * - * (Note in particular that this will throw if passed a value whose type is - * 'number'. To convert a number to a BigInt, use one of the overloads of - * JS::NumberToBigInt().) - */ -extern JS_PUBLIC_API BigInt* ToBigInt(JSContext* cx, Handle val); - -/** - * Convert the given BigInt, modulo 2**64, to a signed 64-bit integer. - */ -extern JS_PUBLIC_API int64_t ToBigInt64(BigInt* bi); - -/** - * Convert the given BigInt, modulo 2**64, to an unsigned 64-bit integer. - */ -extern JS_PUBLIC_API uint64_t ToBigUint64(BigInt* bi); - -} // namespace JS - -#endif /* js_BigInt_h */ Index: libraries/source/spidermonkey/include-win32-debug/js/BinASTFormat.h =================================================================== --- /dev/null +++ libraries/source/spidermonkey/include-win32-debug/js/BinASTFormat.h @@ -1,16 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- - * vim: set ts=8 sts=2 et sw=2 tw=80: - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef js_BinASTFormat_h -#define js_BinASTFormat_h - -namespace JS { - -enum class BinASTFormat { Multipart, Context }; - -} /* namespace JS */ - -#endif /* js_BinASTFormat_h */ Index: libraries/source/spidermonkey/include-win32-debug/js/BuildId.h =================================================================== --- /dev/null +++ libraries/source/spidermonkey/include-win32-debug/js/BuildId.h @@ -1,65 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/** - * Embedding-provided build ID information, used by SpiderMonkey to tag cached - * compilation data so that cached data can be reused when possible, or - * discarded and regenerated if necessary. - */ - -#ifndef js_BuildId_h -#define js_BuildId_h - -#include "mozilla/Attributes.h" // MOZ_MUST_USE - -#include "jstypes.h" // JS_PUBLIC_API - -#include "js/Vector.h" // js::Vector - -namespace js { - -class SystemAllocPolicy; - -} // namespace js - -namespace JS { - -/** Vector of characters used for holding build ids. */ -using BuildIdCharVector = js::Vector; - -/** - * Return the buildId (represented as a sequence of characters) associated with - * the currently-executing build. If the JS engine is embedded such that a - * single cache entry can be observed by different compiled versions of the JS - * engine, it is critical that the buildId shall change for each new build of - * the JS engine. - */ -using BuildIdOp = bool (*)(BuildIdCharVector* buildId); - -/** - * Embedder hook to set the buildId-generating function. - */ -extern JS_PUBLIC_API void SetProcessBuildIdOp(BuildIdOp buildIdOp); - -/** - * Some cached data is, in addition to being build-specific, CPU-specific: the - * cached data depends on CPU features like a particular level of SSE support. - * - * This function produces a buildId that includes: - * - * * the buildId defined by the embedder-provided BuildIdOp set by - * JS::SetProcessBuildIdOp, and - * * CPU feature information for the current CPU. - * - * Embedders may use this function to tag cached data whose validity depends - * on having consistent buildId *and* on the CPU supporting features identical - * to those in play when the cached data was computed. - */ -extern MOZ_MUST_USE JS_PUBLIC_API bool GetOptimizedEncodingBuildId( - BuildIdCharVector* buildId); - -} // namespace JS - -#endif /* js_BuildId_h */ Index: libraries/source/spidermonkey/include-win32-debug/js/CallArgs.h =================================================================== --- /dev/null +++ libraries/source/spidermonkey/include-win32-debug/js/CallArgs.h @@ -1,361 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- - * vim: set ts=8 sts=2 et sw=2 tw=80: - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* - * [SMDOC] JS::CallArgs API - * - * Helper classes encapsulating access to the callee, |this| value, arguments, - * and argument count for a call/construct operation. - * - * JS::CallArgs encapsulates access to a JSNative's un-abstracted - * |unsigned argc, Value* vp| arguments. The principal way to create a - * JS::CallArgs is using JS::CallArgsFromVp: - * - * // If provided no arguments or a non-numeric first argument, return zero. - * // Otherwise return |this| exactly as given, without boxing. - * static bool - * Func(JSContext* cx, unsigned argc, JS::Value* vp) - * { - * JS::CallArgs args = JS::CallArgsFromVp(argc, vp); - * - * // Guard against no arguments or a non-numeric arg0. - * if (args.length() == 0 || !args[0].isNumber()) { - * args.rval().setInt32(0); - * return true; - * } - * - * // Access to the callee must occur before accessing/setting - * // the return value. - * JSObject& callee = args.callee(); - * args.rval().setObject(callee); - * - * // callee() and calleev() will now assert. - * - * // It's always fine to access thisv(). - * HandleValue thisv = args.thisv(); - * args.rval().set(thisv); - * - * // As the return value was last set to |this|, returns |this|. - * return true; - * } - * - * CallArgs is exposed publicly and used internally. Not all parts of its - * public interface are meant to be used by embedders! See inline comments to - * for details. - * - * It's possible (albeit deprecated) to manually index into |vp| to access the - * callee, |this|, and arguments of a function, and to set its return value. - * This does not have the error-handling or moving-GC correctness of CallArgs. - * New code should use CallArgs instead whenever possible. - * - * The eventual plan is to change JSNative to take |const CallArgs&| directly, - * for automatic assertion of correct use and to make calling functions more - * efficient. Embedders should start internally switching away from using - * |argc| and |vp| directly, except to create a |CallArgs|. Then, when an - * eventual release making that change occurs, porting efforts will require - * changing methods' signatures but won't require invasive changes to the - * methods' implementations, potentially under time pressure. - */ - -#ifndef js_CallArgs_h -#define js_CallArgs_h - -#include "mozilla/Assertions.h" -#include "mozilla/Attributes.h" - -#include - -#include "jstypes.h" - -#include "js/RootingAPI.h" -#include "js/Value.h" - -/* Typedef for native functions called by the JS VM. */ -using JSNative = bool (*)(JSContext* cx, unsigned argc, JS::Value* vp); - -namespace JS { - -extern JS_PUBLIC_DATA const HandleValue UndefinedHandleValue; - -namespace detail { - -/* - * Compute |this| for the |vp| inside a JSNative, either boxing primitives or - * replacing with the global object as necessary. - */ -extern JS_PUBLIC_API bool ComputeThis(JSContext* cx, JS::Value* vp, - MutableHandleObject thisObject); - -#ifdef JS_DEBUG -extern JS_PUBLIC_API void CheckIsValidConstructible(const Value& v); -#endif - -class MOZ_STACK_CLASS IncludeUsedRval { - mutable bool usedRval_; - - public: - bool usedRval() const { return usedRval_; } - void setUsedRval() const { usedRval_ = true; } - void clearUsedRval() const { usedRval_ = false; } - void assertUnusedRval() const { MOZ_ASSERT(!usedRval_); } -}; - -class MOZ_STACK_CLASS NoUsedRval { - public: - bool usedRval() const { return false; } - void setUsedRval() const {} - void clearUsedRval() const {} - void assertUnusedRval() const {} -}; - -template -class MOZ_STACK_CLASS CallArgsBase { - static_assert(std::is_same_v || - std::is_same_v, - "WantUsedRval can only be IncludeUsedRval or NoUsedRval"); - - protected: - Value* argv_; - unsigned argc_; - bool constructing_ : 1; - - // True if the caller does not use the return value. - bool ignoresReturnValue_ : 1; - -#ifdef JS_DEBUG - WantUsedRval wantUsedRval_; - bool usedRval() const { return wantUsedRval_.usedRval(); } - void setUsedRval() const { wantUsedRval_.setUsedRval(); } - void clearUsedRval() const { wantUsedRval_.clearUsedRval(); } - void assertUnusedRval() const { wantUsedRval_.assertUnusedRval(); } -#else - bool usedRval() const { return false; } - void setUsedRval() const {} - void clearUsedRval() const {} - void assertUnusedRval() const {} -#endif - - public: - // CALLEE ACCESS - - /* - * Returns the function being called, as a value. Must not be called after - * rval() has been used! - */ - HandleValue calleev() const { - this->assertUnusedRval(); - return HandleValue::fromMarkedLocation(&argv_[-2]); - } - - /* - * Returns the function being called, as an object. Must not be called - * after rval() has been used! - */ - JSObject& callee() const { return calleev().toObject(); } - - // CALLING/CONSTRUCTING-DIFFERENTIATIONS - - bool isConstructing() const { - if (!argv_[-1].isMagic()) { - return false; - } - -#ifdef JS_DEBUG - if (!this->usedRval()) { - CheckIsValidConstructible(calleev()); - } -#endif - - return true; - } - - bool ignoresReturnValue() const { return ignoresReturnValue_; } - - MutableHandleValue newTarget() const { - MOZ_ASSERT(constructing_); - return MutableHandleValue::fromMarkedLocation(&this->argv_[argc_]); - } - - /* - * Returns the |this| value passed to the function. This method must not - * be called when the function is being called as a constructor via |new|. - * The value may or may not be an object: it is the individual function's - * responsibility to box the value if needed. - */ - HandleValue thisv() const { - // Some internal code uses thisv() in constructing cases, so don't do - // this yet. - // MOZ_ASSERT(!argv_[-1].isMagic(JS_IS_CONSTRUCTING)); - return HandleValue::fromMarkedLocation(&argv_[-1]); - } - - bool computeThis(JSContext* cx, MutableHandleObject thisObject) const { - if (thisv().isObject()) { - thisObject.set(&thisv().toObject()); - return true; - } - - return ComputeThis(cx, base(), thisObject); - } - - // ARGUMENTS - - /* Returns the number of arguments. */ - unsigned length() const { return argc_; } - - /* Returns the i-th zero-indexed argument. */ - MutableHandleValue operator[](unsigned i) const { - MOZ_ASSERT(i < argc_); - return MutableHandleValue::fromMarkedLocation(&this->argv_[i]); - } - - /* - * Returns the i-th zero-indexed argument, or |undefined| if there's no - * such argument. - */ - HandleValue get(unsigned i) const { - return i < length() ? HandleValue::fromMarkedLocation(&this->argv_[i]) - : UndefinedHandleValue; - } - - /* - * Returns true if the i-th zero-indexed argument is present and is not - * |undefined|. - */ - bool hasDefined(unsigned i) const { - return i < argc_ && !this->argv_[i].isUndefined(); - } - - // RETURN VALUE - - /* - * Returns the currently-set return value. The initial contents of this - * value are unspecified. Once this method has been called, callee() and - * calleev() can no longer be used. (If you're compiling against a debug - * build of SpiderMonkey, these methods will assert to aid debugging.) - * - * If the method you're implementing succeeds by returning true, you *must* - * set this. (SpiderMonkey doesn't currently assert this, but it will do - * so eventually.) You don't need to use or change this if your method - * fails. - */ - MutableHandleValue rval() const { - this->setUsedRval(); - return MutableHandleValue::fromMarkedLocation(&argv_[-2]); - } - - /* - * Returns true if there are at least |required| arguments passed in. If - * false, it reports an error message on the context. - */ - JS_PUBLIC_API inline bool requireAtLeast(JSContext* cx, const char* fnname, - unsigned required) const; - - public: - // These methods are publicly exposed, but they are *not* to be used when - // implementing a JSNative method and encapsulating access to |vp| within - // it. You probably don't want to use these! - - void setCallee(const Value& aCalleev) const { - this->clearUsedRval(); - argv_[-2] = aCalleev; - } - - void setThis(const Value& aThisv) const { argv_[-1] = aThisv; } - - MutableHandleValue mutableThisv() const { - return MutableHandleValue::fromMarkedLocation(&argv_[-1]); - } - - public: - // These methods are publicly exposed, but we're unsure of the interfaces - // (because they're hackish and drop assertions). Avoid using these if you - // can. - - Value* array() const { return argv_; } - Value* end() const { return argv_ + argc_ + constructing_; } - - public: - // These methods are only intended for internal use. Embedders shouldn't - // use them! - - Value* base() const { return argv_ - 2; } - - Value* spAfterCall() const { - this->setUsedRval(); - return argv_ - 1; - } -}; - -} // namespace detail - -class MOZ_STACK_CLASS CallArgs - : public detail::CallArgsBase { - private: - friend CallArgs CallArgsFromVp(unsigned argc, Value* vp); - friend CallArgs CallArgsFromSp(unsigned stackSlots, Value* sp, - bool constructing, bool ignoresReturnValue); - - static CallArgs create(unsigned argc, Value* argv, bool constructing, - bool ignoresReturnValue = false) { - CallArgs args; - args.clearUsedRval(); - args.argv_ = argv; - args.argc_ = argc; - args.constructing_ = constructing; - args.ignoresReturnValue_ = ignoresReturnValue; -#ifdef DEBUG - AssertValueIsNotGray(args.thisv()); - AssertValueIsNotGray(args.calleev()); - for (unsigned i = 0; i < argc; ++i) { - AssertValueIsNotGray(argv[i]); - } -#endif - return args; - } - - public: - /* - * Helper for requireAtLeast to report the actual exception. Public - * so we can call it from CallArgsBase and not need multiple - * per-template instantiations of it. - */ - static JS_PUBLIC_API void reportMoreArgsNeeded(JSContext* cx, - const char* fnname, - unsigned required, - unsigned actual); -}; - -namespace detail { -template -JS_PUBLIC_API inline bool CallArgsBase::requireAtLeast( - JSContext* cx, const char* fnname, unsigned required) const { - if (MOZ_LIKELY(required <= length())) { - return true; - } - - CallArgs::reportMoreArgsNeeded(cx, fnname, required, length()); - return false; -} -} // namespace detail - -MOZ_ALWAYS_INLINE CallArgs CallArgsFromVp(unsigned argc, Value* vp) { - return CallArgs::create(argc, vp + 2, vp[1].isMagic(JS_IS_CONSTRUCTING)); -} - -// This method is only intended for internal use in SpiderMonkey. We may -// eventually move it to an internal header. Embedders should use -// JS::CallArgsFromVp! -MOZ_ALWAYS_INLINE CallArgs CallArgsFromSp(unsigned stackSlots, Value* sp, - bool constructing = false, - bool ignoresReturnValue = false) { - return CallArgs::create(stackSlots - constructing, sp - stackSlots, - constructing, ignoresReturnValue); -} - -} // namespace JS - -#endif /* js_CallArgs_h */ Index: libraries/source/spidermonkey/include-win32-debug/js/CallNonGenericMethod.h =================================================================== --- /dev/null +++ libraries/source/spidermonkey/include-win32-debug/js/CallNonGenericMethod.h @@ -1,123 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- - * vim: set ts=8 sts=2 et sw=2 tw=80: - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef js_CallNonGenericMethod_h -#define js_CallNonGenericMethod_h - -#include "jstypes.h" - -#include "js/CallArgs.h" - -namespace JS { - -// Returns true if |v| is considered an acceptable this-value. -typedef bool (*IsAcceptableThis)(HandleValue v); - -// Implements the guts of a method; guaranteed to be provided an acceptable -// this-value, as determined by a corresponding IsAcceptableThis method. -typedef bool (*NativeImpl)(JSContext* cx, const CallArgs& args); - -namespace detail { - -// DON'T CALL THIS DIRECTLY. It's for use only by CallNonGenericMethod! -extern JS_PUBLIC_API bool CallMethodIfWrapped(JSContext* cx, - IsAcceptableThis test, - NativeImpl impl, - const CallArgs& args); - -} // namespace detail - -// Methods usually act upon |this| objects only from a single global object and -// compartment. Sometimes, however, a method must act upon |this| values from -// multiple global objects or compartments. In such cases the |this| value a -// method might see will be wrapped, such that various access to the object -- -// to its class, its private data, its reserved slots, and so on -- will not -// work properly without entering that object's compartment. This method -// implements a solution to this problem. -// -// To implement a method that accepts |this| values from multiple compartments, -// define two functions. The first function matches the IsAcceptableThis type -// and indicates whether the provided value is an acceptable |this| for the -// method; it must be a pure function only of its argument. -// -// static const JSClass AnswerClass = { ... }; -// -// static bool -// IsAnswerObject(const Value& v) -// { -// if (!v.isObject()) { -// return false; -// } -// return JS_GetClass(&v.toObject()) == &AnswerClass; -// } -// -// The second function implements the NativeImpl signature and defines the -// behavior of the method when it is provided an acceptable |this| value. -// Aside from some typing niceties -- see the CallArgs interface for details -- -// its interface is the same as that of JSNative. -// -// static bool -// answer_getAnswer_impl(JSContext* cx, JS::CallArgs args) -// { -// args.rval().setInt32(42); -// return true; -// } -// -// The implementation function is guaranteed to be called *only* with a |this| -// value which is considered acceptable. -// -// Now to implement the actual method, write a JSNative that calls the method -// declared below, passing the appropriate template and runtime arguments. -// -// static bool -// answer_getAnswer(JSContext* cx, unsigned argc, JS::Value* vp) -// { -// JS::CallArgs args = JS::CallArgsFromVp(argc, vp); -// return JS::CallNonGenericMethod(cx, args); -// } -// -// Note that, because they are used as template arguments, the predicate -// and implementation functions must have external linkage. (This is -// unfortunate, but GCC wasn't inlining things as one would hope when we -// passed them as function arguments.) -// -// JS::CallNonGenericMethod will test whether |args.thisv()| is acceptable. If -// it is, it will call the provided implementation function, which will return -// a value and indicate success. If it is not, it will attempt to unwrap -// |this| and call the implementation function on the unwrapped |this|. If -// that succeeds, all well and good. If it doesn't succeed, a TypeError will -// be thrown. -// -// Note: JS::CallNonGenericMethod will only work correctly if it's called in -// tail position in a JSNative. Do not call it from any other place. -// -template -MOZ_ALWAYS_INLINE bool CallNonGenericMethod(JSContext* cx, - const CallArgs& args) { - HandleValue thisv = args.thisv(); - if (Test(thisv)) { - return Impl(cx, args); - } - - return detail::CallMethodIfWrapped(cx, Test, Impl, args); -} - -MOZ_ALWAYS_INLINE bool CallNonGenericMethod(JSContext* cx, - IsAcceptableThis Test, - NativeImpl Impl, - const CallArgs& args) { - HandleValue thisv = args.thisv(); - if (Test(thisv)) { - return Impl(cx, args); - } - - return detail::CallMethodIfWrapped(cx, Test, Impl, args); -} - -} // namespace JS - -#endif /* js_CallNonGenericMethod_h */ Index: libraries/source/spidermonkey/include-win32-debug/js/CharacterEncoding.h =================================================================== --- /dev/null +++ libraries/source/spidermonkey/include-win32-debug/js/CharacterEncoding.h @@ -1,427 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- - * vim: set ts=8 sts=2 et sw=2 tw=80: - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef js_CharacterEncoding_h -#define js_CharacterEncoding_h - -#include "mozilla/Range.h" -#include "mozilla/Span.h" -#include "mozilla/Utf8.h" - -#include "js/TypeDecls.h" -#include "js/Utility.h" - -class JSLinearString; - -namespace JS { - -/* - * By default, all C/C++ 1-byte-per-character strings passed into the JSAPI - * are treated as ISO/IEC 8859-1, also known as Latin-1. That is, each - * byte is treated as a 2-byte character, and there is no way to pass in a - * string containing characters beyond U+00FF. - */ -class Latin1Chars : public mozilla::Range { - typedef mozilla::Range Base; - - public: - using CharT = Latin1Char; - - Latin1Chars() = default; - Latin1Chars(char* aBytes, size_t aLength) - : Base(reinterpret_cast(aBytes), aLength) {} - Latin1Chars(const Latin1Char* aBytes, size_t aLength) - : Base(const_cast(aBytes), aLength) {} - Latin1Chars(const char* aBytes, size_t aLength) - : Base(reinterpret_cast(const_cast(aBytes)), - aLength) {} -}; - -/* - * Like Latin1Chars, but the chars are const. - */ -class ConstLatin1Chars : public mozilla::Range { - typedef mozilla::Range Base; - - public: - using CharT = Latin1Char; - - ConstLatin1Chars() = default; - ConstLatin1Chars(const Latin1Char* aChars, size_t aLength) - : Base(aChars, aLength) {} -}; - -/* - * A Latin1Chars, but with \0 termination for C compatibility. - */ -class Latin1CharsZ : public mozilla::RangedPtr { - typedef mozilla::RangedPtr Base; - - public: - using CharT = Latin1Char; - - Latin1CharsZ() : Base(nullptr, 0) {} // NOLINT - - Latin1CharsZ(char* aBytes, size_t aLength) - : Base(reinterpret_cast(aBytes), aLength) { - MOZ_ASSERT(aBytes[aLength] == '\0'); - } - - Latin1CharsZ(Latin1Char* aBytes, size_t aLength) : Base(aBytes, aLength) { - MOZ_ASSERT(aBytes[aLength] == '\0'); - } - - using Base::operator=; - - char* c_str() { return reinterpret_cast(get()); } -}; - -class UTF8Chars : public mozilla::Range { - typedef mozilla::Range Base; - - public: - using CharT = unsigned char; - - UTF8Chars() = default; - UTF8Chars(char* aBytes, size_t aLength) - : Base(reinterpret_cast(aBytes), aLength) {} - UTF8Chars(const char* aBytes, size_t aLength) - : Base(reinterpret_cast(const_cast(aBytes)), - aLength) {} - UTF8Chars(mozilla::Utf8Unit* aUnits, size_t aLength) - : UTF8Chars(reinterpret_cast(aUnits), aLength) {} - UTF8Chars(const mozilla::Utf8Unit* aUnits, size_t aLength) - : UTF8Chars(reinterpret_cast(aUnits), aLength) {} -}; - -/* - * Similar to UTF8Chars, but contains WTF-8. - * https://simonsapin.github.io/wtf-8/ - */ -class WTF8Chars : public mozilla::Range { - typedef mozilla::Range Base; - - public: - using CharT = unsigned char; - - WTF8Chars() = default; - WTF8Chars(char* aBytes, size_t aLength) - : Base(reinterpret_cast(aBytes), aLength) {} - WTF8Chars(const char* aBytes, size_t aLength) - : Base(reinterpret_cast(const_cast(aBytes)), - aLength) {} -}; - -/* - * SpiderMonkey also deals directly with UTF-8 encoded text in some places. - */ -class UTF8CharsZ : public mozilla::RangedPtr { - typedef mozilla::RangedPtr Base; - - public: - using CharT = unsigned char; - - UTF8CharsZ() : Base(nullptr, 0) {} // NOLINT - - UTF8CharsZ(char* aBytes, size_t aLength) - : Base(reinterpret_cast(aBytes), aLength) { - MOZ_ASSERT(aBytes[aLength] == '\0'); - } - - UTF8CharsZ(unsigned char* aBytes, size_t aLength) : Base(aBytes, aLength) { - MOZ_ASSERT(aBytes[aLength] == '\0'); - } - - UTF8CharsZ(mozilla::Utf8Unit* aUnits, size_t aLength) - : UTF8CharsZ(reinterpret_cast(aUnits), aLength) {} - - using Base::operator=; - - char* c_str() { return reinterpret_cast(get()); } -}; - -/* - * A wrapper for a "const char*" that is encoded using UTF-8. - * This class does not manage ownership of the data; that is left - * to others. This differs from UTF8CharsZ in that the chars are - * const and it disallows assignment. - */ -class JS_PUBLIC_API ConstUTF8CharsZ { - const char* data_; - - public: - using CharT = unsigned char; - - ConstUTF8CharsZ() : data_(nullptr) {} - - ConstUTF8CharsZ(const char* aBytes, size_t aLength) : data_(aBytes) { - MOZ_ASSERT(aBytes[aLength] == '\0'); -#ifdef DEBUG - validate(aLength); -#endif - } - - const void* get() const { return data_; } - - const char* c_str() const { return data_; } - - explicit operator bool() const { return data_ != nullptr; } - - private: -#ifdef DEBUG - void validate(size_t aLength); -#endif -}; - -/* - * SpiderMonkey uses a 2-byte character representation: it is a - * 2-byte-at-a-time view of a UTF-16 byte stream. This is similar to UCS-2, - * but unlike UCS-2, we do not strip UTF-16 extension bytes. This allows a - * sufficiently dedicated JavaScript program to be fully unicode-aware by - * manually interpreting UTF-16 extension characters embedded in the JS - * string. - */ -class TwoByteChars : public mozilla::Range { - typedef mozilla::Range Base; - - public: - using CharT = char16_t; - - TwoByteChars() = default; - TwoByteChars(char16_t* aChars, size_t aLength) : Base(aChars, aLength) {} - TwoByteChars(const char16_t* aChars, size_t aLength) - : Base(const_cast(aChars), aLength) {} -}; - -/* - * A TwoByteChars, but \0 terminated for compatibility with JSFlatString. - */ -class TwoByteCharsZ : public mozilla::RangedPtr { - typedef mozilla::RangedPtr Base; - - public: - using CharT = char16_t; - - TwoByteCharsZ() : Base(nullptr, 0) {} // NOLINT - - TwoByteCharsZ(char16_t* chars, size_t length) : Base(chars, length) { - MOZ_ASSERT(chars[length] == '\0'); - } - - using Base::operator=; -}; - -typedef mozilla::RangedPtr ConstCharPtr; - -/* - * Like TwoByteChars, but the chars are const. - */ -class ConstTwoByteChars : public mozilla::Range { - typedef mozilla::Range Base; - - public: - using CharT = char16_t; - - ConstTwoByteChars() = default; - ConstTwoByteChars(const char16_t* aChars, size_t aLength) - : Base(aChars, aLength) {} -}; - -/* - * Convert a 2-byte character sequence to "ISO-Latin-1". This works by - * truncating each 2-byte pair in the sequence to a 1-byte pair. If the source - * contains any UTF-16 extension characters, then this may give invalid Latin1 - * output. The returned string is zero terminated. The returned string or the - * returned string's |start()| must be freed with JS_free or js_free, - * respectively. If allocation fails, an OOM error will be set and the method - * will return a nullptr chars (which can be tested for with the ! operator). - * This method cannot trigger GC. - */ -extern Latin1CharsZ LossyTwoByteCharsToNewLatin1CharsZ( - JSContext* cx, const mozilla::Range tbchars); - -inline Latin1CharsZ LossyTwoByteCharsToNewLatin1CharsZ(JSContext* cx, - const char16_t* begin, - size_t length) { - const mozilla::Range tbchars(begin, length); - return JS::LossyTwoByteCharsToNewLatin1CharsZ(cx, tbchars); -} - -template -extern UTF8CharsZ CharsToNewUTF8CharsZ(JSContext* maybeCx, - const mozilla::Range chars); - -JS_PUBLIC_API uint32_t Utf8ToOneUcs4Char(const uint8_t* utf8Buffer, - int utf8Length); - -/* - * Inflate bytes in UTF-8 encoding to char16_t. - * - On error, returns an empty TwoByteCharsZ. - * - On success, returns a malloc'd TwoByteCharsZ, and updates |outlen| to hold - * its length; the length value excludes the trailing null. - */ -extern JS_PUBLIC_API TwoByteCharsZ -UTF8CharsToNewTwoByteCharsZ(JSContext* cx, const UTF8Chars utf8, size_t* outlen, - arena_id_t destArenaId); - -/* - * Like UTF8CharsToNewTwoByteCharsZ, but for WTF8Chars. - */ -extern JS_PUBLIC_API TwoByteCharsZ -WTF8CharsToNewTwoByteCharsZ(JSContext* cx, const WTF8Chars wtf8, size_t* outlen, - arena_id_t destArenaId); - -/* - * Like UTF8CharsToNewTwoByteCharsZ, but for ConstUTF8CharsZ. - */ -extern JS_PUBLIC_API TwoByteCharsZ -UTF8CharsToNewTwoByteCharsZ(JSContext* cx, const ConstUTF8CharsZ& utf8, - size_t* outlen, arena_id_t destArenaId); - -/* - * The same as UTF8CharsToNewTwoByteCharsZ(), except that any malformed UTF-8 - * characters will be replaced by \uFFFD. No exception will be thrown for - * malformed UTF-8 input. - */ -extern JS_PUBLIC_API TwoByteCharsZ -LossyUTF8CharsToNewTwoByteCharsZ(JSContext* cx, const UTF8Chars utf8, - size_t* outlen, arena_id_t destArenaId); - -extern JS_PUBLIC_API TwoByteCharsZ -LossyUTF8CharsToNewTwoByteCharsZ(JSContext* cx, const ConstUTF8CharsZ& utf8, - size_t* outlen, arena_id_t destArenaId); - -/* - * Returns the length of the char buffer required to encode |s| as UTF8. - * Does not include the null-terminator. - */ -JS_PUBLIC_API size_t GetDeflatedUTF8StringLength(JSLinearString* s); - -/* - * Encode whole scalar values of |src| into |dst| as UTF-8 until |src| is - * exhausted or too little space is available in |dst| to fit the scalar - * value. Lone surrogates are converted to REPLACEMENT CHARACTER. Return - * the number of bytes of |dst| that were filled. - * - * Use |JS_EncodeStringToUTF8BufferPartial| if your string isn't already - * linear. - * - * Given |JSString* str = JS_FORGET_STRING_LINEARNESS(src)|, - * if |JS_StringHasLatin1Chars(str)|, then |src| is always fully converted - * if |dst.Length() >= JS_GetStringLength(str) * 2|. Otherwise |src| is - * always fully converted if |dst.Length() >= JS_GetStringLength(str) * 3|. - * - * The exact space required is always |GetDeflatedUTF8StringLength(str)|. - */ -JS_PUBLIC_API size_t DeflateStringToUTF8Buffer(JSLinearString* src, - mozilla::Span dst); - -/* - * The smallest character encoding capable of fully representing a particular - * string. - */ -enum class SmallestEncoding { ASCII, Latin1, UTF16 }; - -/* - * Returns the smallest encoding possible for the given string: if all - * codepoints are <128 then ASCII, otherwise if all codepoints are <256 - * Latin-1, else UTF16. - */ -JS_PUBLIC_API SmallestEncoding FindSmallestEncoding(UTF8Chars utf8); - -/* - * Return a null-terminated Latin-1 string copied from the input string, - * storing its length (excluding null terminator) in |*outlen|. Fail and - * report an error if the string contains non-Latin-1 codepoints. Returns - * Latin1CharsZ() on failure. - */ -extern JS_PUBLIC_API Latin1CharsZ -UTF8CharsToNewLatin1CharsZ(JSContext* cx, const UTF8Chars utf8, size_t* outlen, - arena_id_t destArenaId); - -/* - * Return a null-terminated Latin-1 string copied from the input string, - * storing its length (excluding null terminator) in |*outlen|. Non-Latin-1 - * codepoints are replaced by '?'. Returns Latin1CharsZ() on failure. - */ -extern JS_PUBLIC_API Latin1CharsZ -LossyUTF8CharsToNewLatin1CharsZ(JSContext* cx, const UTF8Chars utf8, - size_t* outlen, arena_id_t destArenaId); - -/* - * Returns true if all characters in the given null-terminated string are - * ASCII, i.e. < 0x80, false otherwise. - */ -extern JS_PUBLIC_API bool StringIsASCII(const char* s); - -/* - * Returns true if all characters in the given span are ASCII, - * i.e. < 0x80, false otherwise. - */ -extern JS_PUBLIC_API bool StringIsASCII(mozilla::Span s); - -} // namespace JS - -inline void JS_free(JS::Latin1CharsZ& ptr) { js_free((void*)ptr.get()); } -inline void JS_free(JS::UTF8CharsZ& ptr) { js_free((void*)ptr.get()); } - -/** - * DEPRECATED - * - * Allocate memory sufficient to contain the characters of |str| truncated to - * Latin-1 and a trailing null terminator, fill the memory with the characters - * interpreted in that manner plus the null terminator, and return a pointer to - * the memory. - * - * This function *loses information* when it copies the characters of |str| if - * |str| contains code units greater than 0xFF. Additionally, users that - * depend on null-termination will misinterpret the copied characters if |str| - * contains any nulls. Avoid using this function if possible, because it will - * eventually be removed. - */ -extern JS_PUBLIC_API JS::UniqueChars JS_EncodeStringToLatin1(JSContext* cx, - JSString* str); - -/** - * DEPRECATED - * - * Same behavior as JS_EncodeStringToLatin1(), but encode into a UTF-8 string. - * - * This function *loses information* when it copies the characters of |str| if - * |str| contains invalid UTF-16: U+FFFD REPLACEMENT CHARACTER will be copied - * instead. - * - * The returned string is also subject to misinterpretation if |str| contains - * any nulls (which are faithfully transcribed into the returned string, but - * which will implicitly truncate the string if it's passed to functions that - * expect null-terminated strings). - * - * Avoid using this function if possible, because we'll remove it once we can - * devise a better API for the task. - */ -extern JS_PUBLIC_API JS::UniqueChars JS_EncodeStringToUTF8( - JSContext* cx, JS::Handle str); - -/** - * DEPRECATED - * - * Same behavior as JS_EncodeStringToLatin1(), but encode into an ASCII string. - * - * This function asserts in debug mode that the input string contains only - * ASCII characters. - * - * The returned string is also subject to misinterpretation if |str| contains - * any nulls (which are faithfully transcribed into the returned string, but - * which will implicitly truncate the string if it's passed to functions that - * expect null-terminated strings). - * - * Avoid using this function if possible, because we'll remove it once we can - * devise a better API for the task. - */ -extern JS_PUBLIC_API JS::UniqueChars JS_EncodeStringToASCII(JSContext* cx, - JSString* str); - -#endif /* js_CharacterEncoding_h */ Index: libraries/source/spidermonkey/include-win32-debug/js/Class.h =================================================================== --- /dev/null +++ libraries/source/spidermonkey/include-win32-debug/js/Class.h @@ -1,946 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- - * vim: set ts=8 sts=2 et sw=2 tw=80: - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* JSClass definition and its component types, plus related interfaces. */ - -#ifndef js_Class_h -#define js_Class_h - -#include "mozilla/Attributes.h" - -#include "jstypes.h" - -#include "js/CallArgs.h" -#include "js/HeapAPI.h" -#include "js/Id.h" -#include "js/TypeDecls.h" - -/* - * A JSClass acts as a vtable for JS objects that allows JSAPI clients to - * control various aspects of the behavior of an object like property lookup. - * It contains some engine-private extensions that allows more control over - * object behavior and, e.g., allows custom slow layout. - */ - -struct JSAtomState; -struct JSFunctionSpec; - -namespace js { - -class Shape; - -// This is equal to JSFunction::class_. Use it in places where you don't want -// to #include jsfun.h. -extern JS_FRIEND_DATA const JSClass* const FunctionClassPtr; - -} // namespace js - -namespace JS { - -/** - * Per ES6, the [[DefineOwnProperty]] internal method has three different - * possible outcomes: - * - * - It can throw an exception (which we indicate by returning false). - * - * - It can return true, indicating unvarnished success. - * - * - It can return false, indicating "strict failure". The property could - * not be defined. It's an error, but no exception was thrown. - * - * It's not just [[DefineOwnProperty]]: all the mutating internal methods have - * the same three outcomes. (The other affected internal methods are [[Set]], - * [[Delete]], [[SetPrototypeOf]], and [[PreventExtensions]].) - * - * If you think this design is awful, you're not alone. But as it's the - * standard, we must represent these boolean "success" values somehow. - * ObjectOpSuccess is the class for this. It's like a bool, but when it's false - * it also stores an error code. - * - * Typical usage: - * - * ObjectOpResult result; - * if (!DefineProperty(cx, obj, id, ..., result)) { - * return false; - * } - * if (!result) { - * return result.reportError(cx, obj, id); - * } - * - * Users don't have to call `result.report()`; another possible ending is: - * - * argv.rval().setBoolean(result.reallyOk()); - * return true; - */ -class ObjectOpResult { - private: - /** - * code_ is either one of the special codes OkCode or Uninitialized, or - * an error code. For now the error codes are private to the JS engine; - * they're defined in js/src/js.msg. - * - * code_ is uintptr_t (rather than uint32_t) for the convenience of the - * JITs, which would otherwise have to deal with either padding or stack - * alignment on 64-bit platforms. - */ - uintptr_t code_; - - public: - enum SpecialCodes : uintptr_t { OkCode = 0, Uninitialized = uintptr_t(-1) }; - - static const uintptr_t SoftFailBit = uintptr_t(1) - << (sizeof(uintptr_t) * 8 - 1); - - ObjectOpResult() : code_(Uninitialized) {} - - /* Return true if succeed() or failSoft() was called. */ - bool ok() const { - MOZ_ASSERT(code_ != Uninitialized); - return code_ == OkCode || (code_ & SoftFailBit); - } - - explicit operator bool() const { return ok(); } - - /* Return true if succeed() was called. */ - bool reallyOk() const { - MOZ_ASSERT(code_ != Uninitialized); - return code_ == OkCode; - } - - /* Set this ObjectOpResult to true and return true. */ - bool succeed() { - code_ = OkCode; - return true; - } - - /* - * Set this ObjectOpResult to false with an error code. - * - * Always returns true, as a convenience. Typical usage will be: - * - * if (funny condition) { - * return result.fail(JSMSG_CANT_DO_THE_THINGS); - * } - * - * The true return value indicates that no exception is pending, and it - * would be OK to ignore the failure and continue. - */ - bool fail(uint32_t msg) { - MOZ_ASSERT(msg != OkCode); - MOZ_ASSERT((msg & SoftFailBit) == 0); - code_ = msg; - return true; - } - - /* - * DEPRECATED: This is a non-standard compatibility hack. - * - * Set this ObjectOpResult to true, but remembers an error code. - * This is used for situations where we really want to fail, - * but can't for legacy reasons. - * - * Always returns true, as a convenience. - */ - bool failSoft(uint32_t msg) { - // The msg code is currently never extracted again. - code_ = msg | SoftFailBit; - return true; - } - - JS_PUBLIC_API bool failCantRedefineProp(); - JS_PUBLIC_API bool failReadOnly(); - JS_PUBLIC_API bool failGetterOnly(); - JS_PUBLIC_API bool failCantDelete(); - - JS_PUBLIC_API bool failCantSetInterposed(); - JS_PUBLIC_API bool failCantDefineWindowElement(); - JS_PUBLIC_API bool failCantDeleteWindowElement(); - JS_PUBLIC_API bool failCantDeleteWindowNamedProperty(); - JS_PUBLIC_API bool failCantPreventExtensions(); - JS_PUBLIC_API bool failCantSetProto(); - JS_PUBLIC_API bool failNoNamedSetter(); - JS_PUBLIC_API bool failNoIndexedSetter(); - JS_PUBLIC_API bool failNotDataDescriptor(); - - // Careful: This case has special handling in Object.defineProperty. - JS_PUBLIC_API bool failCantDefineWindowNonConfigurable(); - - uint32_t failureCode() const { - MOZ_ASSERT(!ok()); - return uint32_t(code_); - } - - /* - * Report an error if necessary; return true to proceed and - * false if an error was reported. - * - * The precise rules are like this: - * - * - If ok(), then we succeeded. Do nothing and return true. - * - Otherwise, if |strict| is true, throw a TypeError and return false. - * - Otherwise, do nothing and return true. - */ - bool checkStrictModeError(JSContext* cx, HandleObject obj, HandleId id, - bool strict) { - if (ok() || !strict) { - return true; - } - return reportError(cx, obj, id); - } - - /* - * The same as checkStrictModeError(cx, id, strict), except the - * operation is not associated with a particular property id. This is - * used for [[PreventExtensions]] and [[SetPrototypeOf]]. failureCode() - * must not be an error that has "{0}" in the error message. - */ - bool checkStrictModeError(JSContext* cx, HandleObject obj, bool strict) { - if (ok() || !strict) { - return true; - } - return reportError(cx, obj); - } - - /* Throw a TypeError. Call this only if !ok(). */ - bool reportError(JSContext* cx, HandleObject obj, HandleId id); - - /* - * The same as reportError(cx, obj, id), except the operation is not - * associated with a particular property id. - */ - bool reportError(JSContext* cx, HandleObject obj); - - // Convenience method. Return true if ok(); otherwise throw a TypeError - // and return false. - bool checkStrict(JSContext* cx, HandleObject obj, HandleId id) { - return checkStrictModeError(cx, obj, id, true); - } - - // Convenience method. The same as checkStrict(cx, obj, id), except the - // operation is not associated with a particular property id. - bool checkStrict(JSContext* cx, HandleObject obj) { - return checkStrictModeError(cx, obj, true); - } -}; - -class PropertyResult { - union { - js::Shape* shape_; - uintptr_t bits_; - }; - - static const uintptr_t NotFound = 0; - static const uintptr_t NonNativeProperty = 1; - static const uintptr_t DenseOrTypedArrayElement = 1; - - public: - PropertyResult() : bits_(NotFound) {} - - explicit PropertyResult(js::Shape* propertyShape) : shape_(propertyShape) { - MOZ_ASSERT(!isFound() || isNativeProperty()); - } - - explicit operator bool() const { return isFound(); } - - bool isFound() const { return bits_ != NotFound; } - - bool isNonNativeProperty() const { return bits_ == NonNativeProperty; } - - bool isDenseOrTypedArrayElement() const { - return bits_ == DenseOrTypedArrayElement; - } - - bool isNativeProperty() const { return isFound() && !isNonNativeProperty(); } - - js::Shape* maybeShape() const { - MOZ_ASSERT(!isNonNativeProperty()); - return isFound() ? shape_ : nullptr; - } - - js::Shape* shape() const { - MOZ_ASSERT(isNativeProperty()); - return shape_; - } - - void setNotFound() { bits_ = NotFound; } - - void setNativeProperty(js::Shape* propertyShape) { - shape_ = propertyShape; - MOZ_ASSERT(isNativeProperty()); - } - - void setNonNativeProperty() { bits_ = NonNativeProperty; } - - void setDenseOrTypedArrayElement() { bits_ = DenseOrTypedArrayElement; } - - void trace(JSTracer* trc); -}; - -} // namespace JS - -namespace js { - -template -class WrappedPtrOperations { - const JS::PropertyResult& value() const { - return static_cast(this)->get(); - } - - public: - bool isFound() const { return value().isFound(); } - explicit operator bool() const { return bool(value()); } - js::Shape* maybeShape() const { return value().maybeShape(); } - js::Shape* shape() const { return value().shape(); } - bool isNativeProperty() const { return value().isNativeProperty(); } - bool isNonNativeProperty() const { return value().isNonNativeProperty(); } - bool isDenseOrTypedArrayElement() const { - return value().isDenseOrTypedArrayElement(); - } - js::Shape* asTaggedShape() const { return value().asTaggedShape(); } -}; - -template -class MutableWrappedPtrOperations - : public WrappedPtrOperations { - JS::PropertyResult& value() { return static_cast(this)->get(); } - - public: - void setNotFound() { value().setNotFound(); } - void setNativeProperty(js::Shape* shape) { value().setNativeProperty(shape); } - void setNonNativeProperty() { value().setNonNativeProperty(); } - void setDenseOrTypedArrayElement() { value().setDenseOrTypedArrayElement(); } -}; - -} // namespace js - -// JSClass operation signatures. - -/** - * Get a property named by id in obj. Note the jsid id type -- id may - * be a string (Unicode property identifier) or an int (element index). The - * *vp out parameter, on success, is the new property value after the action. - */ -typedef bool (*JSGetterOp)(JSContext* cx, JS::HandleObject obj, JS::HandleId id, - JS::MutableHandleValue vp); - -/** Add a property named by id to obj. */ -typedef bool (*JSAddPropertyOp)(JSContext* cx, JS::HandleObject obj, - JS::HandleId id, JS::HandleValue v); - -/** - * Set a property named by id in obj, treating the assignment as strict - * mode code if strict is true. Note the jsid id type -- id may be a string - * (Unicode property identifier) or an int (element index). - */ -typedef bool (*JSSetterOp)(JSContext* cx, JS::HandleObject obj, JS::HandleId id, - JS::HandleValue v, JS::ObjectOpResult& result); - -/** - * Delete a property named by id in obj. - * - * If an error occurred, return false as per normal JSAPI error practice. - * - * If no error occurred, but the deletion attempt wasn't allowed (perhaps - * because the property was non-configurable), call result.fail() and - * return true. This will cause |delete obj[id]| to evaluate to false in - * non-strict mode code, and to throw a TypeError in strict mode code. - * - * If no error occurred and the deletion wasn't disallowed (this is *not* the - * same as saying that a deletion actually occurred -- deleting a non-existent - * property, or an inherited property, is allowed -- it's just pointless), - * call result.succeed() and return true. - */ -typedef bool (*JSDeletePropertyOp)(JSContext* cx, JS::HandleObject obj, - JS::HandleId id, JS::ObjectOpResult& result); - -/** - * The type of ObjectOps::enumerate. This callback overrides a portion of - * SpiderMonkey's default [[Enumerate]] internal method. When an ordinary object - * is enumerated, that object and each object on its prototype chain is tested - * for an enumerate op, and those ops are called in order. The properties each - * op adds to the 'properties' vector are added to the set of values the for-in - * loop will iterate over. All of this is nonstandard. - * - * An object is "enumerated" when it's the target of a for-in loop or - * JS_Enumerate(). The callback's job is to populate 'properties' with the - * object's property keys. If `enumerableOnly` is true, the callback should only - * add enumerable properties. - */ -typedef bool (*JSNewEnumerateOp)(JSContext* cx, JS::HandleObject obj, - JS::MutableHandleIdVector properties, - bool enumerableOnly); - -/** - * The old-style JSClass.enumerate op should define all lazy properties not - * yet reflected in obj. - */ -typedef bool (*JSEnumerateOp)(JSContext* cx, JS::HandleObject obj); - -/** - * The type of ObjectOps::funToString. This callback allows an object to - * provide a custom string to use when Function.prototype.toString is invoked on - * that object. A null return value means OOM. - */ -typedef JSString* (*JSFunToStringOp)(JSContext* cx, JS::HandleObject obj, - bool isToSource); - -/** - * Resolve a lazy property named by id in obj by defining it directly in obj. - * Lazy properties are those reflected from some peer native property space - * (e.g., the DOM attributes for a given node reflected as obj) on demand. - * - * JS looks for a property in an object, and if not found, tries to resolve - * the given id. *resolvedp should be set to true iff the property was defined - * on |obj|. - */ -typedef bool (*JSResolveOp)(JSContext* cx, JS::HandleObject obj, - JS::HandleId id, bool* resolvedp); - -/** - * A class with a resolve hook can optionally have a mayResolve hook. This hook - * must have no side effects and must return true for a given id if the resolve - * hook may resolve this id. This is useful when we're doing a "pure" lookup: if - * mayResolve returns false, we know we don't have to call the effectful resolve - * hook. - * - * maybeObj, if non-null, is the object on which we're doing the lookup. This - * can be nullptr: during JIT compilation we sometimes know the Class but not - * the object. - */ -typedef bool (*JSMayResolveOp)(const JSAtomState& names, jsid id, - JSObject* maybeObj); - -/** - * Finalize obj, which the garbage collector has determined to be unreachable - * from other live objects or from GC roots. Obviously, finalizers must never - * store a reference to obj. - */ -typedef void (*JSFinalizeOp)(JSFreeOp* fop, JSObject* obj); - -/** - * Check whether v is an instance of obj. Return false on error or exception, - * true on success with true in *bp if v is an instance of obj, false in - * *bp otherwise. - */ -typedef bool (*JSHasInstanceOp)(JSContext* cx, JS::HandleObject obj, - JS::MutableHandleValue vp, bool* bp); - -/** - * Function type for trace operation of the class called to enumerate all - * traceable things reachable from obj's private data structure. For each such - * thing, a trace implementation must call JS::TraceEdge on the thing's - * location. - * - * JSTraceOp implementation can assume that no other threads mutates object - * state. It must not change state of the object or corresponding native - * structures. The only exception for this rule is the case when the embedding - * needs a tight integration with GC. In that case the embedding can check if - * the traversal is a part of the marking phase through calling - * JS_IsGCMarkingTracer and apply a special code like emptying caches or - * marking its native structures. - */ -typedef void (*JSTraceOp)(JSTracer* trc, JSObject* obj); - -typedef size_t (*JSObjectMovedOp)(JSObject* obj, JSObject* old); - -namespace js { - -/* Internal / friend API operation signatures. */ - -typedef bool (*LookupPropertyOp)(JSContext* cx, JS::HandleObject obj, - JS::HandleId id, JS::MutableHandleObject objp, - JS::MutableHandle propp); -typedef bool (*DefinePropertyOp)(JSContext* cx, JS::HandleObject obj, - JS::HandleId id, - JS::Handle desc, - JS::ObjectOpResult& result); -typedef bool (*HasPropertyOp)(JSContext* cx, JS::HandleObject obj, - JS::HandleId id, bool* foundp); -typedef bool (*GetPropertyOp)(JSContext* cx, JS::HandleObject obj, - JS::HandleValue receiver, JS::HandleId id, - JS::MutableHandleValue vp); -typedef bool (*SetPropertyOp)(JSContext* cx, JS::HandleObject obj, - JS::HandleId id, JS::HandleValue v, - JS::HandleValue receiver, - JS::ObjectOpResult& result); -typedef bool (*GetOwnPropertyOp)( - JSContext* cx, JS::HandleObject obj, JS::HandleId id, - JS::MutableHandle desc); -typedef bool (*DeletePropertyOp)(JSContext* cx, JS::HandleObject obj, - JS::HandleId id, JS::ObjectOpResult& result); - -class JS_FRIEND_API ElementAdder { - public: - enum GetBehavior { - // Check if the element exists before performing the Get and preserve - // holes. - CheckHasElemPreserveHoles, - - // Perform a Get operation, like obj[index] in JS. - GetElement - }; - - private: - // Only one of these is used. - JS::RootedObject resObj_; - JS::Value* vp_; - - uint32_t index_; -#ifdef DEBUG - uint32_t length_; -#endif - GetBehavior getBehavior_; - - public: - ElementAdder(JSContext* cx, JSObject* obj, uint32_t length, - GetBehavior behavior) - : resObj_(cx, obj), - vp_(nullptr), - index_(0), -#ifdef DEBUG - length_(length), -#endif - getBehavior_(behavior) { - } - ElementAdder(JSContext* cx, JS::Value* vp, uint32_t length, - GetBehavior behavior) - : resObj_(cx), - vp_(vp), - index_(0), -#ifdef DEBUG - length_(length), -#endif - getBehavior_(behavior) { - } - - GetBehavior getBehavior() const { return getBehavior_; } - - bool append(JSContext* cx, JS::HandleValue v); - void appendHole(); -}; - -typedef bool (*GetElementsOp)(JSContext* cx, JS::HandleObject obj, - uint32_t begin, uint32_t end, - ElementAdder* adder); - -/** Callback for the creation of constructor and prototype objects. */ -typedef JSObject* (*ClassObjectCreationOp)(JSContext* cx, JSProtoKey key); - -/** - * Callback for custom post-processing after class initialization via - * ClassSpec. - */ -typedef bool (*FinishClassInitOp)(JSContext* cx, JS::HandleObject ctor, - JS::HandleObject proto); - -const size_t JSCLASS_CACHED_PROTO_WIDTH = 7; - -struct MOZ_STATIC_CLASS ClassSpec { - ClassObjectCreationOp createConstructor; - ClassObjectCreationOp createPrototype; - const JSFunctionSpec* constructorFunctions; - const JSPropertySpec* constructorProperties; - const JSFunctionSpec* prototypeFunctions; - const JSPropertySpec* prototypeProperties; - FinishClassInitOp finishInit; - uintptr_t flags; - - static const size_t ProtoKeyWidth = JSCLASS_CACHED_PROTO_WIDTH; - - static const uintptr_t ProtoKeyMask = (1 << ProtoKeyWidth) - 1; - static const uintptr_t DontDefineConstructor = 1 << ProtoKeyWidth; - - bool defined() const { return !!createConstructor; } - - // The ProtoKey this class inherits from. - JSProtoKey inheritanceProtoKey() const { - MOZ_ASSERT(defined()); - static_assert(JSProto_Null == 0, "zeroed key must be null"); - - // Default: Inherit from Object. - if (!(flags & ProtoKeyMask)) { - return JSProto_Object; - } - - return JSProtoKey(flags & ProtoKeyMask); - } - - bool shouldDefineConstructor() const { - MOZ_ASSERT(defined()); - return !(flags & DontDefineConstructor); - } -}; - -struct MOZ_STATIC_CLASS ClassExtension { - /** - * Optional hook called when an object is moved by generational or - * compacting GC. - * - * There may exist weak pointers to an object that are not traced through - * when the normal trace APIs are used, for example objects in the wrapper - * cache. This hook allows these pointers to be updated. - * - * Note that this hook can be called before JS_NewObject() returns if a GC - * is triggered during construction of the object. This can happen for - * global objects for example. - * - * The function should return the difference between nursery bytes used and - * tenured bytes used, which may be nonzero e.g. if some nursery-allocated - * data beyond the actual GC thing is moved into malloced memory. - * - * This is used to compute the nursery promotion rate. - */ - JSObjectMovedOp objectMovedOp; -}; - -struct MOZ_STATIC_CLASS ObjectOps { - LookupPropertyOp lookupProperty; - DefinePropertyOp defineProperty; - HasPropertyOp hasProperty; - GetPropertyOp getProperty; - SetPropertyOp setProperty; - GetOwnPropertyOp getOwnPropertyDescriptor; - DeletePropertyOp deleteProperty; - GetElementsOp getElements; - JSFunToStringOp funToString; -}; - -} // namespace js - -static constexpr const js::ClassSpec* JS_NULL_CLASS_SPEC = nullptr; -static constexpr const js::ClassExtension* JS_NULL_CLASS_EXT = nullptr; - -static constexpr const js::ObjectOps* JS_NULL_OBJECT_OPS = nullptr; - -// Classes, objects, and properties. - -// Objects have private slot. -static const uint32_t JSCLASS_HAS_PRIVATE = 1 << 0; - -// Class's initialization code will call `SetNewObjectMetadata` itself. -static const uint32_t JSCLASS_DELAY_METADATA_BUILDER = 1 << 1; - -// Class is an XPCWrappedNative. WeakMaps use this to override the wrapper -// disposal mechanism. -static const uint32_t JSCLASS_IS_WRAPPED_NATIVE = 1 << 2; - -// Private is `nsISupports*`. -static const uint32_t JSCLASS_PRIVATE_IS_NSISUPPORTS = 1 << 3; - -// Objects are DOM. -static const uint32_t JSCLASS_IS_DOMJSCLASS = 1 << 4; - -// If wrapped by an xray wrapper, the builtin class's constructor won't be -// unwrapped and invoked. Instead, the constructor is resolved in the caller's -// compartment and invoked with a wrapped newTarget. The constructor has to -// detect and handle this situation. See PromiseConstructor for details. -static const uint32_t JSCLASS_HAS_XRAYED_CONSTRUCTOR = 1 << 5; - -// Objects of this class act like the value undefined, in some contexts. -static const uint32_t JSCLASS_EMULATES_UNDEFINED = 1 << 6; - -// Reserved for embeddings. -static const uint32_t JSCLASS_USERBIT1 = 1 << 7; - -// To reserve slots fetched and stored via JS_Get/SetReservedSlot, bitwise-or -// JSCLASS_HAS_RESERVED_SLOTS(n) into the initializer for JSClass.flags, where n -// is a constant in [1, 255]. Reserved slots are indexed from 0 to n-1. - -// Room for 8 flags below ... -static const uintptr_t JSCLASS_RESERVED_SLOTS_SHIFT = 8; -// ... and 16 above this field. -static const uint32_t JSCLASS_RESERVED_SLOTS_WIDTH = 8; - -static const uint32_t JSCLASS_RESERVED_SLOTS_MASK = - js::BitMask(JSCLASS_RESERVED_SLOTS_WIDTH); - -static constexpr uint32_t JSCLASS_HAS_RESERVED_SLOTS(uint32_t n) { - return (n & JSCLASS_RESERVED_SLOTS_MASK) << JSCLASS_RESERVED_SLOTS_SHIFT; -} - -static constexpr uint32_t JSCLASS_HIGH_FLAGS_SHIFT = - JSCLASS_RESERVED_SLOTS_SHIFT + JSCLASS_RESERVED_SLOTS_WIDTH; - -static const uint32_t JSCLASS_INTERNAL_FLAG1 = - 1 << (JSCLASS_HIGH_FLAGS_SHIFT + 0); -static const uint32_t JSCLASS_IS_GLOBAL = 1 << (JSCLASS_HIGH_FLAGS_SHIFT + 1); -static const uint32_t JSCLASS_INTERNAL_FLAG2 = - 1 << (JSCLASS_HIGH_FLAGS_SHIFT + 2); -static const uint32_t JSCLASS_IS_PROXY = 1 << (JSCLASS_HIGH_FLAGS_SHIFT + 3); -static const uint32_t JSCLASS_SKIP_NURSERY_FINALIZE = - 1 << (JSCLASS_HIGH_FLAGS_SHIFT + 4); - -// Reserved for embeddings. -static const uint32_t JSCLASS_USERBIT2 = 1 << (JSCLASS_HIGH_FLAGS_SHIFT + 5); -static const uint32_t JSCLASS_USERBIT3 = 1 << (JSCLASS_HIGH_FLAGS_SHIFT + 6); - -static const uint32_t JSCLASS_BACKGROUND_FINALIZE = - 1 << (JSCLASS_HIGH_FLAGS_SHIFT + 7); -static const uint32_t JSCLASS_FOREGROUND_FINALIZE = - 1 << (JSCLASS_HIGH_FLAGS_SHIFT + 8); - -// Bits 25 through 31 are reserved for the CACHED_PROTO_KEY mechanism, see -// below. - -// ECMA-262 requires that most constructors used internally create objects -// with "the original Foo.prototype value" as their [[Prototype]] (__proto__) -// member initial value. The "original ... value" verbiage is there because -// in ECMA-262, global properties naming class objects are read/write and -// deleteable, for the most part. -// -// Implementing this efficiently requires that global objects have classes -// with the following flags. Failure to use JSCLASS_GLOBAL_FLAGS was -// previously allowed, but is now an ES5 violation and thus unsupported. -// -// JSCLASS_GLOBAL_APPLICATION_SLOTS is the number of slots reserved at -// the beginning of every global object's slots for use by the -// application. -static const uint32_t JSCLASS_GLOBAL_APPLICATION_SLOTS = 5; -static const uint32_t JSCLASS_GLOBAL_SLOT_COUNT = - JSCLASS_GLOBAL_APPLICATION_SLOTS + JSProto_LIMIT * 2 + 25; - -static constexpr uint32_t JSCLASS_GLOBAL_FLAGS_WITH_SLOTS(uint32_t n) { - return JSCLASS_IS_GLOBAL | - JSCLASS_HAS_RESERVED_SLOTS(JSCLASS_GLOBAL_SLOT_COUNT + n); -} - -static constexpr uint32_t JSCLASS_GLOBAL_FLAGS = - JSCLASS_GLOBAL_FLAGS_WITH_SLOTS(0); - -// Fast access to the original value of each standard class's prototype. -static const uint32_t JSCLASS_CACHED_PROTO_SHIFT = JSCLASS_HIGH_FLAGS_SHIFT + 9; -static const uint32_t JSCLASS_CACHED_PROTO_MASK = - js::BitMask(js::JSCLASS_CACHED_PROTO_WIDTH); - -static_assert(JSProto_LIMIT <= (JSCLASS_CACHED_PROTO_MASK + 1), - "JSProtoKey must not exceed the maximum cacheable proto-mask"); - -static constexpr uint32_t JSCLASS_HAS_CACHED_PROTO(JSProtoKey key) { - return uint32_t(key) << JSCLASS_CACHED_PROTO_SHIFT; -} - -struct MOZ_STATIC_CLASS JSClassOps { - /* Function pointer members (may be null). */ - JSAddPropertyOp addProperty; - JSDeletePropertyOp delProperty; - JSEnumerateOp enumerate; - JSNewEnumerateOp newEnumerate; - JSResolveOp resolve; - JSMayResolveOp mayResolve; - JSFinalizeOp finalize; - JSNative call; - JSHasInstanceOp hasInstance; - JSNative construct; - JSTraceOp trace; -}; - -static constexpr const JSClassOps* JS_NULL_CLASS_OPS = nullptr; - -struct alignas(js::gc::JSClassAlignBytes) JSClass { - const char* name; - uint32_t flags; - const JSClassOps* cOps; - - const js::ClassSpec* spec; - const js::ClassExtension* ext; - const js::ObjectOps* oOps; - - // Public accessors: - - JSAddPropertyOp getAddProperty() const { - return cOps ? cOps->addProperty : nullptr; - } - JSDeletePropertyOp getDelProperty() const { - return cOps ? cOps->delProperty : nullptr; - } - JSEnumerateOp getEnumerate() const { - return cOps ? cOps->enumerate : nullptr; - } - JSNewEnumerateOp getNewEnumerate() const { - return cOps ? cOps->newEnumerate : nullptr; - } - JSResolveOp getResolve() const { return cOps ? cOps->resolve : nullptr; } - JSMayResolveOp getMayResolve() const { - return cOps ? cOps->mayResolve : nullptr; - } - JSNative getCall() const { return cOps ? cOps->call : nullptr; } - JSHasInstanceOp getHasInstance() const { - return cOps ? cOps->hasInstance : nullptr; - } - JSNative getConstruct() const { return cOps ? cOps->construct : nullptr; } - - bool hasFinalize() const { return cOps && cOps->finalize; } - bool hasTrace() const { return cOps && cOps->trace; } - - bool isTrace(JSTraceOp trace) const { return cOps && cOps->trace == trace; } - - // The special treatment of |finalize| and |trace| is necessary because if we - // assign either of those hooks to a local variable and then call it -- as is - // done with the other hooks -- the GC hazard analysis gets confused. - void doFinalize(JSFreeOp* fop, JSObject* obj) const { - MOZ_ASSERT(cOps && cOps->finalize); - cOps->finalize(fop, obj); - } - void doTrace(JSTracer* trc, JSObject* obj) const { - MOZ_ASSERT(cOps && cOps->trace); - cOps->trace(trc, obj); - } - - /* - * Objects of this class aren't native objects. They don't have Shapes that - * describe their properties and layout. Classes using this flag must - * provide their own property behavior, either by being proxy classes (do - * this) or by overriding all the ObjectOps except getElements - * (don't do this). - */ - static const uint32_t NON_NATIVE = JSCLASS_INTERNAL_FLAG2; - - bool isNative() const { return !(flags & NON_NATIVE); } - - bool hasPrivate() const { return !!(flags & JSCLASS_HAS_PRIVATE); } - - bool emulatesUndefined() const { return flags & JSCLASS_EMULATES_UNDEFINED; } - - bool isJSFunction() const { return this == js::FunctionClassPtr; } - - bool nonProxyCallable() const { - MOZ_ASSERT(!isProxy()); - return isJSFunction() || getCall(); - } - - bool isGlobal() const { return flags & JSCLASS_IS_GLOBAL; } - - bool isProxy() const { return flags & JSCLASS_IS_PROXY; } - - bool isDOMClass() const { return flags & JSCLASS_IS_DOMJSCLASS; } - - bool shouldDelayMetadataBuilder() const { - return flags & JSCLASS_DELAY_METADATA_BUILDER; - } - - bool isWrappedNative() const { return flags & JSCLASS_IS_WRAPPED_NATIVE; } - - static size_t offsetOfFlags() { return offsetof(JSClass, flags); } - - // Internal / friend API accessors: - - bool specDefined() const { return spec ? spec->defined() : false; } - JSProtoKey specInheritanceProtoKey() const { - return spec ? spec->inheritanceProtoKey() : JSProto_Null; - } - bool specShouldDefineConstructor() const { - return spec ? spec->shouldDefineConstructor() : true; - } - js::ClassObjectCreationOp specCreateConstructorHook() const { - return spec ? spec->createConstructor : nullptr; - } - js::ClassObjectCreationOp specCreatePrototypeHook() const { - return spec ? spec->createPrototype : nullptr; - } - const JSFunctionSpec* specConstructorFunctions() const { - return spec ? spec->constructorFunctions : nullptr; - } - const JSPropertySpec* specConstructorProperties() const { - return spec ? spec->constructorProperties : nullptr; - } - const JSFunctionSpec* specPrototypeFunctions() const { - return spec ? spec->prototypeFunctions : nullptr; - } - const JSPropertySpec* specPrototypeProperties() const { - return spec ? spec->prototypeProperties : nullptr; - } - js::FinishClassInitOp specFinishInitHook() const { - return spec ? spec->finishInit : nullptr; - } - - JSObjectMovedOp extObjectMovedOp() const { - return ext ? ext->objectMovedOp : nullptr; - } - - js::LookupPropertyOp getOpsLookupProperty() const { - return oOps ? oOps->lookupProperty : nullptr; - } - js::DefinePropertyOp getOpsDefineProperty() const { - return oOps ? oOps->defineProperty : nullptr; - } - js::HasPropertyOp getOpsHasProperty() const { - return oOps ? oOps->hasProperty : nullptr; - } - js::GetPropertyOp getOpsGetProperty() const { - return oOps ? oOps->getProperty : nullptr; - } - js::SetPropertyOp getOpsSetProperty() const { - return oOps ? oOps->setProperty : nullptr; - } - js::GetOwnPropertyOp getOpsGetOwnPropertyDescriptor() const { - return oOps ? oOps->getOwnPropertyDescriptor : nullptr; - } - js::DeletePropertyOp getOpsDeleteProperty() const { - return oOps ? oOps->deleteProperty : nullptr; - } - js::GetElementsOp getOpsGetElements() const { - return oOps ? oOps->getElements : nullptr; - } - JSFunToStringOp getOpsFunToString() const { - return oOps ? oOps->funToString : nullptr; - } -}; - -static constexpr uint32_t JSCLASS_RESERVED_SLOTS(const JSClass* clasp) { - return (clasp->flags >> JSCLASS_RESERVED_SLOTS_SHIFT) & - JSCLASS_RESERVED_SLOTS_MASK; -} - -static constexpr bool JSCLASS_HAS_GLOBAL_FLAG_AND_SLOTS(const JSClass* clasp) { - return (clasp->flags & JSCLASS_IS_GLOBAL) && - JSCLASS_RESERVED_SLOTS(clasp) >= JSCLASS_GLOBAL_SLOT_COUNT; -} - -static constexpr JSProtoKey JSCLASS_CACHED_PROTO_KEY(const JSClass* clasp) { - return JSProtoKey((clasp->flags >> JSCLASS_CACHED_PROTO_SHIFT) & - JSCLASS_CACHED_PROTO_MASK); -} - -namespace js { - -/** - * Enumeration describing possible values of the [[Class]] internal property - * value of objects. - */ -enum class ESClass { - Object, - Array, - Number, - String, - Boolean, - RegExp, - ArrayBuffer, - SharedArrayBuffer, - Date, - Set, - Map, - Promise, - MapIterator, - SetIterator, - Arguments, - Error, - BigInt, - Function, // Note: Only JSFunction objects. - - /** None of the above. */ - Other -}; - -/* Fills |vp| with the unboxed value for boxed types, or undefined otherwise. */ -bool Unbox(JSContext* cx, JS::HandleObject obj, JS::MutableHandleValue vp); - -#ifdef DEBUG -JS_FRIEND_API bool HasObjectMovedOp(JSObject* obj); -#endif - -} /* namespace js */ - -#endif /* js_Class_h */ Index: libraries/source/spidermonkey/include-win32-debug/js/ComparisonOperators.h =================================================================== --- /dev/null +++ libraries/source/spidermonkey/include-win32-debug/js/ComparisonOperators.h @@ -1,237 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- - * vim: set ts=8 sts=2 et sw=2 tw=80: - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* - * Support comparison operations on wrapper types -- e.g. |JS::Rooted|, - * |JS::Handle|, and so on -- against raw |T| values, against pointers or - * |nullptr| if the wrapper is a pointer wrapper, and against other wrappers - * around compatible types. - */ - -#ifndef js_ComparisonOperators_h -#define js_ComparisonOperators_h - -#include // std::false_type, std::true_type, std::enable_if_t, std::is_pointer_v, std::remove_pointer_t - -// To define |operator==| and |operator!=| for a wrapper class |W| (which may -// or may not be a template class) that contains a |T|: -// -// * Specialize |JS::detail::DefineComparisonOps| for |W|: -// - Make it inherit from |std::true_type|. -// - Include within your specialization a |static get(const W& v)| function -// that returns the value (which may be an lvalue reference) of the |T| in -// |W|. -// * If needed, add |using JS::detail::wrapper_comparison::operator==;| and -// |using JS::detail::wrapper_comparison::operator!=;| to the namespace -// directly containing |W| at the end of this header. (If you are not in -// SpiderMonkey code and have questionably decided to define your own -// wrapper class, add these to its namespace somewhere in your code.) -// -// The first step opts the wrapper class into comparison support and defines a -// generic means of extracting a comparable |T| out of an instance. -// -// The second step ensures that symmetric |operator==| and |operator!=| are -// exposed for the wrapper, accepting two wrappers or a wrapper and a suitable -// raw value. -// -// Failure to perform *both* steps will likely result in errors like -// 'invalid operands to binary expression' or 'no match for operator==' -// when comparing an instance of your wrapper. - -namespace JS { - -namespace detail { - -// By default, comparison ops are not supported for types. -template -struct DefineComparisonOps : std::false_type {}; - -// Define functions for the core equality operations, that the actual operators -// can all invoke. - -// Compare two wrapper types. Assumes both wrapper types support comparison -// operators. -template -inline bool WrapperEqualsWrapper(const W& wrapper, const OW& other) { - return JS::detail::DefineComparisonOps::get(wrapper) == - JS::detail::DefineComparisonOps::get(other); -} - -// Compare a wrapper against a value of its unwrapped element type (or against a -// value that implicitly converts to that unwrapped element type). Assumes its -// wrapper argument supports comparison operators. -template -inline bool WrapperEqualsUnwrapped(const W& wrapper, - const typename W::ElementType& value) { - return JS::detail::DefineComparisonOps::get(wrapper) == value; -} - -// Compare a wrapper containing a pointer against a pointer to const element -// type. Assumes its wrapper argument supports comparison operators. -template -inline bool WrapperEqualsPointer( - const W& wrapper, - const typename std::remove_pointer_t* ptr) { - return JS::detail::DefineComparisonOps::get(wrapper) == ptr; -} - -// It is idiomatic C++ to define operators on user-defined types in the -// namespace of their operands' types (not at global scope, which isn't examined -// if at point of operator use another operator definition shadows the global -// definition). But our wrappers live in *multiple* namespaces (|namespace js| -// and |namespace JS| in SpiderMonkey), so we can't literally do that without -// defining ambiguous overloads. -// -// Instead, we define the operators *once* in a namespace containing nothing -// else at all. Then we |using| the operators into each namespace containing -// a wrapper type. |using| creates *aliases*, so two |using|s of the same -// operator contribute only one overload to overload resolution. -namespace wrapper_comparison { - -// Comparisons between potentially-differing wrappers. -template -inline typename std::enable_if_t::value && - JS::detail::DefineComparisonOps::value, - bool> -operator==(const W& wrapper, const OW& other) { - return JS::detail::WrapperEqualsWrapper(wrapper, other); -} - -template -inline typename std::enable_if_t::value && - JS::detail::DefineComparisonOps::value, - bool> -operator!=(const W& wrapper, const OW& other) { - return !JS::detail::WrapperEqualsWrapper(wrapper, other); -} - -// Comparisons between a wrapper and its unwrapped element type. -template -inline typename std::enable_if_t::value, bool> -operator==(const W& wrapper, const typename W::ElementType& value) { - return WrapperEqualsUnwrapped(wrapper, value); -} - -template -inline typename std::enable_if_t::value, bool> -operator!=(const W& wrapper, const typename W::ElementType& value) { - return !WrapperEqualsUnwrapped(wrapper, value); -} - -template -inline typename std::enable_if_t::value, bool> -operator==(const typename W::ElementType& value, const W& wrapper) { - return WrapperEqualsUnwrapped(wrapper, value); -} - -template -inline typename std::enable_if_t::value, bool> -operator!=(const typename W::ElementType& value, const W& wrapper) { - return !WrapperEqualsUnwrapped(wrapper, value); -} - -// For wrappers around a pointer type, comparisons between a wrapper object -// and a const element pointer. -template -inline typename std::enable_if_t::value && - std::is_pointer_v, - bool> -operator==(const W& wrapper, - const typename std::remove_pointer_t* ptr) { - return WrapperEqualsPointer(wrapper, ptr); -} - -template -inline typename std::enable_if_t::value && - std::is_pointer_v, - bool> -operator!=(const W& wrapper, - const typename std::remove_pointer_t* ptr) { - return !WrapperEqualsPointer(wrapper, ptr); -} - -template -inline typename std::enable_if_t::value && - std::is_pointer_v, - bool> -operator==(const typename std::remove_pointer_t* ptr, - const W& wrapper) { - return WrapperEqualsPointer(wrapper, ptr); -} - -template -inline typename std::enable_if_t::value && - std::is_pointer_v, - bool> -operator!=(const typename std::remove_pointer_t* ptr, - const W& wrapper) { - return !WrapperEqualsPointer(wrapper, ptr); -} - -// For wrappers around a pointer type, comparisons between a wrapper object -// and |nullptr|. -// -// These overloads are a workaround for gcc hazard build bugs. Per spec, -// |nullptr -> const T*| for the wrapper-pointer operators immediately above -// this is a standard conversion sequence (consisting of a single pointer -// conversion). Meanwhile, |nullptr -> T* const&| for the wrapper-element -// operators just above that, is a pointer conversion to |T*|, then an identity -// conversion of the |T* const| to a reference. The former conversion sequence -// is a proper subsequence of the latter, so it *should* be a better conversion -// sequence and thus should be the better overload. But gcc doesn't implement -// things this way, so we add overloads directly targeting |nullptr| as an exact -// match, preferred to either of those overloads. -// -// We should be able to remove these overloads when gcc hazard builds use modern -// clang. -template -inline typename std::enable_if_t::value, bool> -operator==(const W& wrapper, std::nullptr_t) { - return WrapperEqualsUnwrapped(wrapper, nullptr); -} - -template -inline typename std::enable_if_t::value, bool> -operator!=(const W& wrapper, std::nullptr_t) { - return !WrapperEqualsUnwrapped(wrapper, nullptr); -} - -template -inline typename std::enable_if_t::value, bool> -operator==(std::nullptr_t, const W& wrapper) { - return WrapperEqualsUnwrapped(wrapper, nullptr); -} - -template -inline typename std::enable_if_t::value, bool> -operator!=(std::nullptr_t, const W& wrapper) { - return !WrapperEqualsUnwrapped(wrapper, nullptr); -} - -} // namespace wrapper_comparison - -} // namespace detail - -} // namespace JS - -// Expose wrapper-supporting |operator==| and |operator!=| in the namespaces of -// all SpiderMonkey's wrapper classes that support comparisons. - -namespace JS { - -using JS::detail::wrapper_comparison::operator==; -using JS::detail::wrapper_comparison::operator!=; - -} // namespace JS - -namespace js { - -using JS::detail::wrapper_comparison::operator==; -using JS::detail::wrapper_comparison::operator!=; - -} // namespace js - -#endif // js_ComparisonOperators_h Index: libraries/source/spidermonkey/include-win32-debug/js/CompilationAndEvaluation.h =================================================================== --- /dev/null +++ libraries/source/spidermonkey/include-win32-debug/js/CompilationAndEvaluation.h @@ -1,251 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* Functions for compiling and evaluating scripts. */ - -#ifndef js_CompilationAndEvaluation_h -#define js_CompilationAndEvaluation_h - -#include "mozilla/Utf8.h" // mozilla::Utf8Unit - -#include // size_t -#include // FILE - -#include "jsapi.h" // JSGetElementCallback -#include "jstypes.h" // JS_PUBLIC_API - -#include "js/CompileOptions.h" // JS::CompileOptions, JS::ReadOnlyCompileOptions -#include "js/RootingAPI.h" // JS::Handle, JS::MutableHandle -#include "js/Value.h" // JS::Value and specializations of JS::*Handle-related types - -struct JS_PUBLIC_API JSContext; -class JS_PUBLIC_API JSFunction; -class JS_PUBLIC_API JSObject; -class JS_PUBLIC_API JSScript; - -namespace JS { - -template -class SourceText; - -} // namespace JS - -/** - * Given a buffer, return false if the buffer might become a valid JavaScript - * script with the addition of more lines, or true if the validity of such a - * script is conclusively known (because it's the prefix of a valid script -- - * and possibly the entirety of such a script). - * - * The intent of this function is to enable interactive compilation: accumulate - * lines in a buffer until JS_Utf8BufferIsCompilableUnit is true, then pass it - * to the compiler. - * - * The provided buffer is interpreted as UTF-8 data. An error is reported if - * a UTF-8 encoding error is encountered. - */ -extern JS_PUBLIC_API bool JS_Utf8BufferIsCompilableUnit( - JSContext* cx, JS::Handle obj, const char* utf8, size_t length); - -/* - * NB: JS_ExecuteScript and the JS::Evaluate APIs come in two flavors: either - * they use the global as the scope, or they take a HandleValueVector of - * objects to use as the scope chain. In the former case, the global is also - * used as the "this" keyword value and the variables object (ECMA parlance for - * where 'var' and 'function' bind names) of the execution context for script. - * In the latter case, the first object in the provided list is used, unless the - * list is empty, in which case the global is used. - * - * Why a runtime option? The alternative is to add APIs duplicating those - * for the other value of flags, and that doesn't seem worth the code bloat - * cost. Such new entry points would probably have less obvious names, too, so - * would not tend to be used. The ContextOptionsRef adjustment, OTOH, can be - * more easily hacked into existing code that does not depend on the bug; such - * code can continue to use the familiar JS::Evaluate, etc., entry points. - */ - -/** - * Evaluate a script in the scope of the current global of cx. - */ -extern JS_PUBLIC_API bool JS_ExecuteScript(JSContext* cx, - JS::Handle script, - JS::MutableHandle rval); - -extern JS_PUBLIC_API bool JS_ExecuteScript(JSContext* cx, - JS::Handle script); - -/** - * As above, but providing an explicit scope chain. envChain must not include - * the global object on it; that's implicit. It needs to contain the other - * objects that should end up on the script's scope chain. - */ -extern JS_PUBLIC_API bool JS_ExecuteScript(JSContext* cx, - JS::HandleObjectVector envChain, - JS::Handle script, - JS::MutableHandle rval); - -extern JS_PUBLIC_API bool JS_ExecuteScript(JSContext* cx, - JS::HandleObjectVector envChain, - JS::Handle script); - -namespace JS { - -/** - * Like the above, but handles a cross-compartment script. If the script is - * cross-compartment, it is cloned into the current compartment before - * executing. - */ -extern JS_PUBLIC_API bool CloneAndExecuteScript(JSContext* cx, - Handle script, - MutableHandle rval); - -/** - * Like CloneAndExecuteScript above, but allows executing under a non-syntactic - * environment chain. - */ -extern JS_PUBLIC_API bool CloneAndExecuteScript(JSContext* cx, - HandleObjectVector envChain, - Handle script, - MutableHandle rval); - -/** - * Evaluate the given source buffer in the scope of the current global of cx, - * and return the completion value in |rval|. - */ -extern JS_PUBLIC_API bool Evaluate(JSContext* cx, - const ReadOnlyCompileOptions& options, - SourceText& srcBuf, - MutableHandle rval); - -/** - * As above, but providing an explicit scope chain. envChain must not include - * the global object on it; that's implicit. It needs to contain the other - * objects that should end up on the script's scope chain. - */ -extern JS_PUBLIC_API bool Evaluate(JSContext* cx, HandleObjectVector envChain, - const ReadOnlyCompileOptions& options, - SourceText& srcBuf, - MutableHandle rval); - -/** - * Evaluate the provided UTF-8 data in the scope of the current global of |cx|, - * and return the completion value in |rval|. If the data contains invalid - * UTF-8, an error is reported. - */ -extern JS_PUBLIC_API bool Evaluate(JSContext* cx, - const ReadOnlyCompileOptions& options, - SourceText& srcBuf, - MutableHandle rval); - -/** - * Evaluate the UTF-8 contents of the file at the given path, and return the - * completion value in |rval|. (The path itself is in the system encoding, not - * [necessarily] UTF-8.) If the contents contain any malformed UTF-8, an error - * is reported. - */ -extern JS_PUBLIC_API bool EvaluateUtf8Path( - JSContext* cx, const ReadOnlyCompileOptions& options, const char* filename, - MutableHandle rval); - -/** - * Compile the provided script using the given options. Return the script on - * success, or return null on failure (usually with an error reported). - */ -extern JS_PUBLIC_API JSScript* Compile(JSContext* cx, - const ReadOnlyCompileOptions& options, - SourceText& srcBuf); - -/** - * Compile the provided script using the given options. Return the script on - * success, or return null on failure (usually with an error reported). - */ -extern JS_PUBLIC_API JSScript* Compile(JSContext* cx, - const ReadOnlyCompileOptions& options, - SourceText& srcBuf); - -/** - * Compile the UTF-8 contents of the given file into a script. It is an error - * if the file contains invalid UTF-8. Return the script on success, or return - * null on failure (usually with an error reported). - */ -extern JS_PUBLIC_API JSScript* CompileUtf8File( - JSContext* cx, const ReadOnlyCompileOptions& options, FILE* file); - -/** - * Compile the UTF-8 contents of the file at the given path into a script. - * (The path itself is in the system encoding, not [necessarily] UTF-8.) It - * is an error if the file's contents are invalid UTF-8. Return the script on - * success, or return null on failure (usually with an error reported). - */ -extern JS_PUBLIC_API JSScript* CompileUtf8Path( - JSContext* cx, const ReadOnlyCompileOptions& options, const char* filename); - -extern JS_PUBLIC_API JSScript* CompileForNonSyntacticScope( - JSContext* cx, const ReadOnlyCompileOptions& options, - SourceText& srcBuf); - -/** - * Compile the provided UTF-8 data into a script in a non-syntactic scope. It - * is an error if the data contains invalid UTF-8. Return the script on - * success, or return null on failure (usually with an error reported). - */ -extern JS_PUBLIC_API JSScript* CompileForNonSyntacticScope( - JSContext* cx, const ReadOnlyCompileOptions& options, - SourceText& srcBuf); - -/** - * Compile a function with envChain plus the global as its scope chain. - * envChain must contain objects in the current compartment of cx. The actual - * scope chain used for the function will consist of With wrappers for those - * objects, followed by the current global of the compartment cx is in. This - * global must not be explicitly included in the scope chain. - */ -extern JS_PUBLIC_API JSFunction* CompileFunction( - JSContext* cx, HandleObjectVector envChain, - const ReadOnlyCompileOptions& options, const char* name, unsigned nargs, - const char* const* argnames, SourceText& srcBuf); - -/** - * Compile a function with envChain plus the global as its scope chain. - * envChain must contain objects in the current compartment of cx. The actual - * scope chain used for the function will consist of With wrappers for those - * objects, followed by the current global of the compartment cx is in. This - * global must not be explicitly included in the scope chain. - */ -extern JS_PUBLIC_API JSFunction* CompileFunction( - JSContext* cx, HandleObjectVector envChain, - const ReadOnlyCompileOptions& options, const char* name, unsigned nargs, - const char* const* argnames, SourceText& srcBuf); - -/** - * Identical to the CompileFunction overload above for UTF-8, but with - * Rust-friendly ergonomics. - */ -extern JS_PUBLIC_API JSFunction* CompileFunctionUtf8( - JSContext* cx, HandleObjectVector envChain, - const ReadOnlyCompileOptions& options, const char* name, unsigned nargs, - const char* const* argnames, const char* utf8, size_t length); - -/* - * Associate an element wrapper and attribute name with a previously compiled - * script, for debugging purposes. Calling this function is optional, but should - * be done before script execution if it is required. - */ -extern JS_PUBLIC_API bool InitScriptSourceElement( - JSContext* cx, Handle script, Handle element, - Handle elementAttrName = nullptr); - -/* - * For a script compiled with the hideScriptFromDebugger option, expose the - * script to the debugger by calling the debugger's onNewScript hook. - */ -extern JS_PUBLIC_API void ExposeScriptToDebugger(JSContext* cx, - Handle script); - -extern JS_PUBLIC_API void SetGetElementCallback(JSContext* cx, - JSGetElementCallback callback); - -} /* namespace JS */ - -#endif /* js_CompilationAndEvaluation_h */ Index: libraries/source/spidermonkey/include-win32-debug/js/CompileOptions.h =================================================================== --- /dev/null +++ libraries/source/spidermonkey/include-win32-debug/js/CompileOptions.h @@ -1,436 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* - * Options for JavaScript compilation. - * - * In the most common use case, a CompileOptions instance is allocated on the - * stack, and holds non-owning references to non-POD option values: strings, - * principals, objects, and so on. The code declaring the instance guarantees - * that such option values will outlive the CompileOptions itself: objects are - * otherwise rooted, principals have had their reference counts bumped, and - * strings won't be freed until the CompileOptions goes out of scope. In this - * situation, CompileOptions only refers to things others own, so it can be - * lightweight. - * - * In some cases, however, we need to hold compilation options with a - * non-stack-like lifetime. For example, JS::CompileOffThread needs to save - * compilation options where a worker thread can find them, then return - * immediately. The worker thread will come along at some later point, and use - * the options. - * - * The compiler itself just needs to be able to access a collection of options; - * it doesn't care who owns them, or what's keeping them alive. It does its - * own addrefs/copies/tracing/etc. - * - * Furthermore, in some cases compile options are propagated from one entity to - * another (e.g. from a script to a function defined in that script). This - * involves copying over some, but not all, of the options. - * - * So we have a class hierarchy that reflects these four use cases: - * - * - TransitiveCompileOptions is the common base class, representing options - * that should get propagated from a script to functions defined in that - * script. This class is abstract and is only ever used as a subclass. - * - * - ReadOnlyCompileOptions is the only subclass of TransitiveCompileOptions, - * representing a full set of compile options. It can be used by code that - * simply needs to access options set elsewhere, like the compiler. This - * class too is abstract and is only ever used as a subclass. - * - * - The usual CompileOptions class must be stack-allocated, and holds - * non-owning references to the filename, element, and so on. It's derived - * from ReadOnlyCompileOptions, so the compiler can use it. - * - * - OwningCompileOptions roots / copies / reference counts of all its values, - * and unroots / frees / releases them when it is destructed. It too is - * derived from ReadOnlyCompileOptions, so the compiler accepts it. - */ - -#ifndef js_CompileOptions_h -#define js_CompileOptions_h - -#include "mozilla/Attributes.h" // MOZ_MUST_USE -#include "mozilla/MemoryReporting.h" // mozilla::MallocSizeOf - -#include // size_t -#include // uint8_t - -#include "jstypes.h" // JS_PUBLIC_API - -#include "js/RootingAPI.h" // JS::PersistentRooted, JS::Rooted -#include "js/Value.h" - -struct JS_PUBLIC_API JSContext; -class JS_PUBLIC_API JSObject; -class JS_PUBLIC_API JSScript; -class JS_PUBLIC_API JSString; - -namespace JS { - -enum class AsmJSOption : uint8_t { - Enabled, - Disabled, - DisabledByDebugger, -}; - -/** - * The common base class for the CompileOptions hierarchy. - * - * Use this in code that needs to propagate compile options from one - * compilation unit to another. - */ -class JS_PUBLIC_API TransitiveCompileOptions { - protected: - /** - * The Web Platform allows scripts to be loaded from arbitrary cross-origin - * sources. This allows an attack by which a malicious website loads a - * sensitive file (say, a bank statement) cross-origin (using the user's - * cookies), and sniffs the generated syntax errors (via a window.onerror - * handler) for juicy morsels of its contents. - * - * To counter this attack, HTML5 specifies that script errors should be - * sanitized ("muted") when the script is not same-origin with the global - * for which it is loaded. Callers should set this flag for cross-origin - * scripts, and it will be propagated appropriately to child scripts and - * passed back in JSErrorReports. - */ - bool mutedErrors_ = false; - - // Either the Realm configuration or specialized VM operating modes may - // disallow syntax-parse altogether. These conditions are checked in the - // CompileOptions constructor. - bool forceFullParse_ = false; - - // Either the Realm configuration or the compile request may force - // strict-mode. - bool forceStrictMode_ = false; - - // The context has specified that source pragmas should be parsed. - bool sourcePragmas_ = true; - - const char* filename_ = nullptr; - const char* introducerFilename_ = nullptr; - const char16_t* sourceMapURL_ = nullptr; - - // Flag used to bypass the filename validation callback. - // See also SetFilenameValidationCallback. - bool skipFilenameValidation_ = false; - - public: - // POD options. - bool selfHostingMode = false; - AsmJSOption asmJSOption = AsmJSOption::Disabled; - bool throwOnAsmJSValidationFailureOption = false; - bool forceAsync = false; - bool discardSource = false; - bool sourceIsLazy = false; - bool allowHTMLComments = true; - bool hideScriptFromDebugger = false; - bool nonSyntacticScope = false; - - /** - * |introductionType| is a statically allocated C string: one of "eval", - * "Function", or "GeneratorFunction". - */ - const char* introductionType = nullptr; - - unsigned introductionLineno = 0; - uint32_t introductionOffset = 0; - bool hasIntroductionInfo = false; - - // Mask of operation kinds which should be instrumented. - uint32_t instrumentationKinds = 0; - - protected: - TransitiveCompileOptions() = default; - - // Set all POD options (those not requiring reference counts, copies, - // rooting, or other hand-holding) to their values in |rhs|. - void copyPODTransitiveOptions(const TransitiveCompileOptions& rhs); - - public: - // Read-only accessors for non-POD options. The proper way to set these - // depends on the derived type. - bool mutedErrors() const { return mutedErrors_; } - bool forceFullParse() const { return forceFullParse_; } - bool forceStrictMode() const { return forceStrictMode_; } - bool skipFilenameValidation() const { return skipFilenameValidation_; } - bool sourcePragmas() const { return sourcePragmas_; } - const char* filename() const { return filename_; } - const char* introducerFilename() const { return introducerFilename_; } - const char16_t* sourceMapURL() const { return sourceMapURL_; } - virtual Value privateValue() const = 0; - virtual JSString* elementAttributeName() const = 0; - virtual JSScript* introductionScript() const = 0; - - // For some compilations the spec requires the ScriptOrModule field of the - // resulting script to be set to the currently executing script. This can be - // achieved by setting this option with setScriptOrModule() below. - // - // Note that this field doesn't explicitly exist in our implementation; - // instead the ScriptSourceObject's private value is set to that associated - // with the specified script. - virtual JSScript* scriptOrModule() const = 0; - - TransitiveCompileOptions(const TransitiveCompileOptions&) = delete; - TransitiveCompileOptions& operator=(const TransitiveCompileOptions&) = delete; -}; - -/** - * The class representing a full set of compile options. - * - * Use this in code that only needs to access compilation options created - * elsewhere, like the compiler. Don't instantiate this class (the constructor - * is protected anyway); instead, create instances only of the derived classes: - * CompileOptions and OwningCompileOptions. - */ -class JS_PUBLIC_API ReadOnlyCompileOptions : public TransitiveCompileOptions { - public: - // POD options. - unsigned lineno = 1; - unsigned column = 0; - - // The offset within the ScriptSource's full uncompressed text of the first - // character we're presenting for compilation with this CompileOptions. - // - // When we compile a lazy script, we pass the compiler only the substring of - // the source the lazy function occupies. With chunked decompression, we may - // not even have the complete uncompressed source present in memory. But parse - // node positions are offsets within the ScriptSource's full text, and - // BaseScript indicate their substring of the full source by its starting and - // ending offsets within the full text. This scriptSourceOffset field lets the - // frontend convert between these offsets and offsets within the substring - // presented for compilation. - unsigned scriptSourceOffset = 0; - - // These only apply to non-function scripts. - bool isRunOnce = false; - bool noScriptRval = false; - - protected: - ReadOnlyCompileOptions() = default; - - void copyPODNonTransitiveOptions(const ReadOnlyCompileOptions& rhs); - - ReadOnlyCompileOptions(const ReadOnlyCompileOptions&) = delete; - ReadOnlyCompileOptions& operator=(const ReadOnlyCompileOptions&) = delete; -}; - -/** - * Compilation options, with dynamic lifetime. An instance of this type - * makes a copy of / holds / roots all dynamically allocated resources - * (principals; elements; strings) that it refers to. Its destructor frees - * / drops / unroots them. This is heavier than CompileOptions, below, but - * unlike CompileOptions, it can outlive any given stack frame. - * - * Note that this *roots* any JS values it refers to - they're live - * unconditionally. Thus, instances of this type can't be owned, directly - * or indirectly, by a JavaScript object: if any value that this roots ever - * comes to refer to the object that owns this, then the whole cycle, and - * anything else it entrains, will never be freed. - */ -class JS_PUBLIC_API OwningCompileOptions final : public ReadOnlyCompileOptions { - PersistentRooted elementAttributeNameRoot; - PersistentRooted introductionScriptRoot; - PersistentRooted scriptOrModuleRoot; - PersistentRooted privateValueRoot; - - public: - // A minimal constructor, for use with OwningCompileOptions::copy. - explicit OwningCompileOptions(JSContext* cx); - ~OwningCompileOptions(); - - Value privateValue() const override { return privateValueRoot; } - JSString* elementAttributeName() const override { - return elementAttributeNameRoot; - } - JSScript* introductionScript() const override { - return introductionScriptRoot; - } - JSScript* scriptOrModule() const override { return scriptOrModuleRoot; } - - /** Set this to a copy of |rhs|. Return false on OOM. */ - bool copy(JSContext* cx, const ReadOnlyCompileOptions& rhs); - - size_t sizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf) const; - - private: - void release(); - - OwningCompileOptions(const OwningCompileOptions&) = delete; - OwningCompileOptions& operator=(const OwningCompileOptions&) = delete; -}; - -/** - * Compilation options stored on the stack. An instance of this type - * simply holds references to dynamically allocated resources (element; - * filename; source map URL) that are owned by something else. If you - * create an instance of this type, it's up to you to guarantee that - * everything you store in it will outlive it. - */ -class MOZ_STACK_CLASS JS_PUBLIC_API CompileOptions final - : public ReadOnlyCompileOptions { - private: - Rooted elementAttributeNameRoot; - Rooted introductionScriptRoot; - Rooted scriptOrModuleRoot; - Rooted privateValueRoot; - - public: - // Default options determined using the JSContext. - explicit CompileOptions(JSContext* cx); - - // Copy both the transitive and the non-transitive options from another - // options object. - CompileOptions(JSContext* cx, const ReadOnlyCompileOptions& rhs) - : ReadOnlyCompileOptions(), - elementAttributeNameRoot(cx), - introductionScriptRoot(cx), - scriptOrModuleRoot(cx), - privateValueRoot(cx) { - copyPODNonTransitiveOptions(rhs); - copyPODTransitiveOptions(rhs); - - filename_ = rhs.filename(); - introducerFilename_ = rhs.introducerFilename(); - sourceMapURL_ = rhs.sourceMapURL(); - privateValueRoot = rhs.privateValue(); - elementAttributeNameRoot = rhs.elementAttributeName(); - introductionScriptRoot = rhs.introductionScript(); - scriptOrModuleRoot = rhs.scriptOrModule(); - } - - Value privateValue() const override { return privateValueRoot; } - - JSString* elementAttributeName() const override { - return elementAttributeNameRoot; - } - - JSScript* introductionScript() const override { - return introductionScriptRoot; - } - - JSScript* scriptOrModule() const override { return scriptOrModuleRoot; } - - CompileOptions& setFile(const char* f) { - filename_ = f; - return *this; - } - - CompileOptions& setLine(unsigned l) { - lineno = l; - return *this; - } - - CompileOptions& setFileAndLine(const char* f, unsigned l) { - filename_ = f; - lineno = l; - return *this; - } - - CompileOptions& setSourceMapURL(const char16_t* s) { - sourceMapURL_ = s; - return *this; - } - - CompileOptions& setPrivateValue(const Value& v) { - privateValueRoot = v; - return *this; - } - - CompileOptions& setElementAttributeName(JSString* p) { - elementAttributeNameRoot = p; - return *this; - } - - CompileOptions& setScriptOrModule(JSScript* s) { - scriptOrModuleRoot = s; - return *this; - } - - CompileOptions& setMutedErrors(bool mute) { - mutedErrors_ = mute; - return *this; - } - - CompileOptions& setColumn(unsigned c) { - column = c; - return *this; - } - - CompileOptions& setScriptSourceOffset(unsigned o) { - scriptSourceOffset = o; - return *this; - } - - CompileOptions& setIsRunOnce(bool once) { - isRunOnce = once; - return *this; - } - - CompileOptions& setNoScriptRval(bool nsr) { - noScriptRval = nsr; - return *this; - } - - CompileOptions& setSkipFilenameValidation(bool b) { - skipFilenameValidation_ = b; - return *this; - } - - CompileOptions& setSelfHostingMode(bool shm) { - selfHostingMode = shm; - return *this; - } - - CompileOptions& setSourceIsLazy(bool l) { - sourceIsLazy = l; - return *this; - } - - CompileOptions& setNonSyntacticScope(bool n) { - nonSyntacticScope = n; - return *this; - } - - CompileOptions& setIntroductionType(const char* t) { - introductionType = t; - return *this; - } - - CompileOptions& setIntroductionInfo(const char* introducerFn, - const char* intro, unsigned line, - JSScript* script, uint32_t offset) { - introducerFilename_ = introducerFn; - introductionType = intro; - introductionLineno = line; - introductionScriptRoot = script; - introductionOffset = offset; - hasIntroductionInfo = true; - return *this; - } - - // Set introduction information according to any currently executing script. - CompileOptions& setIntroductionInfoToCaller(JSContext* cx, - const char* introductionType); - - CompileOptions& setForceFullParse() { - forceFullParse_ = true; - return *this; - } - - CompileOptions& setForceStrictMode() { - forceStrictMode_ = true; - return *this; - } - - CompileOptions(const CompileOptions& rhs) = delete; - CompileOptions& operator=(const CompileOptions& rhs) = delete; -}; - -} // namespace JS - -#endif /* js_CompileOptions_h */ Index: libraries/source/spidermonkey/include-win32-debug/js/ContextOptions.h =================================================================== --- /dev/null +++ libraries/source/spidermonkey/include-win32-debug/js/ContextOptions.h @@ -1,250 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- - * vim: set ts=8 sts=2 et sw=2 tw=80: - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* JavaScript API. */ - -#ifndef js_ContextOptions_h -#define js_ContextOptions_h - -#include "jstypes.h" // JS_PUBLIC_API - -struct JS_PUBLIC_API JSContext; - -namespace JS { - -class JS_PUBLIC_API ContextOptions { - public: - ContextOptions() - : asmJS_(true), - wasm_(true), - wasmForTrustedPrinciples_(true), - wasmVerbose_(false), - wasmBaseline_(true), - wasmIon_(true), - wasmCranelift_(false), - wasmReftypes_(true), - wasmGc_(false), - wasmMultiValue_(false), - wasmSimd_(false), - testWasmAwaitTier2_(false), - throwOnAsmJSValidationFailure_(false), - disableIon_(false), - disableEvalSecurityChecks_(false), - asyncStack_(true), - sourcePragmas_(true), - throwOnDebuggeeWouldRun_(true), - dumpStackOnDebuggeeWouldRun_(false), - strictMode_(false), -#ifdef JS_ENABLE_SMOOSH - trackNotImplemented_(false), - trySmoosh_(false), -#endif - fuzzing_(false) { - } - - bool asmJS() const { return asmJS_; } - ContextOptions& setAsmJS(bool flag) { - asmJS_ = flag; - return *this; - } - ContextOptions& toggleAsmJS() { - asmJS_ = !asmJS_; - return *this; - } - - bool wasm() const { return wasm_; } - ContextOptions& setWasm(bool flag) { - wasm_ = flag; - return *this; - } - ContextOptions& toggleWasm() { - wasm_ = !wasm_; - return *this; - } - - bool wasmForTrustedPrinciples() const { return wasmForTrustedPrinciples_; } - ContextOptions& setWasmForTrustedPrinciples(bool flag) { - wasmForTrustedPrinciples_ = flag; - return *this; - } - - bool wasmVerbose() const { return wasmVerbose_; } - ContextOptions& setWasmVerbose(bool flag) { - wasmVerbose_ = flag; - return *this; - } - - bool wasmBaseline() const { return wasmBaseline_; } - ContextOptions& setWasmBaseline(bool flag) { - wasmBaseline_ = flag; - return *this; - } - - bool wasmIon() const { return wasmIon_; } - ContextOptions& setWasmIon(bool flag) { - wasmIon_ = flag; - return *this; - } - - bool wasmCranelift() const { return wasmCranelift_; } - // Defined out-of-line because it depends on a compile-time option - ContextOptions& setWasmCranelift(bool flag); - - bool testWasmAwaitTier2() const { return testWasmAwaitTier2_; } - ContextOptions& setTestWasmAwaitTier2(bool flag) { - testWasmAwaitTier2_ = flag; - return *this; - } - - bool wasmReftypes() const { return wasmReftypes_; } - ContextOptions& setWasmReftypes(bool flag) { - wasmReftypes_ = flag; - return *this; - } - - bool wasmGc() const { return wasmGc_; } - // Defined out-of-line because it depends on a compile-time option - ContextOptions& setWasmGc(bool flag); - - bool wasmMultiValue() const { return wasmMultiValue_; } - // Defined out-of-line because it depends on a compile-time option - ContextOptions& setWasmMultiValue(bool flag); - - bool wasmSimd() const { return wasmSimd_; } - // Defined out-of-line because it depends on a compile-time option - ContextOptions& setWasmSimd(bool flag); - - bool throwOnAsmJSValidationFailure() const { - return throwOnAsmJSValidationFailure_; - } - ContextOptions& setThrowOnAsmJSValidationFailure(bool flag) { - throwOnAsmJSValidationFailure_ = flag; - return *this; - } - ContextOptions& toggleThrowOnAsmJSValidationFailure() { - throwOnAsmJSValidationFailure_ = !throwOnAsmJSValidationFailure_; - return *this; - } - - // Override to allow disabling Ion for this context irrespective of the - // process-wide Ion-enabled setting. This must be set right after creating - // the context. - bool disableIon() const { return disableIon_; } - ContextOptions& setDisableIon() { - disableIon_ = true; - return *this; - } - - // Override to allow disabling the eval restriction security checks for - // this context. - bool disableEvalSecurityChecks() const { return disableEvalSecurityChecks_; } - ContextOptions& setDisableEvalSecurityChecks() { - disableEvalSecurityChecks_ = true; - return *this; - } - - bool asyncStack() const { return asyncStack_; } - ContextOptions& setAsyncStack(bool flag) { - asyncStack_ = flag; - return *this; - } - - // Enable/disable support for parsing '//(#@) source(Mapping)?URL=' pragmas. - bool sourcePragmas() const { return sourcePragmas_; } - ContextOptions& setSourcePragmas(bool flag) { - sourcePragmas_ = flag; - return *this; - } - - bool throwOnDebuggeeWouldRun() const { return throwOnDebuggeeWouldRun_; } - ContextOptions& setThrowOnDebuggeeWouldRun(bool flag) { - throwOnDebuggeeWouldRun_ = flag; - return *this; - } - - bool dumpStackOnDebuggeeWouldRun() const { - return dumpStackOnDebuggeeWouldRun_; - } - ContextOptions& setDumpStackOnDebuggeeWouldRun(bool flag) { - dumpStackOnDebuggeeWouldRun_ = flag; - return *this; - } - - bool strictMode() const { return strictMode_; } - ContextOptions& setStrictMode(bool flag) { - strictMode_ = flag; - return *this; - } - ContextOptions& toggleStrictMode() { - strictMode_ = !strictMode_; - return *this; - } - -#ifdef JS_ENABLE_SMOOSH - // Track Number of Not Implemented Calls by writing to a file - bool trackNotImplemented() const { return trackNotImplemented_; } - ContextOptions& setTrackNotImplemented(bool flag) { - trackNotImplemented_ = flag; - return *this; - } - - // Try compiling SmooshMonkey frontend first, and fallback to C++ - // implementation when it fails. - bool trySmoosh() const { return trySmoosh_; } - ContextOptions& setTrySmoosh(bool flag) { - trySmoosh_ = flag; - return *this; - } - -#endif // JS_ENABLE_SMOOSH - - bool fuzzing() const { return fuzzing_; } - // Defined out-of-line because it depends on a compile-time option - ContextOptions& setFuzzing(bool flag); - - void disableOptionsForSafeMode() { - setAsmJS(false); - setWasm(false); - setWasmBaseline(false); - setWasmIon(false); - setWasmGc(false); - setWasmMultiValue(false); - setWasmSimd(false); - } - - private: - bool asmJS_ : 1; - bool wasm_ : 1; - bool wasmForTrustedPrinciples_ : 1; - bool wasmVerbose_ : 1; - bool wasmBaseline_ : 1; - bool wasmIon_ : 1; - bool wasmCranelift_ : 1; - bool wasmReftypes_ : 1; - bool wasmGc_ : 1; - bool wasmMultiValue_ : 1; - bool wasmSimd_ : 1; - bool testWasmAwaitTier2_ : 1; - bool throwOnAsmJSValidationFailure_ : 1; - bool disableIon_ : 1; - bool disableEvalSecurityChecks_ : 1; - bool asyncStack_ : 1; - bool sourcePragmas_ : 1; - bool throwOnDebuggeeWouldRun_ : 1; - bool dumpStackOnDebuggeeWouldRun_ : 1; - bool strictMode_ : 1; -#ifdef JS_ENABLE_SMOOSH - bool trackNotImplemented_ : 1; - bool trySmoosh_ : 1; -#endif - bool fuzzing_ : 1; -}; - -JS_PUBLIC_API ContextOptions& ContextOptionsRef(JSContext* cx); - -} // namespace JS - -#endif // js_ContextOptions_h Index: libraries/source/spidermonkey/include-win32-debug/js/Conversions.h =================================================================== --- /dev/null +++ libraries/source/spidermonkey/include-win32-debug/js/Conversions.h @@ -1,590 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- - * vim: set ts=8 sts=2 et sw=2 tw=80: - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* ECMAScript conversion operations. */ - -#ifndef js_Conversions_h -#define js_Conversions_h - -#include "mozilla/Casting.h" -#include "mozilla/Compiler.h" -#include "mozilla/FloatingPoint.h" -#include "mozilla/MathAlgorithms.h" -#include "mozilla/WrappingOperations.h" - -#include -#include // size_t -#include // {u,}int{8,16,32,64}_t -#include - -#include "jspubtd.h" -#include "jstypes.h" // JS_PUBLIC_API - -#include "js/RootingAPI.h" -#include "js/Value.h" - -namespace js { - -/* DO NOT CALL THIS. Use JS::ToBoolean. */ -extern JS_PUBLIC_API bool ToBooleanSlow(JS::HandleValue v); - -/* DO NOT CALL THIS. Use JS::ToNumber. */ -extern JS_PUBLIC_API bool ToNumberSlow(JSContext* cx, JS::HandleValue v, - double* dp); - -/* DO NOT CALL THIS. Use JS::ToInt8. */ -extern JS_PUBLIC_API bool ToInt8Slow(JSContext* cx, JS::HandleValue v, - int8_t* out); - -/* DO NOT CALL THIS. Use JS::ToUint8. */ -extern JS_PUBLIC_API bool ToUint8Slow(JSContext* cx, JS::HandleValue v, - uint8_t* out); - -/* DO NOT CALL THIS. Use JS::ToInt16. */ -extern JS_PUBLIC_API bool ToInt16Slow(JSContext* cx, JS::HandleValue v, - int16_t* out); - -/* DO NOT CALL THIS. Use JS::ToInt32. */ -extern JS_PUBLIC_API bool ToInt32Slow(JSContext* cx, JS::HandleValue v, - int32_t* out); - -/* DO NOT CALL THIS. Use JS::ToUint32. */ -extern JS_PUBLIC_API bool ToUint32Slow(JSContext* cx, JS::HandleValue v, - uint32_t* out); - -/* DO NOT CALL THIS. Use JS::ToUint16. */ -extern JS_PUBLIC_API bool ToUint16Slow(JSContext* cx, JS::HandleValue v, - uint16_t* out); - -/* DO NOT CALL THIS. Use JS::ToInt64. */ -extern JS_PUBLIC_API bool ToInt64Slow(JSContext* cx, JS::HandleValue v, - int64_t* out); - -/* DO NOT CALL THIS. Use JS::ToUint64. */ -extern JS_PUBLIC_API bool ToUint64Slow(JSContext* cx, JS::HandleValue v, - uint64_t* out); - -/* DO NOT CALL THIS. Use JS::ToString. */ -extern JS_PUBLIC_API JSString* ToStringSlow(JSContext* cx, JS::HandleValue v); - -/* DO NOT CALL THIS. Use JS::ToObject. */ -extern JS_PUBLIC_API JSObject* ToObjectSlow(JSContext* cx, JS::HandleValue v, - bool reportScanStack); - -} // namespace js - -namespace JS { - -namespace detail { - -#ifdef JS_DEBUG -/** - * Assert that we're not doing GC on cx, that we're in a request as - * needed, and that the compartments for cx and v are correct. - * Also check that GC would be safe at this point. - */ -extern JS_PUBLIC_API void AssertArgumentsAreSane(JSContext* cx, HandleValue v); -#else -inline void AssertArgumentsAreSane(JSContext* cx, HandleValue v) {} -#endif /* JS_DEBUG */ - -} // namespace detail - -/** - * ES6 draft 20141224, 7.1.1, second algorithm. - * - * Most users shouldn't call this -- use JS::ToBoolean, ToNumber, or ToString - * instead. This will typically only be called from custom convert hooks that - * wish to fall back to the ES6 default conversion behavior shared by most - * objects in JS, codified as OrdinaryToPrimitive. - */ -extern JS_PUBLIC_API bool OrdinaryToPrimitive(JSContext* cx, HandleObject obj, - JSType type, - MutableHandleValue vp); - -/* ES6 draft 20141224, 7.1.2. */ -MOZ_ALWAYS_INLINE bool ToBoolean(HandleValue v) { - if (v.isBoolean()) { - return v.toBoolean(); - } - if (v.isInt32()) { - return v.toInt32() != 0; - } - if (v.isNullOrUndefined()) { - return false; - } - if (v.isDouble()) { - double d = v.toDouble(); - return !mozilla::IsNaN(d) && d != 0; - } - if (v.isSymbol()) { - return true; - } - - /* The slow path handles strings, BigInts and objects. */ - return js::ToBooleanSlow(v); -} - -/* ES6 draft 20141224, 7.1.3. */ -MOZ_ALWAYS_INLINE bool ToNumber(JSContext* cx, HandleValue v, double* out) { - detail::AssertArgumentsAreSane(cx, v); - - if (v.isNumber()) { - *out = v.toNumber(); - return true; - } - return js::ToNumberSlow(cx, v, out); -} - -// ES2020 draft rev 6b05bc56ba4e3c7a2b9922c4282d9eb844426d9b -// 7.1.5 ToInteger ( argument ) -// -// Specialized for double values. -inline double ToInteger(double d) { - if (d == 0) { - return 0; - } - - if (!mozilla::IsFinite(d)) { - if (mozilla::IsNaN(d)) { - return 0; - } - return d; - } - - return std::trunc(d) + (+0.0); // Add zero to convert -0 to +0. -} - -/* ES6 draft 20141224, 7.1.5. */ -MOZ_ALWAYS_INLINE bool ToInt32(JSContext* cx, JS::HandleValue v, int32_t* out) { - detail::AssertArgumentsAreSane(cx, v); - - if (v.isInt32()) { - *out = v.toInt32(); - return true; - } - return js::ToInt32Slow(cx, v, out); -} - -/* ES6 draft 20141224, 7.1.6. */ -MOZ_ALWAYS_INLINE bool ToUint32(JSContext* cx, HandleValue v, uint32_t* out) { - detail::AssertArgumentsAreSane(cx, v); - - if (v.isInt32()) { - *out = uint32_t(v.toInt32()); - return true; - } - return js::ToUint32Slow(cx, v, out); -} - -/* ES6 draft 20141224, 7.1.7. */ -MOZ_ALWAYS_INLINE bool ToInt16(JSContext* cx, JS::HandleValue v, int16_t* out) { - detail::AssertArgumentsAreSane(cx, v); - - if (v.isInt32()) { - *out = int16_t(v.toInt32()); - return true; - } - return js::ToInt16Slow(cx, v, out); -} - -/* ES6 draft 20141224, 7.1.8. */ -MOZ_ALWAYS_INLINE bool ToUint16(JSContext* cx, HandleValue v, uint16_t* out) { - detail::AssertArgumentsAreSane(cx, v); - - if (v.isInt32()) { - *out = uint16_t(v.toInt32()); - return true; - } - return js::ToUint16Slow(cx, v, out); -} - -/* ES6 draft 20141224, 7.1.9 */ -MOZ_ALWAYS_INLINE bool ToInt8(JSContext* cx, JS::HandleValue v, int8_t* out) { - detail::AssertArgumentsAreSane(cx, v); - - if (v.isInt32()) { - *out = int8_t(v.toInt32()); - return true; - } - return js::ToInt8Slow(cx, v, out); -} - -/* ES6 ECMA-262, 7.1.10 */ -MOZ_ALWAYS_INLINE bool ToUint8(JSContext* cx, JS::HandleValue v, uint8_t* out) { - detail::AssertArgumentsAreSane(cx, v); - - if (v.isInt32()) { - *out = uint8_t(v.toInt32()); - return true; - } - return js::ToUint8Slow(cx, v, out); -} - -/* - * Non-standard, with behavior similar to that of ToInt32, except in its - * producing an int64_t. - */ -MOZ_ALWAYS_INLINE bool ToInt64(JSContext* cx, HandleValue v, int64_t* out) { - detail::AssertArgumentsAreSane(cx, v); - - if (v.isInt32()) { - *out = int64_t(v.toInt32()); - return true; - } - return js::ToInt64Slow(cx, v, out); -} - -/* - * Non-standard, with behavior similar to that of ToUint32, except in its - * producing a uint64_t. - */ -MOZ_ALWAYS_INLINE bool ToUint64(JSContext* cx, HandleValue v, uint64_t* out) { - detail::AssertArgumentsAreSane(cx, v); - - if (v.isInt32()) { - *out = uint64_t(v.toInt32()); - return true; - } - return js::ToUint64Slow(cx, v, out); -} - -/* ES6 draft 20141224, 7.1.12. */ -MOZ_ALWAYS_INLINE JSString* ToString(JSContext* cx, HandleValue v) { - detail::AssertArgumentsAreSane(cx, v); - - if (v.isString()) { - return v.toString(); - } - return js::ToStringSlow(cx, v); -} - -/* ES6 draft 20141224, 7.1.13. */ -inline JSObject* ToObject(JSContext* cx, HandleValue v) { - detail::AssertArgumentsAreSane(cx, v); - - if (v.isObject()) { - return &v.toObject(); - } - return js::ToObjectSlow(cx, v, false); -} - -/** - * Convert a double value to UnsignedInteger (an unsigned integral type) using - * ECMAScript-style semantics (that is, in like manner to how ECMAScript's - * ToInt32 converts to int32_t). - * - * If d is infinite or NaN, return 0. - * Otherwise compute d2 = sign(d) * floor(abs(d)), and return the - * UnsignedInteger value congruent to d2 % 2**(bit width of UnsignedInteger). - * - * The algorithm below is inspired by that found in - * - * but has been generalized to all integer widths. - */ -template -inline UnsignedInteger ToUnsignedInteger(double d) { - static_assert(std::is_unsigned_v, - "UnsignedInteger must be an unsigned type"); - - uint64_t bits = mozilla::BitwiseCast(d); - unsigned DoubleExponentShift = mozilla::FloatingPoint::kExponentShift; - - // Extract the exponent component. (Be careful here! It's not technically - // the exponent in NaN, infinities, and subnormals.) - int_fast16_t exp = - int_fast16_t((bits & mozilla::FloatingPoint::kExponentBits) >> - DoubleExponentShift) - - int_fast16_t(mozilla::FloatingPoint::kExponentBias); - - // If the exponent's less than zero, abs(d) < 1, so the result is 0. (This - // also handles subnormals.) - if (exp < 0) { - return 0; - } - - uint_fast16_t exponent = mozilla::AssertedCast(exp); - - // If the exponent is greater than or equal to the bits of precision of a - // double plus UnsignedInteger's width, the number is either infinite, NaN, - // or too large to have lower-order bits in the congruent value. (Example: - // 2**84 is exactly representable as a double. The next exact double is - // 2**84 + 2**32. Thus if UnsignedInteger is uint32_t, an exponent >= 84 - // implies floor(abs(d)) == 0 mod 2**32.) Return 0 in all these cases. - constexpr size_t ResultWidth = CHAR_BIT * sizeof(UnsignedInteger); - if (exponent >= DoubleExponentShift + ResultWidth) { - return 0; - } - - // The significand contains the bits that will determine the final result. - // Shift those bits left or right, according to the exponent, to their - // locations in the unsigned binary representation of floor(abs(d)). - static_assert(sizeof(UnsignedInteger) <= sizeof(uint64_t), - "left-shifting below would lose upper bits"); - UnsignedInteger result = - (exponent > DoubleExponentShift) - ? UnsignedInteger(bits << (exponent - DoubleExponentShift)) - : UnsignedInteger(bits >> (DoubleExponentShift - exponent)); - - // Two further complications remain. First, |result| may contain bogus - // sign/exponent bits. Second, IEEE-754 numbers' significands (excluding - // subnormals, but we already handled those) have an implicit leading 1 - // which may affect the final result. - // - // It may appear that there's complexity here depending on how ResultWidth - // and DoubleExponentShift relate, but it turns out there's not. - // - // Assume ResultWidth < DoubleExponentShift: - // Only right-shifts leave bogus bits in |result|. For this to happen, - // we must right-shift by > |DoubleExponentShift - ResultWidth|, implying - // |exponent < ResultWidth|. - // The implicit leading bit only matters if it appears in the final - // result -- if |2**exponent mod 2**ResultWidth != 0|. This implies - // |exponent < ResultWidth|. - // Otherwise assume ResultWidth >= DoubleExponentShift: - // Any left-shift less than |ResultWidth - DoubleExponentShift| leaves - // bogus bits in |result|. This implies |exponent < ResultWidth|. Any - // right-shift less than |ResultWidth| does too, which implies - // |DoubleExponentShift - ResultWidth < exponent|. By assumption, then, - // |exponent| is negative, but we excluded that above. So bogus bits - // need only |exponent < ResultWidth|. - // The implicit leading bit matters identically to the other case, so - // again, |exponent < ResultWidth|. - if (exponent < ResultWidth) { - const auto implicitOne = - static_cast(UnsignedInteger{1} << exponent); - result &= implicitOne - 1; // remove bogus bits - result += implicitOne; // add the implicit bit - } - - // Compute the congruent value in the signed range. - return (bits & mozilla::FloatingPoint::kSignBit) ? ~result + 1 - : result; -} - -template -inline SignedInteger ToSignedInteger(double d) { - static_assert(std::is_signed_v, - "SignedInteger must be a signed type"); - - using UnsignedInteger = std::make_unsigned_t; - UnsignedInteger u = ToUnsignedInteger(d); - - return mozilla::WrapToSigned(u); -} - -// clang crashes compiling this when targeting arm: -// https://llvm.org/bugs/show_bug.cgi?id=22974 -#if defined(__arm__) && MOZ_IS_GCC - -template <> -inline int32_t ToSignedInteger(double d) { - int32_t i; - uint32_t tmp0; - uint32_t tmp1; - uint32_t tmp2; - asm( - // We use a pure integer solution here. In the 'softfp' ABI, the argument - // will start in r0 and r1, and VFP can't do all of the necessary ECMA - // conversions by itself so some integer code will be required anyway. A - // hybrid solution is faster on A9, but this pure integer solution is - // notably faster for A8. - - // %0 is the result register, and may alias either of the %[QR]1 - // registers. - // %Q4 holds the lower part of the mantissa. - // %R4 holds the sign, exponent, and the upper part of the mantissa. - // %1, %2 and %3 are used as temporary values. - - // Extract the exponent. - " mov %1, %R4, LSR #20\n" - " bic %1, %1, #(1 << 11)\n" // Clear the sign. - - // Set the implicit top bit of the mantissa. This clobbers a bit of the - // exponent, but we have already extracted that. - " orr %R4, %R4, #(1 << 20)\n" - - // Special Cases - // We should return zero in the following special cases: - // - Exponent is 0x000 - 1023: +/-0 or subnormal. - // - Exponent is 0x7ff - 1023: +/-INFINITY or NaN - // - This case is implicitly handled by the standard code path - // anyway, as shifting the mantissa up by the exponent will - // result in '0'. - // - // The result is composed of the mantissa, prepended with '1' and - // bit-shifted left by the (decoded) exponent. Note that because the - // r1[20] is the bit with value '1', r1 is effectively already shifted - // (left) by 20 bits, and r0 is already shifted by 52 bits. - - // Adjust the exponent to remove the encoding offset. If the decoded - // exponent is negative, quickly bail out with '0' as such values round to - // zero anyway. This also catches +/-0 and subnormals. - " sub %1, %1, #0xff\n" - " subs %1, %1, #0x300\n" - " bmi 8f\n" - - // %1 = (decoded) exponent >= 0 - // %R4 = upper mantissa and sign - - // ---- Lower Mantissa ---- - " subs %3, %1, #52\n" // Calculate exp-52 - " bmi 1f\n" - - // Shift r0 left by exp-52. - // Ensure that we don't overflow ARM's 8-bit shift operand range. - // We need to handle anything up to an 11-bit value here as we know that - // 52 <= exp <= 1024 (0x400). Any shift beyond 31 bits results in zero - // anyway, so as long as we don't touch the bottom 5 bits, we can use - // a logical OR to push long shifts into the 32 <= (exp&0xff) <= 255 - // range. - " bic %2, %3, #0xff\n" - " orr %3, %3, %2, LSR #3\n" - // We can now perform a straight shift, avoiding the need for any - // conditional instructions or extra branches. - " mov %Q4, %Q4, LSL %3\n" - " b 2f\n" - "1:\n" // Shift r0 right by 52-exp. - // We know that 0 <= exp < 52, and we can shift up to 255 bits so - // 52-exp will always be a valid shift and we can sk%3 the range - // check for this case. - " rsb %3, %1, #52\n" - " mov %Q4, %Q4, LSR %3\n" - - // %1 = (decoded) exponent - // %R4 = upper mantissa and sign - // %Q4 = partially-converted integer - - "2:\n" - // ---- Upper Mantissa ---- - // This is much the same as the lower mantissa, with a few different - // boundary checks and some masking to hide the exponent & sign bit in the - // upper word. - // Note that the upper mantissa is pre-shifted by 20 in %R4, but we shift - // it left more to remove the sign and exponent so it is effectively - // pre-shifted by 31 bits. - " subs %3, %1, #31\n" // Calculate exp-31 - " mov %1, %R4, LSL #11\n" // Re-use %1 as a temporary register. - " bmi 3f\n" - - // Shift %R4 left by exp-31. - // Avoid overflowing the 8-bit shift range, as before. - " bic %2, %3, #0xff\n" - " orr %3, %3, %2, LSR #3\n" - // Perform the shift. - " mov %2, %1, LSL %3\n" - " b 4f\n" - "3:\n" // Shift r1 right by 31-exp. - // We know that 0 <= exp < 31, and we can shift up to 255 bits so - // 31-exp will always be a valid shift and we can skip the range - // check for this case. - " rsb %3, %3, #0\n" // Calculate 31-exp from -(exp-31) - " mov %2, %1, LSR %3\n" // Thumb-2 can't do "LSR %3" in "orr". - - // %Q4 = partially-converted integer (lower) - // %R4 = upper mantissa and sign - // %2 = partially-converted integer (upper) - - "4:\n" - // Combine the converted parts. - " orr %Q4, %Q4, %2\n" - // Negate the result if we have to, and move it to %0 in the process. To - // avoid conditionals, we can do this by inverting on %R4[31], then adding - // %R4[31]>>31. - " eor %Q4, %Q4, %R4, ASR #31\n" - " add %0, %Q4, %R4, LSR #31\n" - " b 9f\n" - "8:\n" - // +/-INFINITY, +/-0, subnormals, NaNs, and anything else out-of-range - // that will result in a conversion of '0'. - " mov %0, #0\n" - "9:\n" - : "=r"(i), "=&r"(tmp0), "=&r"(tmp1), "=&r"(tmp2), "=&r"(d) - : "4"(d) - : "cc"); - return i; -} - -#endif // defined (__arm__) && MOZ_IS_GCC - -namespace detail { - -template > -struct ToSignedOrUnsignedInteger; - -template -struct ToSignedOrUnsignedInteger { - static IntegerType compute(double d) { - return ToUnsignedInteger(d); - } -}; - -template -struct ToSignedOrUnsignedInteger { - static IntegerType compute(double d) { - return ToSignedInteger(d); - } -}; - -} // namespace detail - -template -inline IntegerType ToSignedOrUnsignedInteger(double d) { - return detail::ToSignedOrUnsignedInteger::compute(d); -} - -/* WEBIDL 4.2.4 */ -inline int8_t ToInt8(double d) { return ToSignedInteger(d); } - -/* ECMA-262 7.1.10 ToUInt8() specialized for doubles. */ -inline int8_t ToUint8(double d) { return ToUnsignedInteger(d); } - -/* WEBIDL 4.2.6 */ -inline int16_t ToInt16(double d) { return ToSignedInteger(d); } - -inline uint16_t ToUint16(double d) { return ToUnsignedInteger(d); } - -/* ES5 9.5 ToInt32 (specialized for doubles). */ -inline int32_t ToInt32(double d) { return ToSignedInteger(d); } - -/* ES5 9.6 (specialized for doubles). */ -inline uint32_t ToUint32(double d) { return ToUnsignedInteger(d); } - -/* WEBIDL 4.2.10 */ -inline int64_t ToInt64(double d) { return ToSignedInteger(d); } - -/* WEBIDL 4.2.11 */ -inline uint64_t ToUint64(double d) { return ToUnsignedInteger(d); } - -/** - * An amount of space large enough to store the null-terminated result of - * |ToString| on any Number. - * - * The - * |NumberToString| algorithm is specified in terms of results, not an - * algorithm. It is extremely unclear from the algorithm's definition what its - * longest output can be. |-(2**-19 - 2**-72)| requires 25 + 1 characters and - * is believed to be at least *very close* to the upper bound, so we round that - * *very generously* upward to a 64-bit pointer-size boundary (to be extra - * cautious) and assume that's adequate. - * - * If you can supply better reasoning for a tighter bound, file a bug to improve - * this! - */ -static constexpr size_t MaximumNumberToStringLength = 31 + 1; - -/** - * Store in |out| the null-terminated, base-10 result of |ToString| applied to - * |d| per . - * (This will produce "NaN", "-Infinity", or "Infinity" for non-finite |d|.) - */ -extern JS_PUBLIC_API void NumberToString( - double d, char (&out)[MaximumNumberToStringLength]); - -} // namespace JS - -#endif /* js_Conversions_h */ Index: libraries/source/spidermonkey/include-win32-debug/js/Date.h =================================================================== --- /dev/null +++ libraries/source/spidermonkey/include-win32-debug/js/Date.h @@ -1,209 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* JavaScript date/time computation and creation functions. */ - -#ifndef js_Date_h -#define js_Date_h - -/* - * Dates in JavaScript are defined by IEEE-754 double precision numbers from - * the set: - * - * { t ∈ ℕ : -8.64e15 ≤ t ≤ +8.64e15 } ∪ { NaN } - * - * The single NaN value represents any invalid-date value. All other values - * represent idealized durations in milliseconds since the UTC epoch. (Leap - * seconds are ignored; leap days are not.) +0 is the only zero in this set. - * The limit represented by 8.64e15 milliseconds is 100 million days either - * side of 00:00 January 1, 1970 UTC. - * - * Dates in the above set are represented by the |ClippedTime| class. The - * double type is a superset of the above set, so it *may* (but need not) - * represent a date. Use ECMAScript's |TimeClip| method to produce a date from - * a double. - * - * Date *objects* are simply wrappers around |TimeClip|'d numbers, with a bunch - * of accessor methods to the various aspects of the represented date. - */ - -#include "mozilla/FloatingPoint.h" // mozilla::{IsFinite,IsNaN}, mozilla::UnspecifiedNaN -#include "mozilla/MathAlgorithms.h" // mozilla::Abs - -#include "js/Conversions.h" // JS::ToInteger -#include "js/RootingAPI.h" // JS::Handle -#include "js/Value.h" // JS::CanonicalizeNaN, JS::DoubleValue, JS::Value - -struct JS_PUBLIC_API JSContext; -class JS_PUBLIC_API JSObject; - -namespace JS { - -/** - * Re-query the system to determine the current time zone adjustment from UTC, - * including any component due to DST. If the time zone has changed, this will - * cause all Date object non-UTC methods and formatting functions to produce - * appropriately adjusted results. - * - * Left to its own devices, SpiderMonkey itself may occasionally try to detect - * system time changes. However, no particular frequency of checking is - * guaranteed. Embedders unable to accept occasional inaccuracies should call - * this method in response to system time changes, or immediately before - * operations requiring instantaneous correctness, to guarantee correct - * behavior. - */ -extern JS_PUBLIC_API void ResetTimeZone(); - -class ClippedTime; -inline ClippedTime TimeClip(double time); - -/* - * |ClippedTime| represents the limited subset of dates/times described above. - * - * An invalid date/time may be created through the |ClippedTime::invalid| - * method. Otherwise, a |ClippedTime| may be created using the |TimeClip| - * method. - * - * In typical use, the user might wish to manipulate a timestamp. The user - * performs a series of operations on it, but the final value might not be a - * date as defined above -- it could have overflowed, acquired a fractional - * component, &c. So as a *final* step, the user passes that value through - * |TimeClip| to produce a number restricted to JavaScript's date range. - * - * APIs that accept a JavaScript date value thus accept a |ClippedTime|, not a - * double. This ensures that date/time APIs will only ever receive acceptable - * JavaScript dates. This also forces users to perform any desired clipping, - * as only the user knows what behavior is desired when clipping occurs. - */ -class ClippedTime { - double t = mozilla::UnspecifiedNaN(); - - explicit ClippedTime(double time) : t(time) {} - friend ClippedTime TimeClip(double time); - - public: - // Create an invalid date. - ClippedTime() = default; - - // Create an invalid date/time, more explicitly; prefer this to the default - // constructor. - static ClippedTime invalid() { return ClippedTime(); } - - double toDouble() const { return t; } - - bool isValid() const { return !mozilla::IsNaN(t); } -}; - -// ES6 20.3.1.15. -// -// Clip a double to JavaScript's date range (or to an invalid date) using the -// ECMAScript TimeClip algorithm. -inline ClippedTime TimeClip(double time) { - // Steps 1-2. - const double MaxTimeMagnitude = 8.64e15; - if (!mozilla::IsFinite(time) || mozilla::Abs(time) > MaxTimeMagnitude) { - return ClippedTime(mozilla::UnspecifiedNaN()); - } - - // Step 3. - return ClippedTime(ToInteger(time)); -} - -// Produce a double Value from the given time. Because times may be NaN, -// prefer using this to manual canonicalization. -inline Value TimeValue(ClippedTime time) { - return CanonicalizedDoubleValue(time.toDouble()); -} - -// Create a new Date object whose [[DateValue]] internal slot contains the -// clipped |time|. (Users who must represent times outside that range must use -// another representation.) -extern JS_PUBLIC_API JSObject* NewDateObject(JSContext* cx, ClippedTime time); - -/** - * Create a new Date object for a year/month/day-of-month/hour/minute/second. - * - * The created date is initialized with the time value - * - * TimeClip(UTC(MakeDate(MakeDay(year, mon, mday), - * MakeTime(hour, min, sec, 0.0)))) - * - * where each function/operation is as specified in ECMAScript. - */ -extern JS_PUBLIC_API JSObject* NewDateObject(JSContext* cx, int year, int mon, - int mday, int hour, int min, - int sec); - -/** - * On success, returns true, setting |*isDate| to true if |obj| is a Date - * object or a wrapper around one, or to false if not. Returns false on - * failure. - * - * This method returns true with |*isDate == false| when passed an ES6 proxy - * whose target is a Date, or when passed a revoked proxy. - */ -extern JS_PUBLIC_API bool ObjectIsDate(JSContext* cx, Handle obj, - bool* isDate); - -// Year is a year, month is 0-11, day is 1-based. The return value is a number -// of milliseconds since the epoch. -// -// Consistent with the MakeDate algorithm defined in ECMAScript, this value is -// *not* clipped! Use JS::TimeClip if you need a clipped date. -JS_PUBLIC_API double MakeDate(double year, unsigned month, unsigned day); - -// Year is a year, month is 0-11, day is 1-based, and time is in milliseconds. -// The return value is a number of milliseconds since the epoch. -// -// Consistent with the MakeDate algorithm defined in ECMAScript, this value is -// *not* clipped! Use JS::TimeClip if you need a clipped date. -JS_PUBLIC_API double MakeDate(double year, unsigned month, unsigned day, - double time); - -// Takes an integer number of milliseconds since the epoch and returns the -// year. Can return NaN, and will do so if NaN is passed in. -JS_PUBLIC_API double YearFromTime(double time); - -// Takes an integer number of milliseconds since the epoch and returns the -// month (0-11). Can return NaN, and will do so if NaN is passed in. -JS_PUBLIC_API double MonthFromTime(double time); - -// Takes an integer number of milliseconds since the epoch and returns the -// day (1-based). Can return NaN, and will do so if NaN is passed in. -JS_PUBLIC_API double DayFromTime(double time); - -// Takes an integer year and returns the number of days from epoch to the given -// year. -// NOTE: The calculation performed by this function is literally that given in -// the ECMAScript specification. Nonfinite years, years containing fractional -// components, and years outside ECMAScript's date range are not handled with -// any particular intelligence. Garbage in, garbage out. -JS_PUBLIC_API double DayFromYear(double year); - -// Takes an integer number of milliseconds since the epoch and an integer year, -// returns the number of days in that year. If |time| is nonfinite, returns NaN. -// Otherwise |time| *must* correspond to a time within the valid year |year|. -// This should usually be ensured by computing |year| as -// |JS::DayFromYear(time)|. -JS_PUBLIC_API double DayWithinYear(double time, double year); - -// The callback will be a wrapper function that accepts a single double (the -// time to clamp and jitter.) Inside the JS Engine, other parameters that may be -// needed are all constant, so they are handled inside the wrapper function -using ReduceMicrosecondTimePrecisionCallback = double (*)(double, JSContext*); - -// Set a callback into the toolkit/components/resistfingerprinting function that -// will centralize time resolution and jitter into one place. -JS_PUBLIC_API void SetReduceMicrosecondTimePrecisionCallback( - ReduceMicrosecondTimePrecisionCallback callback); - -// Sets the time resolution for fingerprinting protection, and whether jitter -// should occur. If resolution is set to zero, then no rounding or jitter will -// occur. This is used if the callback above is not specified. -JS_PUBLIC_API void SetTimeResolutionUsec(uint32_t resolution, bool jitter); - -} // namespace JS - -#endif /* js_Date_h */ Index: libraries/source/spidermonkey/include-win32-debug/js/Debug.h =================================================================== --- /dev/null +++ libraries/source/spidermonkey/include-win32-debug/js/Debug.h @@ -1,349 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- - * vim: set ts=8 sts=2 et sw=2 tw=80: - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -// Interfaces by which the embedding can interact with the Debugger API. - -#ifndef js_Debug_h -#define js_Debug_h - -#include "mozilla/Assertions.h" -#include "mozilla/Attributes.h" -#include "mozilla/MemoryReporting.h" - -#include "jsapi.h" -#include "jspubtd.h" - -#include "js/GCAPI.h" -#include "js/RootingAPI.h" -#include "js/TypeDecls.h" - -namespace js { -class Debugger; -} // namespace js - -namespace JS { -namespace dbg { - -// [SMDOC] Debugger builder API -// -// Helping embedding code build objects for Debugger -// ------------------------------------------------- -// -// Some Debugger API features lean on the embedding application to construct -// their result values. For example, Debugger.Frame.prototype.scriptEntryReason -// calls hooks provided by the embedding to construct values explaining why it -// invoked JavaScript; if F is a frame called from a mouse click event handler, -// F.scriptEntryReason would return an object of the form: -// -// { eventType: "mousedown", event: } -// -// where is a Debugger.Object whose referent is the event being -// dispatched. -// -// However, Debugger implements a trust boundary. Debuggee code may be -// considered untrusted; debugger code needs to be protected from debuggee -// getters, setters, proxies, Object.watch watchpoints, and any other feature -// that might accidentally cause debugger code to set the debuggee running. The -// Debugger API tries to make it easy to write safe debugger code by only -// offering access to debuggee objects via Debugger.Object instances, which -// ensure that only those operations whose explicit purpose is to invoke -// debuggee code do so. But this protective membrane is only helpful if we -// interpose Debugger.Object instances in all the necessary spots. -// -// SpiderMonkey's compartment system also implements a trust boundary. The -// debuggee and debugger are always in different compartments. Inter-compartment -// work requires carefully tracking which compartment each JSObject or JS::Value -// belongs to, and ensuring that is is correctly wrapped for each operation. -// -// It seems precarious to expect the embedding's hooks to implement these trust -// boundaries. Instead, the JS::dbg::Builder API segregates the code which -// constructs trusted objects from that which deals with untrusted objects. -// Trusted objects have an entirely different C++ type, so code that improperly -// mixes trusted and untrusted objects is caught at compile time. -// -// In the structure shown above, there are two trusted objects, and one -// untrusted object: -// -// - The overall object, with the 'eventType' and 'event' properties, is a -// trusted object. We're going to return it to D.F.p.scriptEntryReason's -// caller, which will handle it directly. -// -// - The Debugger.Object instance appearing as the value of the 'event' property -// is a trusted object. It belongs to the same Debugger instance as the -// Debugger.Frame instance whose scriptEntryReason accessor was called, and -// presents a safe reflection-oriented API for inspecting its referent, which -// is: -// -// - The actual event object, an untrusted object, and the referent of the -// Debugger.Object above. (Content can do things like replacing accessors on -// Event.prototype.) -// -// Using JS::dbg::Builder, all objects and values the embedding deals with -// directly are considered untrusted, and are assumed to be debuggee values. The -// only way to construct trusted objects is to use Builder's own methods, which -// return a separate Object type. The only way to set a property on a trusted -// object is through that Object type. The actual trusted object is never -// exposed to the embedding. -// -// So, for example, the embedding might use code like the following to construct -// the object shown above, given a Builder passed to it by Debugger: -// -// bool -// MyScriptEntryReason::explain(JSContext* cx, -// Builder& builder, -// Builder::Object& result) -// { -// JSObject* eventObject = ... obtain debuggee event object somehow ...; -// if (!eventObject) { -// return false; -// } -// result = builder.newObject(cx); -// return result && -// result.defineProperty(cx, "eventType", -// SafelyFetchType(eventObject)) && -// result.defineProperty(cx, "event", eventObject); -// } -// -// -// Object::defineProperty also accepts an Object as the value to store on the -// property. By its type, we know that the value is trusted, so we set it -// directly as the property's value, without interposing a Debugger.Object -// wrapper. This allows the embedding to builted nested structures of trusted -// objects. -// -// The Builder and Builder::Object methods take care of doing whatever -// compartment switching and wrapping are necessary to construct the trusted -// values in the Debugger's compartment. -// -// The Object type is self-rooting. Construction, assignment, and destruction -// all properly root the referent object. - -class BuilderOrigin; - -class Builder { - // The Debugger instance whose client we are building a value for. We build - // objects in this object's compartment. - PersistentRootedObject debuggerObject; - - // debuggerObject's Debugger structure, for convenience. - js::Debugger* debugger; - - // Check that |thing| is in the same compartment as our debuggerObject. Used - // for assertions when constructing BuiltThings. We can overload this as we - // add more instantiations of BuiltThing. -#if DEBUG - void assertBuilt(JSObject* obj); -#else - void assertBuilt(JSObject* obj) {} -#endif - - protected: - // A reference to a trusted object or value. At the moment, we only use it - // with JSObject*. - template - class BuiltThing { - friend class BuilderOrigin; - - protected: - // The Builder to which this trusted thing belongs. - Builder& owner; - - // A rooted reference to our value. - PersistentRooted value; - - BuiltThing(JSContext* cx, Builder& owner_, - T value_ = SafelyInitialized()) - : owner(owner_), value(cx, value_) { - owner.assertBuilt(value_); - } - - // Forward some things from our owner, for convenience. - js::Debugger* debugger() const { return owner.debugger; } - JSObject* debuggerObject() const { return owner.debuggerObject; } - - public: - BuiltThing(const BuiltThing& rhs) : owner(rhs.owner), value(rhs.value) {} - BuiltThing& operator=(const BuiltThing& rhs) { - MOZ_ASSERT(&owner == &rhs.owner); - owner.assertBuilt(rhs.value); - value = rhs.value; - return *this; - } - - explicit operator bool() const { - // If we ever instantiate BuiltThing, this might not suffice. - return value; - } - - private: - BuiltThing() = delete; - }; - - public: - // A reference to a trusted object, possibly null. Instances of Object are - // always properly rooted. They can be copied and assigned, as if they were - // pointers. - class Object : private BuiltThing { - friend class Builder; // for construction - friend class BuilderOrigin; // for unwrapping - - typedef BuiltThing Base; - - // This is private, because only Builders can create Objects that - // actually point to something (hence the 'friend' declaration). - Object(JSContext* cx, Builder& owner_, HandleObject obj) - : Base(cx, owner_, obj.get()) {} - - bool definePropertyToTrusted(JSContext* cx, const char* name, - JS::MutableHandleValue value); - - public: - Object(JSContext* cx, Builder& owner_) : Base(cx, owner_, nullptr) {} - Object(const Object& rhs) = default; - - // Our automatically-generated assignment operator can see our base - // class's assignment operator, so we don't need to write one out here. - - // Set the property named |name| on this object to |value|. - // - // If |value| is a string or primitive, re-wrap it for the debugger's - // compartment. - // - // If |value| is an object, assume it is a debuggee object and make a - // Debugger.Object instance referring to it. Set that as the propery's - // value. - // - // If |value| is another trusted object, store it directly as the - // property's value. - // - // On error, report the problem on cx and return false. - bool defineProperty(JSContext* cx, const char* name, JS::HandleValue value); - bool defineProperty(JSContext* cx, const char* name, - JS::HandleObject value); - bool defineProperty(JSContext* cx, const char* name, Object& value); - - using Base::operator bool; - }; - - // Build an empty object for direct use by debugger code, owned by this - // Builder. If an error occurs, report it on cx and return a false Object. - Object newObject(JSContext* cx); - - protected: - Builder(JSContext* cx, js::Debugger* debugger); -}; - -// Debugger itself instantiates this subclass of Builder, which can unwrap -// BuiltThings that belong to it. -class BuilderOrigin : public Builder { - template - T unwrapAny(const BuiltThing& thing) { - MOZ_ASSERT(&thing.owner == this); - return thing.value.get(); - } - - public: - BuilderOrigin(JSContext* cx, js::Debugger* debugger_) - : Builder(cx, debugger_) {} - - JSObject* unwrap(Object& object) { return unwrapAny(object); } -}; - -// Finding the size of blocks allocated with malloc -// ------------------------------------------------ -// -// Debugger.Memory wants to be able to report how many bytes items in memory are -// consuming. To do this, it needs a function that accepts a pointer to a block, -// and returns the number of bytes allocated to that block. SpiderMonkey itself -// doesn't know which function is appropriate to use, but the embedding does. - -// Tell Debuggers in |cx| to use |mallocSizeOf| to find the size of -// malloc'd blocks. -JS_PUBLIC_API void SetDebuggerMallocSizeOf(JSContext* cx, - mozilla::MallocSizeOf mallocSizeOf); - -// Get the MallocSizeOf function that the given context is using to find the -// size of malloc'd blocks. -JS_PUBLIC_API mozilla::MallocSizeOf GetDebuggerMallocSizeOf(JSContext* cx); - -// Debugger and Garbage Collection Events -// -------------------------------------- -// -// The Debugger wants to report about its debuggees' GC cycles, however entering -// JS after a GC is troublesome since SpiderMonkey will often do something like -// force a GC and then rely on the nursery being empty. If we call into some -// Debugger's hook after the GC, then JS runs and the nursery won't be -// empty. Instead, we rely on embedders to call back into SpiderMonkey after a -// GC and notify Debuggers to call their onGarbageCollection hook. - -// Determine whether it's necessary to call FireOnGarbageCollectionHook() after -// a GC. This is only required if there are debuggers with an -// onGarbageCollection hook observing a global in the set of collected zones. -JS_PUBLIC_API bool FireOnGarbageCollectionHookRequired(JSContext* cx); - -// For each Debugger that observed a debuggee involved in the given GC event, -// call its `onGarbageCollection` hook. -JS_PUBLIC_API bool FireOnGarbageCollectionHook( - JSContext* cx, GarbageCollectionEvent::Ptr&& data); - -// Return true if the given value is a Debugger object, false otherwise. -JS_PUBLIC_API bool IsDebugger(JSObject& obj); - -// Append each of the debuggee global objects observed by the Debugger object -// |dbgObj| to |vector|. Returns true on success, false on failure. -JS_PUBLIC_API bool GetDebuggeeGlobals(JSContext* cx, JSObject& dbgObj, - MutableHandleObjectVector vector); - -// Hooks for reporting where JavaScript execution began. -// -// Our performance tools would like to be able to label blocks of JavaScript -// execution with the function name and source location where execution began: -// the event handler, the callback, etc. -// -// Construct an instance of this class on the stack, providing a JSContext -// belonging to the runtime in which execution will occur. Each time we enter -// JavaScript --- specifically, each time we push a JavaScript stack frame that -// has no older JS frames younger than this AutoEntryMonitor --- we will -// call the appropriate |Entry| member function to indicate where we've begun -// execution. - -class MOZ_STACK_CLASS JS_PUBLIC_API AutoEntryMonitor { - JSContext* cx_; - AutoEntryMonitor* savedMonitor_; - - public: - explicit AutoEntryMonitor(JSContext* cx); - ~AutoEntryMonitor(); - - // SpiderMonkey reports the JavaScript entry points occuring within this - // AutoEntryMonitor's scope to the following member functions, which the - // embedding is expected to override. - // - // It is important to note that |asyncCause| is owned by the caller and its - // lifetime must outlive the lifetime of the AutoEntryMonitor object. It is - // strongly encouraged that |asyncCause| be a string constant or similar - // statically allocated string. - - // We have begun executing |function|. Note that |function| may not be the - // actual closure we are running, but only the canonical function object to - // which the script refers. - virtual void Entry(JSContext* cx, JSFunction* function, - HandleValue asyncStack, const char* asyncCause) = 0; - - // Execution has begun at the entry point of |script|, which is not a - // function body. (This is probably being executed by 'eval' or some - // JSAPI equivalent.) - virtual void Entry(JSContext* cx, JSScript* script, HandleValue asyncStack, - const char* asyncCause) = 0; - - // Execution of the function or script has ended. - virtual void Exit(JSContext* cx) {} -}; - -} // namespace dbg -} // namespace JS - -#endif /* js_Debug_h */ Index: libraries/source/spidermonkey/include-win32-debug/js/Equality.h =================================================================== --- /dev/null +++ libraries/source/spidermonkey/include-win32-debug/js/Equality.h @@ -1,66 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* Equality operations. */ - -#ifndef js_Equality_h -#define js_Equality_h - -#include "mozilla/FloatingPoint.h" - -#include "jstypes.h" // JS_PUBLIC_API - -#include "js/RootingAPI.h" // JS::Handle -#include "js/Value.h" // JS::Value - -struct JS_PUBLIC_API JSContext; - -namespace JS { - -/** - * Store |v1 === v2| to |*equal| -- strict equality, which performs no - * conversions on |v1| or |v2| before comparing. - * - * This operation can fail only if an internal error occurs (e.g. OOM while - * linearizing a string value). - */ -extern JS_PUBLIC_API bool StrictlyEqual(JSContext* cx, JS::Handle v1, - JS::Handle v2, bool* equal); - -/** - * Store |v1 == v2| to |*equal| -- loose equality, which may perform - * user-modifiable conversions on |v1| or |v2|. - * - * This operation can fail if a user-modifiable conversion fails *or* if an - * internal error occurs. (e.g. OOM while linearizing a string value). - */ -extern JS_PUBLIC_API bool LooselyEqual(JSContext* cx, JS::Handle v1, - JS::Handle v2, bool* equal); - -/** - * Stores |SameValue(v1, v2)| to |*equal| -- using the SameValue operation - * defined in ECMAScript, initially exposed to script as |Object.is|. SameValue - * behaves identically to strict equality, except that it equates two NaN values - * and does not equate differently-signed zeroes. It performs no conversions on - * |v1| or |v2| before comparing. - * - * This operation can fail only if an internal error occurs (e.g. OOM while - * linearizing a string value). - */ -extern JS_PUBLIC_API bool SameValue(JSContext* cx, JS::Handle v1, - JS::Handle v2, bool* same); - -/** - * Implements |SameValueZero(v1, v2)| for Number values |v1| and |v2|. - * SameValueZero equates NaNs, equal nonzero values, and zeroes without respect - * to their signs. - */ -static inline bool SameValueZero(double v1, double v2) { - return mozilla::EqualOrBothNaN(v1, v2); -} - -} // namespace JS - -#endif /* js_Equality_h */ Index: libraries/source/spidermonkey/include-win32-debug/js/ErrorReport.h =================================================================== --- /dev/null +++ libraries/source/spidermonkey/include-win32-debug/js/ErrorReport.h @@ -1,360 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* - * Error-reporting types and structures. - * - * Despite these types and structures existing in js/public, significant parts - * of their heritage date back to distant SpiderMonkey past, and they are not - * all universally well-thought-out as ideal, intended-to-be-permanent API. - * We may eventually replace this with something more consistent with - * ECMAScript the language and less consistent with '90s-era JSAPI inventions, - * but it's doubtful this will happen any time soon. - */ - -#ifndef js_ErrorReport_h -#define js_ErrorReport_h - -#include "mozilla/Assertions.h" // MOZ_ASSERT - -#include // std::input_iterator_tag, std::iterator -#include // size_t -#include // int16_t, uint16_t -#include // strlen - -#include "jstypes.h" // JS_PUBLIC_API - -#include "js/AllocPolicy.h" // js::SystemAllocPolicy -#include "js/CharacterEncoding.h" // JS::ConstUTF8CharsZ -#include "js/Exception.h" // JS::ExceptionStack -#include "js/RootingAPI.h" // JS::HandleObject, JS::RootedObject -#include "js/UniquePtr.h" // js::UniquePtr -#include "js/Vector.h" // js::Vector - -struct JS_PUBLIC_API JSContext; -class JS_PUBLIC_API JSString; - -/** - * Possible exception types. These types are part of a JSErrorFormatString - * structure. They define which error to throw in case of a runtime error. - * - * JSEXN_WARN is used for warnings in js.msg files (for instance because we - * don't want to prepend 'Error:' to warning messages). This value can go away - * if we ever decide to use an entirely separate mechanism for warnings. - */ -enum JSExnType { - JSEXN_ERR, - JSEXN_FIRST = JSEXN_ERR, - JSEXN_INTERNALERR, - JSEXN_AGGREGATEERR, - JSEXN_EVALERR, - JSEXN_RANGEERR, - JSEXN_REFERENCEERR, - JSEXN_SYNTAXERR, - JSEXN_TYPEERR, - JSEXN_URIERR, - JSEXN_DEBUGGEEWOULDRUN, - JSEXN_WASMCOMPILEERROR, - JSEXN_WASMLINKERROR, - JSEXN_WASMRUNTIMEERROR, - JSEXN_ERROR_LIMIT, - JSEXN_WARN = JSEXN_ERROR_LIMIT, - JSEXN_NOTE, - JSEXN_LIMIT -}; - -struct JSErrorFormatString { - /** The error message name in ASCII. */ - const char* name; - - /** The error format string in ASCII. */ - const char* format; - - /** The number of arguments to expand in the formatted error message. */ - uint16_t argCount; - - /** One of the JSExnType constants above. */ - int16_t exnType; -}; - -using JSErrorCallback = - const JSErrorFormatString* (*)(void* userRef, const unsigned errorNumber); - -/** - * Base class that implements parts shared by JSErrorReport and - * JSErrorNotes::Note. - */ -class JSErrorBase { - private: - // The (default) error message. - // If ownsMessage_ is true, the it is freed in destructor. - JS::ConstUTF8CharsZ message_; - - public: - // Source file name, URL, etc., or null. - const char* filename; - - // Unique identifier for the script source. - unsigned sourceId; - - // Source line number. - unsigned lineno; - - // Zero-based column index in line. - unsigned column; - - // the error number, e.g. see js.msg. - unsigned errorNumber; - - // Points to JSErrorFormatString::name. - // This string must never be freed. - const char* errorMessageName; - - private: - bool ownsMessage_ : 1; - - public: - JSErrorBase() - : filename(nullptr), - sourceId(0), - lineno(0), - column(0), - errorNumber(0), - errorMessageName(nullptr), - ownsMessage_(false) {} - - ~JSErrorBase() { freeMessage(); } - - public: - const JS::ConstUTF8CharsZ message() const { return message_; } - - void initOwnedMessage(const char* messageArg) { - initBorrowedMessage(messageArg); - ownsMessage_ = true; - } - void initBorrowedMessage(const char* messageArg) { - MOZ_ASSERT(!message_); - message_ = JS::ConstUTF8CharsZ(messageArg, strlen(messageArg)); - } - - JSString* newMessageString(JSContext* cx); - - private: - void freeMessage(); -}; - -/** - * Notes associated with JSErrorReport. - */ -class JSErrorNotes { - public: - class Note final : public JSErrorBase {}; - - private: - // Stores pointers to each note. - js::Vector, 1, js::SystemAllocPolicy> notes_; - - public: - JSErrorNotes(); - ~JSErrorNotes(); - - // Add an note to the given position. - bool addNoteASCII(JSContext* cx, const char* filename, unsigned sourceId, - unsigned lineno, unsigned column, - JSErrorCallback errorCallback, void* userRef, - const unsigned errorNumber, ...); - bool addNoteLatin1(JSContext* cx, const char* filename, unsigned sourceId, - unsigned lineno, unsigned column, - JSErrorCallback errorCallback, void* userRef, - const unsigned errorNumber, ...); - bool addNoteUTF8(JSContext* cx, const char* filename, unsigned sourceId, - unsigned lineno, unsigned column, - JSErrorCallback errorCallback, void* userRef, - const unsigned errorNumber, ...); - - JS_PUBLIC_API size_t length(); - - // Create a deep copy of notes. - js::UniquePtr copy(JSContext* cx); - - class iterator final { - private: - js::UniquePtr* note_; - - public: - using iterator_category = std::input_iterator_tag; - using value_type = js::UniquePtr; - using difference_type = ptrdiff_t; - using pointer = value_type*; - using reference = value_type&; - - explicit iterator(js::UniquePtr* note = nullptr) : note_(note) {} - - bool operator==(iterator other) const { return note_ == other.note_; } - bool operator!=(iterator other) const { return !(*this == other); } - iterator& operator++() { - note_++; - return *this; - } - reference operator*() { return *note_; } - }; - - JS_PUBLIC_API iterator begin(); - JS_PUBLIC_API iterator end(); -}; - -/** - * Describes a single error or warning that occurs in the execution of script. - */ -class JSErrorReport : public JSErrorBase { - private: - // Offending source line without final '\n'. - // If ownsLinebuf_ is true, the buffer is freed in destructor. - const char16_t* linebuf_; - - // Number of chars in linebuf_. Does not include trailing '\0'. - size_t linebufLength_; - - // The 0-based offset of error token in linebuf_. - size_t tokenOffset_; - - public: - // Associated notes, or nullptr if there's no note. - js::UniquePtr notes; - - // One of the JSExnType constants. - int16_t exnType; - - // See the comment in TransitiveCompileOptions. - bool isMuted : 1; - - // This error report is actually a warning. - bool isWarning_ : 1; - - private: - bool ownsLinebuf_ : 1; - - public: - JSErrorReport() - : linebuf_(nullptr), - linebufLength_(0), - tokenOffset_(0), - notes(nullptr), - exnType(0), - isMuted(false), - isWarning_(false), - ownsLinebuf_(false) {} - - ~JSErrorReport() { freeLinebuf(); } - - public: - const char16_t* linebuf() const { return linebuf_; } - size_t linebufLength() const { return linebufLength_; } - size_t tokenOffset() const { return tokenOffset_; } - void initOwnedLinebuf(const char16_t* linebufArg, size_t linebufLengthArg, - size_t tokenOffsetArg) { - initBorrowedLinebuf(linebufArg, linebufLengthArg, tokenOffsetArg); - ownsLinebuf_ = true; - } - void initBorrowedLinebuf(const char16_t* linebufArg, size_t linebufLengthArg, - size_t tokenOffsetArg); - - bool isWarning() const { return isWarning_; } - - private: - void freeLinebuf(); -}; - -namespace JS { - -struct MOZ_STACK_CLASS JS_PUBLIC_API ErrorReportBuilder { - explicit ErrorReportBuilder(JSContext* cx); - ~ErrorReportBuilder(); - - enum SniffingBehavior { WithSideEffects, NoSideEffects }; - - /** - * Generate a JSErrorReport from the provided thrown value. - * - * If the value is a (possibly wrapped) Error object, the JSErrorReport will - * be exactly initialized from the Error object's information, without - * observable side effects. (The Error object's JSErrorReport is reused, if - * it has one.) - * - * Otherwise various attempts are made to derive JSErrorReport information - * from |exnStack| and from the current execution state. This process is - * *definitely* inconsistent with any standard, and particulars of the - * behavior implemented here generally shouldn't be relied upon. - * - * If the value of |sniffingBehavior| is |WithSideEffects|, some of these - * attempts *may* invoke user-configurable behavior when the exception is an - * object: converting it to a string, detecting and getting its properties, - * accessing its prototype chain, and others are possible. Users *must* - * tolerate |ErrorReportBuilder::init| potentially having arbitrary effects. - * Any exceptions thrown by these operations will be caught and silently - * ignored, and "default" values will be substituted into the JSErrorReport. - * - * But if the value of |sniffingBehavior| is |NoSideEffects|, these attempts - * *will not* invoke any observable side effects. The JSErrorReport will - * simply contain fewer, less precise details. - * - * Unlike some functions involved in error handling, this function adheres - * to the usual JSAPI return value error behavior. - */ - bool init(JSContext* cx, const JS::ExceptionStack& exnStack, - SniffingBehavior sniffingBehavior); - - JSErrorReport* report() const { return reportp; } - - const JS::ConstUTF8CharsZ toStringResult() const { return toStringResult_; } - - private: - // More or less an equivalent of JS_ReportErrorNumber/js::ReportErrorNumberVA - // but fills in an ErrorReport instead of reporting it. Uses varargs to - // make it simpler to call js::ExpandErrorArgumentsVA. - // - // Returns false if we fail to actually populate the ErrorReport - // for some reason (probably out of memory). - bool populateUncaughtExceptionReportUTF8(JSContext* cx, - JS::HandleObject stack, ...); - bool populateUncaughtExceptionReportUTF8VA(JSContext* cx, - JS::HandleObject stack, - va_list ap); - - // Reports exceptions from add-on scopes to telemetry. - void ReportAddonExceptionToTelemetry(JSContext* cx); - - // We may have a provided JSErrorReport, so need a way to represent that. - JSErrorReport* reportp; - - // Or we may need to synthesize a JSErrorReport one of our own. - JSErrorReport ownedReport; - - // Root our exception value to keep a possibly borrowed |reportp| alive. - JS::RootedObject exnObject; - - // And for our filename. - JS::UniqueChars filename; - - // We may have a result of error.toString(). - // FIXME: We should not call error.toString(), since it could have side - // effect (see bug 633623). - JS::ConstUTF8CharsZ toStringResult_; - JS::UniqueChars toStringResultBytesStorage; -}; - -// Writes a full report to a file descriptor. Does nothing for JSErrorReports -// which are warnings, unless reportWarnings is set. -extern JS_PUBLIC_API void PrintError(JSContext* cx, FILE* file, - JSErrorReport* report, - bool reportWarnings); - -extern JS_PUBLIC_API void PrintError(JSContext* cx, FILE* file, - const JS::ErrorReportBuilder& builder, - bool reportWarnings); - -} // namespace JS - -#endif /* js_ErrorReport_h */ Index: libraries/source/spidermonkey/include-win32-debug/js/Exception.h =================================================================== --- /dev/null +++ libraries/source/spidermonkey/include-win32-debug/js/Exception.h @@ -1,69 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- - * vim: set ts=8 sts=2 et sw=2 tw=80: - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef js_Exception_h -#define js_Exception_h - -#include "mozilla/Attributes.h" - -#include "jspubtd.h" -#include "js/RootingAPI.h" // JS::{Handle,Rooted} -#include "js/Value.h" // JS::Value, JS::Handle - -namespace JS { - -// This class encapsulates a (pending) exception and the corresponding optional -// SavedFrame stack object captured when the pending exception was set -// on the JSContext. This fuzzily correlates with a `throw` statement in JS, -// although arbitrary JSAPI consumers or VM code may also set pending exceptions -// via `JS_SetPendingException`. -// -// This is not the same stack as `e.stack` when `e` is an `Error` object. -// (That would be JS::ExceptionStackOrNull). -class MOZ_STACK_CLASS ExceptionStack { - Rooted exception_; - Rooted stack_; - - friend JS_PUBLIC_API bool GetPendingExceptionStack( - JSContext* cx, JS::ExceptionStack* exceptionStack); - - void init(HandleValue exception, HandleObject stack) { - exception_ = exception; - stack_ = stack; - } - - public: - explicit ExceptionStack(JSContext* cx) : exception_(cx), stack_(cx) {} - - ExceptionStack(JSContext* cx, HandleValue exception, HandleObject stack) - : exception_(cx, exception), stack_(cx, stack) {} - - HandleValue exception() const { return exception_; } - - // |stack| can be null. - HandleObject stack() const { return stack_; } -}; - -// Get the current pending exception value and stack. -// This function asserts that there is a pending exception. -// If this function returns false, then retrieving the current pending exception -// failed and might have been overwritten by a new exception. -extern JS_PUBLIC_API bool GetPendingExceptionStack( - JSContext* cx, JS::ExceptionStack* exceptionStack); - -// Similar to GetPendingExceptionStack, but also clears the current -// pending exception. -extern JS_PUBLIC_API bool StealPendingExceptionStack( - JSContext* cx, JS::ExceptionStack* exceptionStack); - -// Set both the exception value and its associated stack on the context as -// the current pending exception. -extern JS_PUBLIC_API void SetPendingExceptionStack( - JSContext* cx, const JS::ExceptionStack& exceptionStack); - -} // namespace JS - -#endif // js_Exception_h Index: libraries/source/spidermonkey/include-win32-debug/js/ForOfIterator.h =================================================================== --- /dev/null +++ libraries/source/spidermonkey/include-win32-debug/js/ForOfIterator.h @@ -1,118 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- - * vim: set ts=8 sts=2 et sw=2 tw=80: - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* - * A convenience class that makes it easy to perform the operations of a for-of - * loop. - */ - -#ifndef js_ForOfIterator_h -#define js_ForOfIterator_h - -#include "mozilla/Attributes.h" // MOZ_MUST_USE, MOZ_STACK_CLASS - -#include // UINT32_MAX, uint32_t - -#include "jstypes.h" // JS_PUBLIC_API - -#include "js/RootingAPI.h" // JS::{Handle,Rooted} -#include "js/Value.h" // JS::Value, JS::{,Mutable}Handle - -struct JS_PUBLIC_API JSContext; -class JS_PUBLIC_API JSObject; - -namespace JS { - -/** - * A convenience class for imitating a JS for-of loop. Typical usage: - * - * JS::ForOfIterator it(cx); - * if (!it.init(iterable)) { - * return false; - * } - * JS::Rooted val(cx); - * while (true) { - * bool done; - * if (!it.next(&val, &done)) { - * return false; - * } - * if (done) { - * break; - * } - * if (!DoStuff(cx, val)) { - * return false; - * } - * } - */ -class MOZ_STACK_CLASS JS_PUBLIC_API ForOfIterator { - protected: - JSContext* cx_; - - // Use the ForOfPIC on the global object (see vm/GlobalObject.h) to try to - // optimize iteration across arrays. - // - // Case 1: Regular Iteration - // iterator - pointer to the iterator object. - // nextMethod - value of |iterator|.next. - // index - fixed to NOT_ARRAY (== UINT32_MAX) - // - // Case 2: Optimized Array Iteration - // iterator - pointer to the array object. - // nextMethod - the undefined value. - // index - current position in array. - // - // The cases are distinguished by whether |index == NOT_ARRAY|. - Rooted iterator; - Rooted nextMethod; - - static constexpr uint32_t NOT_ARRAY = UINT32_MAX; - - uint32_t index = NOT_ARRAY; - - ForOfIterator(const ForOfIterator&) = delete; - ForOfIterator& operator=(const ForOfIterator&) = delete; - - public: - explicit ForOfIterator(JSContext* cx) - : cx_(cx), iterator(cx), nextMethod(cx) {} - - enum NonIterableBehavior { ThrowOnNonIterable, AllowNonIterable }; - - /** - * Initialize the iterator. If AllowNonIterable is passed then if getting - * the @@iterator property from iterable returns undefined init() will just - * return true instead of throwing. Callers must then check - * valueIsIterable() before continuing with the iteration. - */ - MOZ_MUST_USE bool init( - Handle iterable, - NonIterableBehavior nonIterableBehavior = ThrowOnNonIterable); - - /** - * Get the next value from the iterator. If false *done is true - * after this call, do not examine val. - */ - MOZ_MUST_USE bool next(MutableHandle val, bool* done); - - /** - * Close the iterator. - * For the case that completion type is throw. - */ - void closeThrow(); - - /** - * If initialized with throwOnNonCallable = false, check whether - * the value is iterable. - */ - bool valueIsIterable() const { return iterator; } - - private: - inline bool nextFromOptimizedArray(MutableHandle val, bool* done); -}; - -} // namespace JS - -#endif // js_ForOfIterator_h Index: libraries/source/spidermonkey/include-win32-debug/js/GCAPI.h =================================================================== --- /dev/null +++ libraries/source/spidermonkey/include-win32-debug/js/GCAPI.h @@ -1,1145 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- - * vim: set ts=8 sts=2 et sw=2 tw=80: - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* - * High-level interface to the JS garbage collector. - */ - -#ifndef js_GCAPI_h -#define js_GCAPI_h - -#include "mozilla/TimeStamp.h" -#include "mozilla/Vector.h" - -#include "js/GCAnnotations.h" -#include "js/TypeDecls.h" -#include "js/UniquePtr.h" -#include "js/Utility.h" - -class JS_PUBLIC_API JSTracer; - -namespace js { -namespace gc { -class GCRuntime; -} // namespace gc -namespace gcstats { -struct Statistics; -} // namespace gcstats -} // namespace js - -typedef enum JSGCMode { - /** Perform only global GCs. */ - JSGC_MODE_GLOBAL = 0, - - /** Perform per-zone GCs until too much garbage has accumulated. */ - JSGC_MODE_ZONE = 1, - - /** Collect in short time slices rather than all at once. */ - JSGC_MODE_INCREMENTAL = 2, - - /** Both of the above. */ - JSGC_MODE_ZONE_INCREMENTAL = 3, -} JSGCMode; - -/** - * Kinds of js_GC invocation. - */ -typedef enum JSGCInvocationKind { - /* Normal invocation. */ - GC_NORMAL = 0, - - /* Minimize GC triggers and release empty GC chunks right away. */ - GC_SHRINK = 1 -} JSGCInvocationKind; - -typedef enum JSGCParamKey { - /** - * Maximum nominal heap before last ditch GC. - * - * Soft limit on the number of bytes we are allowed to allocate in the GC - * heap. Attempts to allocate gcthings over this limit will return null and - * subsequently invoke the standard OOM machinery, independent of available - * physical memory. - * - * Pref: javascript.options.mem.max - * Default: 0xffffffff - */ - JSGC_MAX_BYTES = 0, - - /** - * Maximum size of the generational GC nurseries. - * - * This will be rounded to the nearest gc::ChunkSize. - * - * Pref: javascript.options.mem.nursery.max_kb - * Default: JS::DefaultNurseryMaxBytes - */ - JSGC_MAX_NURSERY_BYTES = 2, - - /** Amount of bytes allocated by the GC. */ - JSGC_BYTES = 3, - - /** Number of times GC has been invoked. Includes both major and minor GC. */ - JSGC_NUMBER = 4, - - /** - * Select GC mode. - * - * See: JSGCMode in GCAPI.h - * prefs: javascript.options.mem.gc_per_zone and - * javascript.options.mem.gc_incremental. - * Default: JSGC_MODE_ZONE_INCREMENTAL - */ - JSGC_MODE = 6, - - /** Number of cached empty GC chunks. */ - JSGC_UNUSED_CHUNKS = 7, - - /** Total number of allocated GC chunks. */ - JSGC_TOTAL_CHUNKS = 8, - - /** - * Max milliseconds to spend in an incremental GC slice. - * - * Pref: javascript.options.mem.gc_incremental_slice_ms - * Default: DefaultTimeBudgetMS. - */ - JSGC_SLICE_TIME_BUDGET_MS = 9, - - /** - * Maximum size the GC mark stack can grow to. - * - * Pref: none - * Default: MarkStack::DefaultCapacity - */ - JSGC_MARK_STACK_LIMIT = 10, - - /** - * The "do we collect?" decision depends on various parameters and can be - * summarised as: - * - * ZoneSize > Max(ThresholdBase, LastSize) * GrowthFactor * ThresholdFactor - * - * Where - * ZoneSize: Current size of this zone. - * LastSize: Heap size immediately after the most recent collection. - * ThresholdBase: The JSGC_ALLOCATION_THRESHOLD parameter - * GrowthFactor: A number above 1, calculated based on some of the - * following parameters. - * See computeZoneHeapGrowthFactorForHeapSize() in GC.cpp - * ThresholdFactor: 1.0 to trigger an incremental collections or between - * JSGC_SMALL_HEAP_INCREMENTAL_LIMIT and - * JSGC_LARGE_HEAP_INCREMENTAL_LIMIT to trigger a - * non-incremental collection. - * - * The RHS of the equation above is calculated and sets - * zone->gcHeapThreshold.bytes(). When gcHeapSize.bytes() exeeds - * gcHeapThreshold.bytes() for a zone, the zone may be scheduled for a GC. - */ - - /** - * GCs less than this far apart in milliseconds will be considered - * 'high-frequency GCs'. - * - * Pref: javascript.options.mem.gc_high_frequency_time_limit_ms - * Default: HighFrequencyThreshold - */ - JSGC_HIGH_FREQUENCY_TIME_LIMIT = 11, - - /** - * Upper limit for classifying a heap as small (MB). - * - * Dynamic heap growth thresholds are based on whether the heap is small, - * medium or large. Heaps smaller than this size are classified as small; - * larger heaps are classified as medium or large. - * - * Pref: javascript.options.mem.gc_small_heap_size_max_mb - * Default: SmallHeapSizeMaxBytes - */ - JSGC_SMALL_HEAP_SIZE_MAX = 12, - - /** - * Lower limit for classifying a heap as large (MB). - * - * Dynamic heap growth thresholds are based on whether the heap is small, - * medium or large. Heaps larger than this size are classified as large; - * smaller heaps are classified as small or medium. - * - * Pref: javascript.options.mem.gc_large_heap_size_min_mb - * Default: LargeHeapSizeMinBytes - */ - JSGC_LARGE_HEAP_SIZE_MIN = 13, - - /** - * Heap growth factor for small heaps in the high-frequency GC state. - * - * Pref: javascript.options.mem.gc_high_frequency_small_heap_growth - * Default: HighFrequencySmallHeapGrowth - */ - JSGC_HIGH_FREQUENCY_SMALL_HEAP_GROWTH = 14, - - /** - * Heap growth factor for large heaps in the high-frequency GC state. - * - * Pref: javascript.options.mem.gc_high_frequency_large_heap_growth - * Default: HighFrequencyLargeHeapGrowth - */ - JSGC_HIGH_FREQUENCY_LARGE_HEAP_GROWTH = 15, - - /** - * Heap growth factor for low frequency GCs. - * - * This factor is applied regardless of the size of the heap when not in the - * high-frequency GC state. - * - * Pref: javascript.options.mem.gc_low_frequency_heap_growth - * Default: LowFrequencyHeapGrowth - */ - JSGC_LOW_FREQUENCY_HEAP_GROWTH = 16, - - /** - * Lower limit for collecting a zone. - * - * Zones smaller than this size will not normally be collected. - * - * Pref: javascript.options.mem.gc_allocation_threshold_mb - * Default GCZoneAllocThresholdBase - */ - JSGC_ALLOCATION_THRESHOLD = 19, - - /** - * We try to keep at least this many unused chunks in the free chunk pool at - * all times, even after a shrinking GC. - * - * Pref: javascript.options.mem.gc_min_empty_chunk_count - * Default: MinEmptyChunkCount - */ - JSGC_MIN_EMPTY_CHUNK_COUNT = 21, - - /** - * We never keep more than this many unused chunks in the free chunk - * pool. - * - * Pref: javascript.options.mem.gc_min_empty_chunk_count - * Default: MinEmptyChunkCount - */ - JSGC_MAX_EMPTY_CHUNK_COUNT = 22, - - /** - * Whether compacting GC is enabled. - * - * Pref: javascript.options.mem.gc_compacting - * Default: CompactingEnabled - */ - JSGC_COMPACTING_ENABLED = 23, - - /** - * Limit of how far over the incremental trigger threshold we allow the heap - * to grow before finishing a collection non-incrementally, for small heaps. - * - * We trigger an incremental GC when a trigger threshold is reached but the - * collection may not be fast enough to keep up with the mutator. At some - * point we finish the collection non-incrementally. - * - * Default: SmallHeapIncrementalLimit - * Pref: javascript.options.mem.gc_small_heap_incremental_limit - */ - JSGC_SMALL_HEAP_INCREMENTAL_LIMIT = 25, - - /** - * Limit of how far over the incremental trigger threshold we allow the heap - * to grow before finishing a collection non-incrementally, for large heaps. - * - * Default: LargeHeapIncrementalLimit - * Pref: javascript.options.mem.gc_large_heap_incremental_limit - */ - JSGC_LARGE_HEAP_INCREMENTAL_LIMIT = 26, - - /** - * Attempt to run a minor GC in the idle time if the free space falls - * below this number of bytes. - * - * Default: NurseryChunkUsableSize / 4 - * Pref: None - */ - JSGC_NURSERY_FREE_THRESHOLD_FOR_IDLE_COLLECTION = 27, - - /** - * If this percentage of the nursery is tenured and the nursery is at least - * 4MB, then proceed to examine which groups we should pretenure. - * - * Default: PretenureThreshold - * Pref: None - */ - JSGC_PRETENURE_THRESHOLD = 28, - - /** - * If the above condition is met, then any object group that tenures more than - * this number of objects will be pretenured (if it can be). - * - * Default: PretenureGroupThreshold - * Pref: None - */ - JSGC_PRETENURE_GROUP_THRESHOLD = 29, - - /** - * Attempt to run a minor GC in the idle time if the free space falls - * below this percentage (from 0 to 99). - * - * Default: 25 - * Pref: None - */ - JSGC_NURSERY_FREE_THRESHOLD_FOR_IDLE_COLLECTION_PERCENT = 30, - - /** - * Minimum size of the generational GC nurseries. - * - * This value will be rounded to the nearest Nursery::SubChunkStep if below - * gc::ChunkSize, otherwise it'll be rounded to the nearest gc::ChunkSize. - * - * Default: Nursery::SubChunkLimit - * Pref: javascript.options.mem.nursery.min_kb - */ - JSGC_MIN_NURSERY_BYTES = 31, - - /** - * The minimum time to allow between triggering last ditch GCs in seconds. - * - * Default: 60 seconds - * Pref: None - */ - JSGC_MIN_LAST_DITCH_GC_PERIOD = 32, - - /** - * The delay (in heapsize kilobytes) between slices of an incremental GC. - * - * Default: ZoneAllocDelayBytes - */ - JSGC_ZONE_ALLOC_DELAY_KB = 33, - - /* - * The current size of the nursery. - * - * read-only. - */ - JSGC_NURSERY_BYTES = 34, - - /** - * Retained size base value for calculating malloc heap threshold. - * - * Default: MallocThresholdBase - */ - JSGC_MALLOC_THRESHOLD_BASE = 35, - - /** - * Growth factor for calculating malloc heap threshold. - * - * Default: MallocGrowthFactor - */ - JSGC_MALLOC_GROWTH_FACTOR = 36, - - /** - * Whether incremental weakmap marking is enabled. - * - * Pref: javascript.options.mem.incremental_weakmap - * Default: IncrementalWeakMarkEnabled - */ - JSGC_INCREMENTAL_WEAKMAP_ENABLED = 37, -} JSGCParamKey; - -/* - * Generic trace operation that calls JS::TraceEdge on each traceable thing's - * location reachable from data. - */ -typedef void (*JSTraceDataOp)(JSTracer* trc, void* data); - -typedef enum JSGCStatus { JSGC_BEGIN, JSGC_END } JSGCStatus; - -typedef void (*JSObjectsTenuredCallback)(JSContext* cx, void* data); - -typedef enum JSFinalizeStatus { - /** - * Called when preparing to sweep a group of zones, before anything has been - * swept. The collector will not yield to the mutator before calling the - * callback with JSFINALIZE_GROUP_START status. - */ - JSFINALIZE_GROUP_PREPARE, - - /** - * Called after preparing to sweep a group of zones. Weak references to - * unmarked things have been removed at this point, but no GC things have - * been swept. The collector may yield to the mutator after this point. - */ - JSFINALIZE_GROUP_START, - - /** - * Called after sweeping a group of zones. All dead GC things have been - * swept at this point. - */ - JSFINALIZE_GROUP_END, - - /** - * Called at the end of collection when everything has been swept. - */ - JSFINALIZE_COLLECTION_END -} JSFinalizeStatus; - -typedef void (*JSFinalizeCallback)(JSFreeOp* fop, JSFinalizeStatus status, - void* data); - -typedef void (*JSWeakPointerZonesCallback)(JSContext* cx, void* data); - -typedef void (*JSWeakPointerCompartmentCallback)(JSContext* cx, - JS::Compartment* comp, - void* data); - -/* - * This is called to tell the embedding that the FinalizationRegistry object - * |registry| has cleanup work, and that then engine should be called back at an - * appropriate later time to perform this cleanup. - * - * This callback must not do anything that could cause GC. - */ -using JSHostCleanupFinalizationRegistryCallback = void (*)(JSObject* registry, - void* data); - -/** - * Each external string has a pointer to JSExternalStringCallbacks. Embedders - * can use this to implement custom finalization or memory reporting behavior. - */ -struct JSExternalStringCallbacks { - /** - * Finalizes external strings created by JS_NewExternalString. The finalizer - * can be called off the main thread. - */ - virtual void finalize(char16_t* chars) const = 0; - - /** - * Callback used by memory reporting to ask the embedder how much memory an - * external string is keeping alive. The embedder is expected to return a - * value that corresponds to the size of the allocation that will be released - * by the finalizer callback above. - * - * Implementations of this callback MUST NOT do anything that can cause GC. - */ - virtual size_t sizeOfBuffer(const char16_t* chars, - mozilla::MallocSizeOf mallocSizeOf) const = 0; -}; - -namespace JS { - -#define GCREASONS(D) \ - /* Reasons internal to the JS engine */ \ - D(API, 0) \ - D(EAGER_ALLOC_TRIGGER, 1) \ - D(DESTROY_RUNTIME, 2) \ - D(ROOTS_REMOVED, 3) \ - D(LAST_DITCH, 4) \ - D(TOO_MUCH_MALLOC, 5) \ - D(ALLOC_TRIGGER, 6) \ - D(DEBUG_GC, 7) \ - D(COMPARTMENT_REVIVED, 8) \ - D(RESET, 9) \ - D(OUT_OF_NURSERY, 10) \ - D(EVICT_NURSERY, 11) \ - D(DELAYED_ATOMS_GC, 12) \ - D(SHARED_MEMORY_LIMIT, 13) \ - D(IDLE_TIME_COLLECTION, 14) \ - D(BG_TASK_FINISHED, 15) \ - D(ABORT_GC, 16) \ - D(FULL_WHOLE_CELL_BUFFER, 17) \ - D(FULL_GENERIC_BUFFER, 18) \ - D(FULL_VALUE_BUFFER, 19) \ - D(FULL_CELL_PTR_OBJ_BUFFER, 20) \ - D(FULL_SLOT_BUFFER, 21) \ - D(FULL_SHAPE_BUFFER, 22) \ - D(TOO_MUCH_WASM_MEMORY, 23) \ - D(DISABLE_GENERATIONAL_GC, 24) \ - D(FINISH_GC, 25) \ - D(PREPARE_FOR_TRACING, 26) \ - D(INCREMENTAL_ALLOC_TRIGGER, 27) \ - D(FULL_CELL_PTR_STR_BUFFER, 28) \ - D(TOO_MUCH_JIT_CODE, 29) \ - D(FULL_CELL_PTR_BIGINT_BUFFER, 30) \ - D(INIT_SELF_HOSTING, 31) \ - D(NURSERY_MALLOC_BUFFERS, 32) \ - \ - /* Reasons from Firefox */ \ - D(DOM_WINDOW_UTILS, FIRST_FIREFOX_REASON) \ - D(COMPONENT_UTILS, 34) \ - D(MEM_PRESSURE, 35) \ - D(CC_WAITING, 36) \ - D(CC_FORCED, 37) \ - D(LOAD_END, 38) \ - D(UNUSED3, 39) \ - D(PAGE_HIDE, 40) \ - D(NSJSCONTEXT_DESTROY, 41) \ - D(WORKER_SHUTDOWN, 42) \ - D(SET_DOC_SHELL, 43) \ - D(DOM_UTILS, 44) \ - D(DOM_IPC, 45) \ - D(DOM_WORKER, 46) \ - D(INTER_SLICE_GC, 47) \ - D(UNUSED1, 48) \ - D(FULL_GC_TIMER, 49) \ - D(SHUTDOWN_CC, 50) \ - D(UNUSED2, 51) \ - D(USER_INACTIVE, 52) \ - D(XPCONNECT_SHUTDOWN, 53) \ - D(DOCSHELL, 54) \ - D(HTML_PARSER, 55) - -enum class GCReason { - FIRST_FIREFOX_REASON = 33, - -#define MAKE_REASON(name, val) name = val, - GCREASONS(MAKE_REASON) -#undef MAKE_REASON - NO_REASON, - NUM_REASONS, - - /* - * For telemetry, we want to keep a fixed max bucket size over time so we - * don't have to switch histograms. 100 is conservative; but the cost of extra - * buckets seems to be low while the cost of switching histograms is high. - */ - NUM_TELEMETRY_REASONS = 100 -}; - -/** - * Get a statically allocated C string explaining the given GC reason. - */ -extern JS_PUBLIC_API const char* ExplainGCReason(JS::GCReason reason); - -/** - * Return true if the GC reason is internal to the JS engine. - */ -extern JS_PUBLIC_API bool InternalGCReason(JS::GCReason reason); - -/* - * Zone GC: - * - * SpiderMonkey's GC is capable of performing a collection on an arbitrary - * subset of the zones in the system. This allows an embedding to minimize - * collection time by only collecting zones that have run code recently, - * ignoring the parts of the heap that are unlikely to have changed. - * - * When triggering a GC using one of the functions below, it is first necessary - * to select the zones to be collected. To do this, you can call - * PrepareZoneForGC on each zone, or you can call PrepareForFullGC to select - * all zones. Failing to select any zone is an error. - */ - -/** - * Schedule the given zone to be collected as part of the next GC. - */ -extern JS_PUBLIC_API void PrepareZoneForGC(Zone* zone); - -/** - * Schedule all zones to be collected in the next GC. - */ -extern JS_PUBLIC_API void PrepareForFullGC(JSContext* cx); - -/** - * When performing an incremental GC, the zones that were selected for the - * previous incremental slice must be selected in subsequent slices as well. - * This function selects those slices automatically. - */ -extern JS_PUBLIC_API void PrepareForIncrementalGC(JSContext* cx); - -/** - * Returns true if any zone in the system has been scheduled for GC with one of - * the functions above or by the JS engine. - */ -extern JS_PUBLIC_API bool IsGCScheduled(JSContext* cx); - -/** - * Undoes the effect of the Prepare methods above. The given zone will not be - * collected in the next GC. - */ -extern JS_PUBLIC_API void SkipZoneForGC(Zone* zone); - -/* - * Non-Incremental GC: - * - * The following functions perform a non-incremental GC. - */ - -/** - * Performs a non-incremental collection of all selected zones. - * - * If the gckind argument is GC_NORMAL, then some objects that are unreachable - * from the program may still be alive afterwards because of internal - * references; if GC_SHRINK is passed then caches and other temporary references - * to objects will be cleared and all unreferenced objects will be removed from - * the system. - */ -extern JS_PUBLIC_API void NonIncrementalGC(JSContext* cx, - JSGCInvocationKind gckind, - GCReason reason); - -/* - * Incremental GC: - * - * Incremental GC divides the full mark-and-sweep collection into multiple - * slices, allowing client JavaScript code to run between each slice. This - * allows interactive apps to avoid long collection pauses. Incremental GC does - * not make collection take less time, it merely spreads that time out so that - * the pauses are less noticable. - * - * For a collection to be carried out incrementally the following conditions - * must be met: - * - The collection must be run by calling JS::IncrementalGC() rather than - * JS_GC(). - * - The GC mode must have been set to JSGC_MODE_INCREMENTAL or - * JSGC_MODE_ZONE_INCREMENTAL with JS_SetGCParameter(). - * - * Note: Even if incremental GC is enabled and working correctly, - * non-incremental collections can still happen when low on memory. - */ - -/** - * Begin an incremental collection and perform one slice worth of work. When - * this function returns, the collection may not be complete. - * IncrementalGCSlice() must be called repeatedly until - * !IsIncrementalGCInProgress(cx). - * - * Note: SpiderMonkey's GC is not realtime. Slices in practice may be longer or - * shorter than the requested interval. - */ -extern JS_PUBLIC_API void StartIncrementalGC(JSContext* cx, - JSGCInvocationKind gckind, - GCReason reason, - int64_t millis = 0); - -/** - * Perform a slice of an ongoing incremental collection. When this function - * returns, the collection may not be complete. It must be called repeatedly - * until !IsIncrementalGCInProgress(cx). - * - * Note: SpiderMonkey's GC is not realtime. Slices in practice may be longer or - * shorter than the requested interval. - */ -extern JS_PUBLIC_API void IncrementalGCSlice(JSContext* cx, GCReason reason, - int64_t millis = 0); - -/** - * Return whether an incremental GC has work to do on the foreground thread and - * would make progress if a slice was run now. If this returns false then the GC - * is waiting for background threads to finish their work and a slice started - * now would return immediately. - */ -extern JS_PUBLIC_API bool IncrementalGCHasForegroundWork(JSContext* cx); - -/** - * If IsIncrementalGCInProgress(cx), this call finishes the ongoing collection - * by performing an arbitrarily long slice. If !IsIncrementalGCInProgress(cx), - * this is equivalent to NonIncrementalGC. When this function returns, - * IsIncrementalGCInProgress(cx) will always be false. - */ -extern JS_PUBLIC_API void FinishIncrementalGC(JSContext* cx, GCReason reason); - -/** - * If IsIncrementalGCInProgress(cx), this call aborts the ongoing collection and - * performs whatever work needs to be done to return the collector to its idle - * state. This may take an arbitrarily long time. When this function returns, - * IsIncrementalGCInProgress(cx) will always be false. - */ -extern JS_PUBLIC_API void AbortIncrementalGC(JSContext* cx); - -namespace dbg { - -// The `JS::dbg::GarbageCollectionEvent` class is essentially a view of the -// `js::gcstats::Statistics` data without the uber implementation-specific bits. -// It should generally be palatable for web developers. -class GarbageCollectionEvent { - // The major GC number of the GC cycle this data pertains to. - uint64_t majorGCNumber_; - - // Reference to a non-owned, statically allocated C string. This is a very - // short reason explaining why a GC was triggered. - const char* reason; - - // Reference to a nullable, non-owned, statically allocated C string. If the - // collection was forced to be non-incremental, this is a short reason of - // why the GC could not perform an incremental collection. - const char* nonincrementalReason; - - // Represents a single slice of a possibly multi-slice incremental garbage - // collection. - struct Collection { - mozilla::TimeStamp startTimestamp; - mozilla::TimeStamp endTimestamp; - }; - - // The set of garbage collection slices that made up this GC cycle. - mozilla::Vector collections; - - GarbageCollectionEvent(const GarbageCollectionEvent& rhs) = delete; - GarbageCollectionEvent& operator=(const GarbageCollectionEvent& rhs) = delete; - - public: - explicit GarbageCollectionEvent(uint64_t majorGCNum) - : majorGCNumber_(majorGCNum), - reason(nullptr), - nonincrementalReason(nullptr), - collections() {} - - using Ptr = js::UniquePtr; - static Ptr Create(JSRuntime* rt, ::js::gcstats::Statistics& stats, - uint64_t majorGCNumber); - - JSObject* toJSObject(JSContext* cx) const; - - uint64_t majorGCNumber() const { return majorGCNumber_; } -}; - -} // namespace dbg - -enum GCProgress { - /* - * During GC, the GC is bracketed by GC_CYCLE_BEGIN/END callbacks. Each - * slice between those (whether an incremental or the sole non-incremental - * slice) is bracketed by GC_SLICE_BEGIN/GC_SLICE_END. - */ - - GC_CYCLE_BEGIN, - GC_SLICE_BEGIN, - GC_SLICE_END, - GC_CYCLE_END -}; - -struct JS_PUBLIC_API GCDescription { - bool isZone_; - bool isComplete_; - JSGCInvocationKind invocationKind_; - GCReason reason_; - - GCDescription(bool isZone, bool isComplete, JSGCInvocationKind kind, - GCReason reason) - : isZone_(isZone), - isComplete_(isComplete), - invocationKind_(kind), - reason_(reason) {} - - char16_t* formatSliceMessage(JSContext* cx) const; - char16_t* formatSummaryMessage(JSContext* cx) const; - - mozilla::TimeStamp startTime(JSContext* cx) const; - mozilla::TimeStamp endTime(JSContext* cx) const; - mozilla::TimeStamp lastSliceStart(JSContext* cx) const; - mozilla::TimeStamp lastSliceEnd(JSContext* cx) const; - - char16_t* formatJSONTelemetry(JSContext* cx, uint64_t timestamp) const; - - JS::UniqueChars sliceToJSONProfiler(JSContext* cx) const; - JS::UniqueChars formatJSONProfiler(JSContext* cx) const; - - JS::dbg::GarbageCollectionEvent::Ptr toGCEvent(JSContext* cx) const; -}; - -extern JS_PUBLIC_API UniqueChars MinorGcToJSON(JSContext* cx); - -typedef void (*GCSliceCallback)(JSContext* cx, GCProgress progress, - const GCDescription& desc); - -/** - * The GC slice callback is called at the beginning and end of each slice. This - * callback may be used for GC notifications as well as to perform additional - * marking. - */ -extern JS_PUBLIC_API GCSliceCallback -SetGCSliceCallback(JSContext* cx, GCSliceCallback callback); - -/** - * Describes the progress of an observed nursery collection. - */ -enum class GCNurseryProgress { - /** - * The nursery collection is starting. - */ - GC_NURSERY_COLLECTION_START, - /** - * The nursery collection is ending. - */ - GC_NURSERY_COLLECTION_END -}; - -/** - * A nursery collection callback receives the progress of the nursery collection - * and the reason for the collection. - */ -using GCNurseryCollectionCallback = void (*)(JSContext* cx, - GCNurseryProgress progress, - GCReason reason); - -/** - * Set the nursery collection callback for the given runtime. When set, it will - * be called at the start and end of every nursery collection. - */ -extern JS_PUBLIC_API GCNurseryCollectionCallback SetGCNurseryCollectionCallback( - JSContext* cx, GCNurseryCollectionCallback callback); - -typedef void (*DoCycleCollectionCallback)(JSContext* cx); - -/** - * The purge gray callback is called after any COMPARTMENT_REVIVED GC in which - * the majority of compartments have been marked gray. - */ -extern JS_PUBLIC_API DoCycleCollectionCallback -SetDoCycleCollectionCallback(JSContext* cx, DoCycleCollectionCallback callback); - -/** - * Incremental GC defaults to enabled, but may be disabled for testing or in - * embeddings that have not yet implemented barriers on their native classes. - * There is not currently a way to re-enable incremental GC once it has been - * disabled on the runtime. - */ -extern JS_PUBLIC_API void DisableIncrementalGC(JSContext* cx); - -/** - * Returns true if incremental GC is enabled. Simply having incremental GC - * enabled is not sufficient to ensure incremental collections are happening. - * See the comment "Incremental GC" above for reasons why incremental GC may be - * suppressed. Inspection of the "nonincremental reason" field of the - * GCDescription returned by GCSliceCallback may help narrow down the cause if - * collections are not happening incrementally when expected. - */ -extern JS_PUBLIC_API bool IsIncrementalGCEnabled(JSContext* cx); - -/** - * Returns true while an incremental GC is ongoing, both when actively - * collecting and between slices. - */ -extern JS_PUBLIC_API bool IsIncrementalGCInProgress(JSContext* cx); - -/** - * Returns true while an incremental GC is ongoing, both when actively - * collecting and between slices. - */ -extern JS_PUBLIC_API bool IsIncrementalGCInProgress(JSRuntime* rt); - -/** - * Returns true if the most recent GC ran incrementally. - */ -extern JS_PUBLIC_API bool WasIncrementalGC(JSRuntime* rt); - -/* - * Generational GC: - * - * Note: Generational GC is not yet enabled by default. The following class - * is non-functional unless SpiderMonkey was configured with - * --enable-gcgenerational. - */ - -/** Ensure that generational GC is disabled within some scope. */ -class JS_PUBLIC_API AutoDisableGenerationalGC { - JSContext* cx; - - public: - explicit AutoDisableGenerationalGC(JSContext* cx); - ~AutoDisableGenerationalGC(); -}; - -/** - * Returns true if generational allocation and collection is currently enabled - * on the given runtime. - */ -extern JS_PUBLIC_API bool IsGenerationalGCEnabled(JSRuntime* rt); - -/** - * Pass a subclass of this "abstract" class to callees to require that they - * never GC. Subclasses can use assertions or the hazard analysis to ensure no - * GC happens. - */ -class JS_PUBLIC_API AutoRequireNoGC { - protected: - AutoRequireNoGC() = default; - ~AutoRequireNoGC() = default; -}; - -/** - * Diagnostic assert (see MOZ_DIAGNOSTIC_ASSERT) that GC cannot occur while this - * class is live. This class does not disable the static rooting hazard - * analysis. - * - * This works by entering a GC unsafe region, which is checked on allocation and - * on GC. - */ -class JS_PUBLIC_API AutoAssertNoGC : public AutoRequireNoGC { -#ifdef MOZ_DIAGNOSTIC_ASSERT_ENABLED - JSContext* cx_; - - public: - // This gets the context from TLS if it is not passed in. - explicit AutoAssertNoGC(JSContext* cx = nullptr); - ~AutoAssertNoGC(); -#else - public: - explicit AutoAssertNoGC(JSContext* cx = nullptr) {} - ~AutoAssertNoGC() {} -#endif -}; - -/** - * Disable the static rooting hazard analysis in the live region and assert in - * debug builds if any allocation that could potentially trigger a GC occurs - * while this guard object is live. This is most useful to help the exact - * rooting hazard analysis in complex regions, since it cannot understand - * dataflow. - * - * Note: GC behavior is unpredictable even when deterministic and is generally - * non-deterministic in practice. The fact that this guard has not - * asserted is not a guarantee that a GC cannot happen in the guarded - * region. As a rule, anyone performing a GC unsafe action should - * understand the GC properties of all code in that region and ensure - * that the hazard analysis is correct for that code, rather than relying - * on this class. - */ -#ifdef DEBUG -class JS_PUBLIC_API AutoSuppressGCAnalysis : public AutoAssertNoGC { - public: - explicit AutoSuppressGCAnalysis(JSContext* cx = nullptr) - : AutoAssertNoGC(cx) {} -} JS_HAZ_GC_SUPPRESSED; -#else -class JS_PUBLIC_API AutoSuppressGCAnalysis : public AutoRequireNoGC { - public: - explicit AutoSuppressGCAnalysis(JSContext* cx = nullptr) {} -} JS_HAZ_GC_SUPPRESSED; -#endif - -/** - * Assert that code is only ever called from a GC callback, disable the static - * rooting hazard analysis and assert if any allocation that could potentially - * trigger a GC occurs while this guard object is live. - * - * This is useful to make the static analysis ignore code that runs in GC - * callbacks. - */ -class JS_PUBLIC_API AutoAssertGCCallback : public AutoSuppressGCAnalysis { - public: -#ifdef DEBUG - AutoAssertGCCallback(); -#else - AutoAssertGCCallback() {} -#endif -}; - -/** - * Place AutoCheckCannotGC in scopes that you believe can never GC. These - * annotations will be verified both dynamically via AutoAssertNoGC, and - * statically with the rooting hazard analysis (implemented by making the - * analysis consider AutoCheckCannotGC to be a GC pointer, and therefore - * complain if it is live across a GC call.) It is useful when dealing with - * internal pointers to GC things where the GC thing itself may not be present - * for the static analysis: e.g. acquiring inline chars from a JSString* on the - * heap. - * - * We only do the assertion checking in DEBUG builds. - */ -#ifdef DEBUG -class JS_PUBLIC_API AutoCheckCannotGC : public AutoAssertNoGC { - public: - explicit AutoCheckCannotGC(JSContext* cx = nullptr) : AutoAssertNoGC(cx) {} -} JS_HAZ_GC_INVALIDATED; -#else -class JS_PUBLIC_API AutoCheckCannotGC : public AutoRequireNoGC { - public: - explicit AutoCheckCannotGC(JSContext* cx = nullptr) {} -} JS_HAZ_GC_INVALIDATED; -#endif - -extern JS_PUBLIC_API void SetLowMemoryState(JSContext* cx, bool newState); - -/* - * Internal to Firefox. - */ -extern JS_FRIEND_API void NotifyGCRootsRemoved(JSContext* cx); - -} /* namespace JS */ - -typedef void (*JSGCCallback)(JSContext* cx, JSGCStatus status, - JS::GCReason reason, void* data); - -/** - * Register externally maintained GC roots. - * - * traceOp: the trace operation. For each root the implementation should call - * JS::TraceEdge whenever the root contains a traceable thing. - * data: the data argument to pass to each invocation of traceOp. - */ -extern JS_PUBLIC_API bool JS_AddExtraGCRootsTracer(JSContext* cx, - JSTraceDataOp traceOp, - void* data); - -/** Undo a call to JS_AddExtraGCRootsTracer. */ -extern JS_PUBLIC_API void JS_RemoveExtraGCRootsTracer(JSContext* cx, - JSTraceDataOp traceOp, - void* data); - -extern JS_PUBLIC_API void JS_GC(JSContext* cx, - JS::GCReason reason = JS::GCReason::API); - -extern JS_PUBLIC_API void JS_MaybeGC(JSContext* cx); - -extern JS_PUBLIC_API void JS_SetGCCallback(JSContext* cx, JSGCCallback cb, - void* data); - -extern JS_PUBLIC_API void JS_SetObjectsTenuredCallback( - JSContext* cx, JSObjectsTenuredCallback cb, void* data); - -extern JS_PUBLIC_API bool JS_AddFinalizeCallback(JSContext* cx, - JSFinalizeCallback cb, - void* data); - -extern JS_PUBLIC_API void JS_RemoveFinalizeCallback(JSContext* cx, - JSFinalizeCallback cb); - -/* - * Weak pointers and garbage collection - * - * Weak pointers are by their nature not marked as part of garbage collection, - * but they may need to be updated in two cases after a GC: - * - * 1) Their referent was found not to be live and is about to be finalized - * 2) Their referent has been moved by a compacting GC - * - * To handle this, any part of the system that maintain weak pointers to - * JavaScript GC things must register a callback with - * JS_(Add,Remove)WeakPointer{ZoneGroup,Compartment}Callback(). This callback - * must then call JS_UpdateWeakPointerAfterGC() on all weak pointers it knows - * about. - * - * Since sweeping is incremental, we have several callbacks to avoid repeatedly - * having to visit all embedder structures. The WeakPointerZonesCallback is - * called once for each strongly connected group of zones, whereas the - * WeakPointerCompartmentCallback is called once for each compartment that is - * visited while sweeping. Structures that cannot contain references in more - * than one compartment should sweep the relevant per-compartment structures - * using the latter callback to minimizer per-slice overhead. - * - * The argument to JS_UpdateWeakPointerAfterGC() is an in-out param. If the - * referent is about to be finalized the pointer will be set to null. If the - * referent has been moved then the pointer will be updated to point to the new - * location. - * - * Callers of this method are responsible for updating any state that is - * dependent on the object's address. For example, if the object's address is - * used as a key in a hashtable, then the object must be removed and - * re-inserted with the correct hash. - */ - -extern JS_PUBLIC_API bool JS_AddWeakPointerZonesCallback( - JSContext* cx, JSWeakPointerZonesCallback cb, void* data); - -extern JS_PUBLIC_API void JS_RemoveWeakPointerZonesCallback( - JSContext* cx, JSWeakPointerZonesCallback cb); - -extern JS_PUBLIC_API bool JS_AddWeakPointerCompartmentCallback( - JSContext* cx, JSWeakPointerCompartmentCallback cb, void* data); - -extern JS_PUBLIC_API void JS_RemoveWeakPointerCompartmentCallback( - JSContext* cx, JSWeakPointerCompartmentCallback cb); - -namespace JS { -template -class Heap; -} - -extern JS_PUBLIC_API void JS_UpdateWeakPointerAfterGC( - JS::Heap* objp); - -extern JS_PUBLIC_API void JS_UpdateWeakPointerAfterGCUnbarriered( - JSObject** objp); - -extern JS_PUBLIC_API void JS_SetGCParameter(JSContext* cx, JSGCParamKey key, - uint32_t value); - -extern JS_PUBLIC_API void JS_ResetGCParameter(JSContext* cx, JSGCParamKey key); - -extern JS_PUBLIC_API uint32_t JS_GetGCParameter(JSContext* cx, - JSGCParamKey key); - -extern JS_PUBLIC_API void JS_SetGCParametersBasedOnAvailableMemory( - JSContext* cx, uint32_t availMem); - -/** - * Create a new JSString whose chars member refers to external memory, i.e., - * memory requiring application-specific finalization. - */ -extern JS_PUBLIC_API JSString* JS_NewExternalString( - JSContext* cx, const char16_t* chars, size_t length, - const JSExternalStringCallbacks* callbacks); - -/** - * Create a new JSString whose chars member may refer to external memory. - * If a new external string is allocated, |*allocatedExternal| is set to true. - * Otherwise the returned string is either not an external string or an - * external string allocated by a previous call and |*allocatedExternal| is set - * to false. If |*allocatedExternal| is false, |fin| won't be called. - */ -extern JS_PUBLIC_API JSString* JS_NewMaybeExternalString( - JSContext* cx, const char16_t* chars, size_t length, - const JSExternalStringCallbacks* callbacks, bool* allocatedExternal); - -/** - * Return whether 'str' was created with JS_NewExternalString or - * JS_NewExternalStringWithClosure. - */ -extern JS_PUBLIC_API bool JS_IsExternalString(JSString* str); - -/** - * Return the 'callbacks' arg passed to JS_NewExternalString or - * JS_NewMaybeExternalString. - */ -extern JS_PUBLIC_API const JSExternalStringCallbacks* -JS_GetExternalStringCallbacks(JSString* str); - -namespace JS { - -extern JS_PUBLIC_API bool IsIdleGCTaskNeeded(JSRuntime* rt); - -extern JS_PUBLIC_API void RunIdleTimeGCTask(JSRuntime* rt); - -extern JS_PUBLIC_API void SetHostCleanupFinalizationRegistryCallback( - JSContext* cx, JSHostCleanupFinalizationRegistryCallback cb, void* data); - -/** - * Clear kept alive objects in JS WeakRef. - * https://tc39.es/proposal-weakrefs/#sec-clear-kept-objects - */ -extern JS_PUBLIC_API void ClearKeptObjects(JSContext* cx); - -extern JS_PUBLIC_API bool ZoneIsCollecting(Zone* zone); - -} // namespace JS - -namespace js { -namespace gc { - -/** - * Create an object providing access to the garbage collector's internal notion - * of the current state of memory (both GC heap memory and GCthing-controlled - * malloc memory. - */ -extern JS_PUBLIC_API JSObject* NewMemoryInfoObject(JSContext* cx); - -/* - * Run the finalizer of a nursery-allocated JSObject that is known to be dead. - * - * This is a dangerous operation - only use this if you know what you're doing! - * - * This is used by the browser to implement nursery-allocated wrapper cached - * wrappers. - */ -extern JS_PUBLIC_API void FinalizeDeadNurseryObject(JSContext* cx, - JSObject* obj); - -} /* namespace gc */ -} /* namespace js */ - -#endif /* js_GCAPI_h */ Index: libraries/source/spidermonkey/include-win32-debug/js/GCAnnotations.h =================================================================== --- /dev/null +++ libraries/source/spidermonkey/include-win32-debug/js/GCAnnotations.h @@ -1,82 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- - * vim: set ts=8 sts=2 et sw=2 tw=80: - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef js_GCAnnotations_h -#define js_GCAnnotations_h - -// Set of annotations for the rooting hazard analysis, used to categorize types -// and functions. -#ifdef XGILL_PLUGIN - -# define JS_EXPECT_HAZARDS __attribute__((annotate("Expect Hazards"))) - -// Mark a type as being a GC thing (eg js::gc::Cell has this annotation). -# define JS_HAZ_GC_THING __attribute__((annotate("GC Thing"))) - -// Mark a type as holding a pointer to a GC thing (eg JS::Value has this -// annotation.) "Inherited" by templatized types with -// MOZ_INHERIT_TYPE_ANNOTATIONS_FROM_TEMPLATE_ARGS. -# define JS_HAZ_GC_POINTER __attribute__((annotate("GC Pointer"))) - -// Mark a type as a rooted pointer, suitable for use on the stack (eg all -// Rooted instantiations should have this.) "Inherited" by templatized types -// with MOZ_INHERIT_TYPE_ANNOTATIONS_FROM_TEMPLATE_ARGS. -# define JS_HAZ_ROOTED __attribute__((annotate("Rooted Pointer"))) - -// Mark a type as something that should not be held live across a GC, but which -// is not itself a GC pointer. Note that this property is *not* inherited by -// templatized types with MOZ_INHERIT_TYPE_ANNOTATIONS_FROM_TEMPLATE_ARGS. -# define JS_HAZ_GC_INVALIDATED __attribute__((annotate("Invalidated by GC"))) - -// Mark a class as a base class of rooted types, eg CustomAutoRooter. All -// descendants of this class will be considered rooted, though classes that -// merely contain these as a field member will not be. "Inherited" by -// templatized types with MOZ_INHERIT_TYPE_ANNOTATIONS_FROM_TEMPLATE_ARGS -# define JS_HAZ_ROOTED_BASE __attribute__((annotate("Rooted Base"))) - -// Mark a type that would otherwise be considered a GC Pointer (eg because it -// contains a JS::Value field) as a non-GC pointer. It is handled almost the -// same in the analysis as a rooted pointer, except it will not be reported as -// an unnecessary root if used across a GC call. This should rarely be used, -// but makes sense for something like ErrorResult, which only contains a GC -// pointer when it holds an exception (and it does its own rooting, -// conditionally.) -# define JS_HAZ_NON_GC_POINTER \ - __attribute__((annotate("Suppressed GC Pointer"))) - -// Mark a function as something that runs a garbage collection, potentially -// invalidating GC pointers. -# define JS_HAZ_GC_CALL __attribute__((annotate("GC Call"))) - -// Mark an RAII class as suppressing GC within its scope. -# define JS_HAZ_GC_SUPPRESSED __attribute__((annotate("Suppress GC"))) - -// Mark a function as one that can run script if called. This obviously -// subsumes JS_HAZ_GC_CALL, since anything that can run script can GC.` -# define JS_HAZ_CAN_RUN_SCRIPT __attribute__((annotate("Can run script"))) - -// Mark a function as able to call JSNatives. Otherwise, JSNatives don't show -// up in the callgraph. This doesn't matter for the can-GC analysis, but it is -// very nice for other uses of the callgraph. -# define JS_HAZ_JSNATIVE_CALLER __attribute__((annotate("Calls JSNatives"))) - -#else - -# define JS_EXPECT_HAZARDS -# define JS_HAZ_GC_THING -# define JS_HAZ_GC_POINTER -# define JS_HAZ_ROOTED -# define JS_HAZ_GC_INVALIDATED -# define JS_HAZ_ROOTED_BASE -# define JS_HAZ_NON_GC_POINTER -# define JS_HAZ_GC_CALL -# define JS_HAZ_GC_SUPPRESSED -# define JS_HAZ_CAN_RUN_SCRIPT -# define JS_HAZ_JSNATIVE_CALLER - -#endif - -#endif /* js_GCAnnotations_h */ Index: libraries/source/spidermonkey/include-win32-debug/js/GCHashTable.h =================================================================== --- /dev/null +++ libraries/source/spidermonkey/include-win32-debug/js/GCHashTable.h @@ -1,758 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- - * vim: set ts=8 sts=2 et sw=2 tw=80: - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef GCHashTable_h -#define GCHashTable_h - -#include "mozilla/Maybe.h" - -#include "js/GCPolicyAPI.h" -#include "js/HashTable.h" -#include "js/RootingAPI.h" -#include "js/SweepingAPI.h" -#include "js/TracingAPI.h" - -namespace JS { - -// Define a reasonable default GC policy for GC-aware Maps. -template -struct DefaultMapSweepPolicy { - static bool needsSweep(Key* key, Value* value) { - return GCPolicy::needsSweep(key) || GCPolicy::needsSweep(value); - } - - static bool traceWeak(JSTracer* trc, Key* key, Value* value) { - return GCPolicy::traceWeak(trc, key) && - GCPolicy::traceWeak(trc, value); - } -}; - -// A GCHashMap is a GC-aware HashMap, meaning that it has additional trace and -// sweep methods that know how to visit all keys and values in the table. -// HashMaps that contain GC pointers will generally want to use this GCHashMap -// specialization instead of HashMap, because this conveniently supports tracing -// keys and values, and cleaning up weak entries. -// -// GCHashMap::trace applies GCPolicy::trace to each entry's key and value. -// Most types of GC pointers already have appropriate specializations of -// GCPolicy, so they should just work as keys and values. Any struct type with a -// default constructor and trace and sweep functions should work as well. If you -// need to define your own GCPolicy specialization, generic helpers can be found -// in js/public/TracingAPI.h. -// -// The MapSweepPolicy template parameter controls how the table drops entries -// when swept. GCHashMap::sweep applies MapSweepPolicy::needsSweep to each table -// entry; if it returns true, the entry is dropped. The default MapSweepPolicy -// drops the entry if either the key or value is about to be finalized, -// according to its GCPolicy::needsSweep method. (This default is almost -// always fine: it's hard to imagine keeping such an entry around anyway.) -// -// Note that this HashMap only knows *how* to trace and sweep, but it does not -// itself cause tracing or sweeping to be invoked. For tracing, it must be used -// with Rooted or PersistentRooted, or barriered and traced manually. For -// sweeping, currently it requires an explicit call to .sweep(). -template , - typename AllocPolicy = js::TempAllocPolicy, - typename MapSweepPolicy = DefaultMapSweepPolicy> -class GCHashMap : public js::HashMap { - using Base = js::HashMap; - - public: - explicit GCHashMap(AllocPolicy a = AllocPolicy()) : Base(std::move(a)) {} - explicit GCHashMap(size_t length) : Base(length) {} - GCHashMap(AllocPolicy a, size_t length) : Base(std::move(a), length) {} - - void trace(JSTracer* trc) { - for (typename Base::Enum e(*this); !e.empty(); e.popFront()) { - GCPolicy::trace(trc, &e.front().value(), "hashmap value"); - GCPolicy::trace(trc, &e.front().mutableKey(), "hashmap key"); - } - } - - bool needsSweep() const { return !this->empty(); } - - void sweep() { - for (typename Base::Enum e(*this); !e.empty(); e.popFront()) { - if (MapSweepPolicy::needsSweep(&e.front().mutableKey(), - &e.front().value())) { - e.removeFront(); - } - } - } - - void traceWeak(JSTracer* trc) { - for (typename Base::Enum e(*this); !e.empty(); e.popFront()) { - if (!MapSweepPolicy::traceWeak(trc, &e.front().mutableKey(), - &e.front().value())) { - e.removeFront(); - } - } - } - - // GCHashMap is movable - GCHashMap(GCHashMap&& rhs) : Base(std::move(rhs)) {} - void operator=(GCHashMap&& rhs) { - MOZ_ASSERT(this != &rhs, "self-move assignment is prohibited"); - Base::operator=(std::move(rhs)); - } - - private: - // GCHashMap is not copyable or assignable - GCHashMap(const GCHashMap& hm) = delete; - GCHashMap& operator=(const GCHashMap& hm) = delete; -} MOZ_INHERIT_TYPE_ANNOTATIONS_FROM_TEMPLATE_ARGS; - -} // namespace JS - -namespace js { - -// HashMap that supports rekeying. -// -// If your keys are pointers to something like JSObject that can be tenured or -// compacted, prefer to use GCHashMap with MovableCellHasher, which takes -// advantage of the Zone's stable id table to make rekeying unnecessary. -template , - typename AllocPolicy = TempAllocPolicy, - typename MapSweepPolicy = JS::DefaultMapSweepPolicy> -class GCRekeyableHashMap : public JS::GCHashMap { - using Base = JS::GCHashMap; - - public: - explicit GCRekeyableHashMap(AllocPolicy a = AllocPolicy()) - : Base(std::move(a)) {} - explicit GCRekeyableHashMap(size_t length) : Base(length) {} - GCRekeyableHashMap(AllocPolicy a, size_t length) - : Base(std::move(a), length) {} - - void sweep() { - for (typename Base::Enum e(*this); !e.empty(); e.popFront()) { - Key key(e.front().key()); - if (MapSweepPolicy::needsSweep(&key, &e.front().value())) { - e.removeFront(); - } else if (!HashPolicy::match(key, e.front().key())) { - e.rekeyFront(key); - } - } - } - - void traceWeak(JSTracer* trc) { - for (typename Base::Enum e(*this); !e.empty(); e.popFront()) { - Key key(e.front().key()); - if (!MapSweepPolicy::traceWeak(trc, &key, &e.front().value())) { - e.removeFront(); - } else if (!HashPolicy::match(key, e.front().key())) { - e.rekeyFront(key); - } - } - } - - // GCRekeyableHashMap is movable - GCRekeyableHashMap(GCRekeyableHashMap&& rhs) : Base(std::move(rhs)) {} - void operator=(GCRekeyableHashMap&& rhs) { - MOZ_ASSERT(this != &rhs, "self-move assignment is prohibited"); - Base::operator=(std::move(rhs)); - } -} MOZ_INHERIT_TYPE_ANNOTATIONS_FROM_TEMPLATE_ARGS; - -template -class WrappedPtrOperations, Wrapper> { - using Map = JS::GCHashMap; - using Lookup = typename Map::Lookup; - - const Map& map() const { return static_cast(this)->get(); } - - public: - using AddPtr = typename Map::AddPtr; - using Ptr = typename Map::Ptr; - using Range = typename Map::Range; - - Ptr lookup(const Lookup& l) const { return map().lookup(l); } - Range all() const { return map().all(); } - bool empty() const { return map().empty(); } - uint32_t count() const { return map().count(); } - size_t capacity() const { return map().capacity(); } - bool has(const Lookup& l) const { return map().lookup(l).found(); } - size_t sizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf) const { - return map().sizeOfExcludingThis(mallocSizeOf); - } - size_t sizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf) const { - return mallocSizeOf(this) + map().sizeOfExcludingThis(mallocSizeOf); - } -}; - -template -class MutableWrappedPtrOperations, Wrapper> - : public WrappedPtrOperations, Wrapper> { - using Map = JS::GCHashMap; - using Lookup = typename Map::Lookup; - - Map& map() { return static_cast(this)->get(); } - - public: - using AddPtr = typename Map::AddPtr; - struct Enum : public Map::Enum { - explicit Enum(Wrapper& o) : Map::Enum(o.map()) {} - }; - using Ptr = typename Map::Ptr; - using Range = typename Map::Range; - - void clear() { map().clear(); } - void clearAndCompact() { map().clearAndCompact(); } - void remove(Ptr p) { map().remove(p); } - AddPtr lookupForAdd(const Lookup& l) { return map().lookupForAdd(l); } - - template - bool add(AddPtr& p, KeyInput&& k, ValueInput&& v) { - return map().add(p, std::forward(k), std::forward(v)); - } - - template - bool add(AddPtr& p, KeyInput&& k) { - return map().add(p, std::forward(k), Map::Value()); - } - - template - bool relookupOrAdd(AddPtr& p, KeyInput&& k, ValueInput&& v) { - return map().relookupOrAdd(p, k, std::forward(k), - std::forward(v)); - } - - template - bool put(KeyInput&& k, ValueInput&& v) { - return map().put(std::forward(k), std::forward(v)); - } - - template - bool putNew(KeyInput&& k, ValueInput&& v) { - return map().putNew(std::forward(k), std::forward(v)); - } -}; - -} // namespace js - -namespace JS { - -// A GCHashSet is a HashSet with an additional trace method that knows -// be traced to be kept alive will generally want to use this GCHashSet -// specialization in lieu of HashSet. -// -// Most types of GC pointers can be traced with no extra infrastructure. For -// structs and non-gc-pointer members, ensure that there is a specialization of -// GCPolicy with an appropriate trace method available to handle the custom -// type. Generic helpers can be found in js/public/TracingAPI.h. -// -// Note that although this HashSet's trace will deal correctly with moved -// elements, it does not itself know when to barrier or trace elements. To -// function properly it must either be used with Rooted or barriered and traced -// manually. -template , - typename AllocPolicy = js::TempAllocPolicy> -class GCHashSet : public js::HashSet { - using Base = js::HashSet; - - public: - explicit GCHashSet(AllocPolicy a = AllocPolicy()) : Base(std::move(a)) {} - explicit GCHashSet(size_t length) : Base(length) {} - GCHashSet(AllocPolicy a, size_t length) : Base(std::move(a), length) {} - - void trace(JSTracer* trc) { - for (typename Base::Enum e(*this); !e.empty(); e.popFront()) { - GCPolicy::trace(trc, &e.mutableFront(), "hashset element"); - } - } - - bool needsSweep() const { return !this->empty(); } - - void sweep() { - for (typename Base::Enum e(*this); !e.empty(); e.popFront()) { - if (GCPolicy::needsSweep(&e.mutableFront())) { - e.removeFront(); - } - } - } - - void traceWeak(JSTracer* trc) { - for (typename Base::Enum e(*this); !e.empty(); e.popFront()) { - if (!GCPolicy::traceWeak(trc, &e.mutableFront())) { - e.removeFront(); - } - } - } - - // GCHashSet is movable - GCHashSet(GCHashSet&& rhs) : Base(std::move(rhs)) {} - void operator=(GCHashSet&& rhs) { - MOZ_ASSERT(this != &rhs, "self-move assignment is prohibited"); - Base::operator=(std::move(rhs)); - } - - private: - // GCHashSet is not copyable or assignable - GCHashSet(const GCHashSet& hs) = delete; - GCHashSet& operator=(const GCHashSet& hs) = delete; -} MOZ_INHERIT_TYPE_ANNOTATIONS_FROM_TEMPLATE_ARGS; - -} // namespace JS - -namespace js { - -template -class WrappedPtrOperations, Wrapper> { - using Set = JS::GCHashSet; - - const Set& set() const { return static_cast(this)->get(); } - - public: - using Lookup = typename Set::Lookup; - using AddPtr = typename Set::AddPtr; - using Entry = typename Set::Entry; - using Ptr = typename Set::Ptr; - using Range = typename Set::Range; - - Ptr lookup(const Lookup& l) const { return set().lookup(l); } - Range all() const { return set().all(); } - bool empty() const { return set().empty(); } - uint32_t count() const { return set().count(); } - size_t capacity() const { return set().capacity(); } - bool has(const Lookup& l) const { return set().lookup(l).found(); } - size_t sizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf) const { - return set().sizeOfExcludingThis(mallocSizeOf); - } - size_t sizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf) const { - return mallocSizeOf(this) + set().sizeOfExcludingThis(mallocSizeOf); - } -}; - -template -class MutableWrappedPtrOperations, Wrapper> - : public WrappedPtrOperations, Wrapper> { - using Set = JS::GCHashSet; - using Lookup = typename Set::Lookup; - - Set& set() { return static_cast(this)->get(); } - - public: - using AddPtr = typename Set::AddPtr; - using Entry = typename Set::Entry; - struct Enum : public Set::Enum { - explicit Enum(Wrapper& o) : Set::Enum(o.set()) {} - }; - using Ptr = typename Set::Ptr; - using Range = typename Set::Range; - - void clear() { set().clear(); } - void clearAndCompact() { set().clearAndCompact(); } - MOZ_MUST_USE bool reserve(uint32_t len) { return set().reserve(len); } - void remove(Ptr p) { set().remove(p); } - void remove(const Lookup& l) { set().remove(l); } - AddPtr lookupForAdd(const Lookup& l) { return set().lookupForAdd(l); } - - template - bool add(AddPtr& p, TInput&& t) { - return set().add(p, std::forward(t)); - } - - template - bool relookupOrAdd(AddPtr& p, const Lookup& l, TInput&& t) { - return set().relookupOrAdd(p, l, std::forward(t)); - } - - template - bool put(TInput&& t) { - return set().put(std::forward(t)); - } - - template - bool putNew(TInput&& t) { - return set().putNew(std::forward(t)); - } - - template - bool putNew(const Lookup& l, TInput&& t) { - return set().putNew(l, std::forward(t)); - } -}; - -} /* namespace js */ - -namespace JS { - -// Specialize WeakCache for GCHashMap to provide a barriered map that does not -// need to be swept immediately. -template -class WeakCache> - : protected detail::WeakCacheBase { - using Map = GCHashMap; - using Self = WeakCache; - - Map map; - bool needsBarrier; - - public: - template - explicit WeakCache(Zone* zone, Args&&... args) - : WeakCacheBase(zone), - map(std::forward(args)...), - needsBarrier(false) {} - template - explicit WeakCache(JSRuntime* rt, Args&&... args) - : WeakCacheBase(rt), - map(std::forward(args)...), - needsBarrier(false) {} - ~WeakCache() { MOZ_ASSERT(!needsBarrier); } - - bool needsSweep() override { return map.needsSweep(); } - - size_t sweep() override { - size_t steps = map.count(); - map.sweep(); - return steps; - } - - bool setNeedsIncrementalBarrier(bool needs) override { - MOZ_ASSERT(needsBarrier != needs); - needsBarrier = needs; - return true; - } - - bool needsIncrementalBarrier() const override { return needsBarrier; } - - private: - using Entry = typename Map::Entry; - - static bool entryNeedsSweep(const Entry& prior) { - Key key(prior.key()); - Value value(prior.value()); - bool result = MapSweepPolicy::needsSweep(&key, &value); - MOZ_ASSERT(prior.key() == key); // We shouldn't update here. - MOZ_ASSERT(prior.value() == value); // We shouldn't update here. - return result; - } - - public: - using Lookup = typename Map::Lookup; - using Ptr = typename Map::Ptr; - using AddPtr = typename Map::AddPtr; - - struct Range { - explicit Range(const typename Map::Range& r) : range(r) { settle(); } - Range() = default; - - bool empty() const { return range.empty(); } - const Entry& front() const { return range.front(); } - - void popFront() { - range.popFront(); - settle(); - } - - private: - typename Map::Range range; - - void settle() { - while (!empty() && entryNeedsSweep(front())) { - popFront(); - } - } - }; - - struct Enum : public Map::Enum { - explicit Enum(Self& cache) : Map::Enum(cache.map) { - // This operation is not allowed while barriers are in place as we - // may also need to enumerate the set for sweeping. - MOZ_ASSERT(!cache.needsBarrier); - } - }; - - Ptr lookup(const Lookup& l) const { - Ptr ptr = map.lookup(l); - if (needsBarrier && ptr && entryNeedsSweep(*ptr)) { - const_cast(map).remove(ptr); - return Ptr(); - } - return ptr; - } - - AddPtr lookupForAdd(const Lookup& l) { - AddPtr ptr = map.lookupForAdd(l); - if (needsBarrier && ptr && entryNeedsSweep(*ptr)) { - const_cast(map).remove(ptr); - return map.lookupForAdd(l); - } - return ptr; - } - - Range all() const { return Range(map.all()); } - - bool empty() const { - // This operation is not currently allowed while barriers are in place - // as it would require iterating the map and the caller expects a - // constant time operation. - MOZ_ASSERT(!needsBarrier); - return map.empty(); - } - - uint32_t count() const { - // This operation is not currently allowed while barriers are in place - // as it would require iterating the set and the caller expects a - // constant time operation. - MOZ_ASSERT(!needsBarrier); - return map.count(); - } - - size_t capacity() const { return map.capacity(); } - - bool has(const Lookup& l) const { return lookup(l).found(); } - - size_t sizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf) const { - return map.sizeOfExcludingThis(mallocSizeOf); - } - size_t sizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf) const { - return mallocSizeOf(this) + map.shallowSizeOfExcludingThis(mallocSizeOf); - } - - void clear() { - // This operation is not currently allowed while barriers are in place - // since it doesn't make sense to clear a cache while it is being swept. - MOZ_ASSERT(!needsBarrier); - map.clear(); - } - - void clearAndCompact() { - // This operation is not currently allowed while barriers are in place - // since it doesn't make sense to clear a cache while it is being swept. - MOZ_ASSERT(!needsBarrier); - map.clearAndCompact(); - } - - void remove(Ptr p) { - // This currently supports removing entries during incremental - // sweeping. If we allow these tables to be swept incrementally this may - // no longer be possible. - map.remove(p); - } - - void remove(const Lookup& l) { - Ptr p = lookup(l); - if (p) { - remove(p); - } - } - - template - bool add(AddPtr& p, KeyInput&& k, ValueInput&& v) { - return map.add(p, std::forward(k), std::forward(v)); - } - - template - bool relookupOrAdd(AddPtr& p, KeyInput&& k, ValueInput&& v) { - return map.relookupOrAdd(p, std::forward(k), - std::forward(v)); - } - - template - bool put(KeyInput&& k, ValueInput&& v) { - return map.put(std::forward(k), std::forward(v)); - } - - template - bool putNew(KeyInput&& k, ValueInput&& v) { - return map.putNew(std::forward(k), std::forward(v)); - } -} JS_HAZ_NON_GC_POINTER; - -// Specialize WeakCache for GCHashSet to provide a barriered set that does not -// need to be swept immediately. -template -class WeakCache> - : protected detail::WeakCacheBase { - using Set = GCHashSet; - using Self = WeakCache; - - Set set; - bool needsBarrier; - - public: - using Entry = typename Set::Entry; - - template - explicit WeakCache(Zone* zone, Args&&... args) - : WeakCacheBase(zone), - set(std::forward(args)...), - needsBarrier(false) {} - template - explicit WeakCache(JSRuntime* rt, Args&&... args) - : WeakCacheBase(rt), - set(std::forward(args)...), - needsBarrier(false) {} - - size_t sweep() override { - size_t steps = set.count(); - set.sweep(); - return steps; - } - - bool needsSweep() override { return set.needsSweep(); } - - bool setNeedsIncrementalBarrier(bool needs) override { - MOZ_ASSERT(needsBarrier != needs); - needsBarrier = needs; - return true; - } - - bool needsIncrementalBarrier() const override { return needsBarrier; } - - private: - static bool entryNeedsSweep(const Entry& prior) { - Entry entry(prior); - bool result = GCPolicy::needsSweep(&entry); - MOZ_ASSERT(prior == entry); // We shouldn't update here. - return result; - } - - public: - using Lookup = typename Set::Lookup; - using Ptr = typename Set::Ptr; - using AddPtr = typename Set::AddPtr; - - struct Range { - explicit Range(const typename Set::Range& r) : range(r) { settle(); } - Range() = default; - - bool empty() const { return range.empty(); } - const Entry& front() const { return range.front(); } - - void popFront() { - range.popFront(); - settle(); - } - - private: - typename Set::Range range; - - void settle() { - while (!empty() && entryNeedsSweep(front())) { - popFront(); - } - } - }; - - struct Enum : public Set::Enum { - explicit Enum(Self& cache) : Set::Enum(cache.set) { - // This operation is not allowed while barriers are in place as we - // may also need to enumerate the set for sweeping. - MOZ_ASSERT(!cache.needsBarrier); - } - }; - - Ptr lookup(const Lookup& l) const { - Ptr ptr = set.lookup(l); - if (needsBarrier && ptr && entryNeedsSweep(*ptr)) { - const_cast(set).remove(ptr); - return Ptr(); - } - return ptr; - } - - AddPtr lookupForAdd(const Lookup& l) { - AddPtr ptr = set.lookupForAdd(l); - if (needsBarrier && ptr && entryNeedsSweep(*ptr)) { - const_cast(set).remove(ptr); - return set.lookupForAdd(l); - } - return ptr; - } - - Range all() const { return Range(set.all()); } - - bool empty() const { - // This operation is not currently allowed while barriers are in place - // as it would require iterating the set and the caller expects a - // constant time operation. - MOZ_ASSERT(!needsBarrier); - return set.empty(); - } - - uint32_t count() const { - // This operation is not currently allowed while barriers are in place - // as it would require iterating the set and the caller expects a - // constant time operation. - MOZ_ASSERT(!needsBarrier); - return set.count(); - } - - size_t capacity() const { return set.capacity(); } - - bool has(const Lookup& l) const { return lookup(l).found(); } - - size_t sizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf) const { - return set.shallowSizeOfExcludingThis(mallocSizeOf); - } - size_t sizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf) const { - return mallocSizeOf(this) + set.shallowSizeOfExcludingThis(mallocSizeOf); - } - - void clear() { - // This operation is not currently allowed while barriers are in place - // since it doesn't make sense to clear a cache while it is being swept. - MOZ_ASSERT(!needsBarrier); - set.clear(); - } - - void clearAndCompact() { - // This operation is not currently allowed while barriers are in place - // since it doesn't make sense to clear a cache while it is being swept. - MOZ_ASSERT(!needsBarrier); - set.clearAndCompact(); - } - - void remove(Ptr p) { - // This currently supports removing entries during incremental - // sweeping. If we allow these tables to be swept incrementally this may - // no longer be possible. - set.remove(p); - } - - void remove(const Lookup& l) { - Ptr p = lookup(l); - if (p) { - remove(p); - } - } - - template - bool add(AddPtr& p, TInput&& t) { - return set.add(p, std::forward(t)); - } - - template - bool relookupOrAdd(AddPtr& p, const Lookup& l, TInput&& t) { - return set.relookupOrAdd(p, l, std::forward(t)); - } - - template - bool put(TInput&& t) { - return set.put(std::forward(t)); - } - - template - bool putNew(TInput&& t) { - return set.putNew(std::forward(t)); - } - - template - bool putNew(const Lookup& l, TInput&& t) { - return set.putNew(l, std::forward(t)); - } -} JS_HAZ_NON_GC_POINTER; - -} // namespace JS - -#endif /* GCHashTable_h */ Index: libraries/source/spidermonkey/include-win32-debug/js/GCPolicyAPI.h =================================================================== --- /dev/null +++ libraries/source/spidermonkey/include-win32-debug/js/GCPolicyAPI.h @@ -1,242 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- - * vim: set ts=8 sts=2 et sw=2 tw=80: - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -// GC Policy Mechanism - -// A GCPolicy controls how the GC interacts with both direct pointers to GC -// things (e.g. JSObject* or JSString*), tagged and/or optional pointers to GC -// things (e.g. Value or jsid), and C++ container types (e.g. -// JSPropertyDescriptor or GCHashMap). -// -// The GCPolicy provides at a minimum: -// -// static void trace(JSTracer, T* tp, const char* name) -// - Trace the edge |*tp|, calling the edge |name|. Containers like -// GCHashMap and GCHashSet use this method to trace their children. -// -// static bool needsSweep(T* tp) -// - [DEPRECATED], use traceWeak instead. -// Return true if |*tp| is about to be finalized. Otherwise, update the -// edge for moving GC, and return false. Containers like GCHashMap and -// GCHashSet use this method to decide when to remove an entry: if this -// function returns true on a key/value/member/etc, its entry is dropped -// from the container. Specializing this method is the standard way to -// get custom weak behavior from a container type. -// -// static bool traceWeak(T* tp) -// - Return false if |*tp| has been set to nullptr. Otherwise, update the -// edge for moving GC, and return true. Containers like GCHashMap and -// GCHashSet use this method to decide when to remove an entry: if this -// function returns false on a key/value/member/etc, its entry is -// dropped from the container. Specializing this method is the standard -// way to get custom weak behavior from a container type. -// -// static bool isValid(const T& t) -// - Return false only if |t| is corrupt in some way. The built-in GC -// types do some memory layout checks. For debugging only; it is ok -// to always return true or even to omit this member entirely. -// -// The default GCPolicy assumes that T has a default constructor and |trace| -// and |traceWeak| methods, and forwards to them. GCPolicy has appropriate -// specializations for pointers to GC things and pointer-like types like -// JS::Heap and mozilla::UniquePtr. -// -// There are some stock structs your specializations can inherit from. -// IgnoreGCPolicy does nothing. StructGCPolicy forwards the methods to the -// referent type T. - -#ifndef GCPolicyAPI_h -#define GCPolicyAPI_h - -#include "mozilla/Maybe.h" -#include "mozilla/UniquePtr.h" - -#include - -#include "js/GCTypeMacros.h" // JS_FOR_EACH_PUBLIC_GC_POINTER_TYPE -#include "js/TraceKind.h" -#include "js/TracingAPI.h" -#include "js/TypeDecls.h" - -namespace JS { - -// Defines a policy for container types with non-GC, i.e. C storage. This -// policy dispatches to the underlying struct for GC interactions. -template -struct StructGCPolicy { - static_assert(!std::is_pointer_v, - "Pointer type not allowed for StructGCPolicy"); - - static void trace(JSTracer* trc, T* tp, const char* name) { tp->trace(trc); } - - static void sweep(T* tp) { return tp->sweep(); } - - static bool needsSweep(T* tp) { return tp->needsSweep(); } - - static bool traceWeak(JSTracer* trc, T* tp) { return tp->traceWeak(trc); } - - static bool isValid(const T& tp) { return true; } -}; - -// The default GC policy attempts to defer to methods on the underlying type. -// Most C++ structures that contain a default constructor, a trace function and -// a sweep function will work out of the box with Rooted, Handle, GCVector, -// and GCHash{Set,Map}. -template -struct GCPolicy : public StructGCPolicy {}; - -// This policy ignores any GC interaction, e.g. for non-GC types. -template -struct IgnoreGCPolicy { - static void trace(JSTracer* trc, T* t, const char* name) {} - static bool needsSweep(T* v) { return false; } - static bool traceWeak(JSTracer*, T* v) { return true; } - static bool isValid(const T& v) { return true; } -}; -template <> -struct GCPolicy : public IgnoreGCPolicy {}; -template <> -struct GCPolicy : public IgnoreGCPolicy {}; - -template -struct GCPointerPolicy { - static_assert(std::is_pointer_v, - "Non-pointer type not allowed for GCPointerPolicy"); - - static void trace(JSTracer* trc, T* vp, const char* name) { - // It's not safe to trace unbarriered pointers except as part of root - // marking. - UnsafeTraceRoot(trc, vp, name); - } - static bool needsSweep(T* vp) { - if (*vp) { - return js::gc::IsAboutToBeFinalizedUnbarriered(vp); - } - return false; - } - static bool traceWeak(JSTracer* trc, T* vp) { - if (*vp) { - return js::TraceManuallyBarrieredWeakEdge(trc, vp, "traceWeak"); - } - return true; - } - static bool isTenured(T v) { return !js::gc::IsInsideNursery(v); } - static bool isValid(T v) { return js::gc::IsCellPointerValidOrNull(v); } -}; -#define EXPAND_SPECIALIZE_GCPOLICY(Type) \ - template <> \ - struct GCPolicy : public GCPointerPolicy {}; \ - template <> \ - struct GCPolicy : public GCPointerPolicy {}; -JS_FOR_EACH_PUBLIC_GC_POINTER_TYPE(EXPAND_SPECIALIZE_GCPOLICY) -#undef EXPAND_SPECIALIZE_GCPOLICY - -template -struct NonGCPointerPolicy { - static void trace(JSTracer* trc, T* vp, const char* name) { - if (*vp) { - (*vp)->trace(trc); - } - } - static bool needsSweep(T* vp) { - if (*vp) { - return (*vp)->needsSweep(); - } - return false; - } - static bool traceWeak(JSTracer* trc, T* vp) { - if (*vp) { - return (*vp)->traceWeak(trc); - } - return true; - } - - static bool isValid(T v) { return true; } -}; - -template -struct GCPolicy> { - static void trace(JSTracer* trc, JS::Heap* thingp, const char* name) { - TraceEdge(trc, thingp, name); - } - static bool needsSweep(JS::Heap* thingp) { - return *thingp && js::gc::EdgeNeedsSweep(thingp); - } - static bool traceWeak(JSTracer* trc, JS::Heap* thingp) { - if (*thingp) { - return js::TraceWeakEdge(trc, thingp, "traceWeak"); - } - return true; - } -}; - -// GCPolicy> forwards the contained pointer to GCPolicy. -template -struct GCPolicy> { - static void trace(JSTracer* trc, mozilla::UniquePtr* tp, - const char* name) { - if (tp->get()) { - GCPolicy::trace(trc, tp->get(), name); - } - } - static bool needsSweep(mozilla::UniquePtr* tp) { - if (tp->get()) { - return GCPolicy::needsSweep(tp->get()); - } - return false; - } - static bool traceWeak(JSTracer* trc, mozilla::UniquePtr* tp) { - if (tp->get()) { - return GCPolicy::traceWeak(trc, tp->get()); - } - return true; - } - static bool isValid(const mozilla::UniquePtr& t) { - if (t.get()) { - return GCPolicy::isValid(*t.get()); - } - return true; - } -}; - -template <> -struct GCPolicy : public IgnoreGCPolicy {}; - -// GCPolicy> forwards tracing/sweeping to GCPolicy if -// when the Maybe is full. -template -struct GCPolicy> { - static void trace(JSTracer* trc, mozilla::Maybe* tp, const char* name) { - if (tp->isSome()) { - GCPolicy::trace(trc, tp->ptr(), name); - } - } - static bool needsSweep(mozilla::Maybe* tp) { - if (tp->isSome()) { - return GCPolicy::needsSweep(tp->ptr()); - } - return false; - } - static bool traceWeak(JSTracer* trc, mozilla::Maybe* tp) { - if (tp->isSome()) { - return GCPolicy::traceWeak(trc, tp->ptr()); - } - return true; - } - static bool isValid(const mozilla::Maybe& t) { - if (t.isSome()) { - return GCPolicy::isValid(t.ref()); - } - return true; - } -}; - -template <> -struct GCPolicy; // see Realm.h - -} // namespace JS - -#endif // GCPolicyAPI_h Index: libraries/source/spidermonkey/include-win32-debug/js/GCTypeMacros.h =================================================================== --- /dev/null +++ libraries/source/spidermonkey/include-win32-debug/js/GCTypeMacros.h @@ -1,44 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- - * vim: set ts=8 sts=2 et sw=2 tw=80: - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* - * Higher-order macros enumerating public untagged and tagged GC pointer types. - */ - -#ifndef GCTypeMacros_h -#define GCTypeMacros_h - -#include "jstypes.h" // JS_PUBLIC_API - -class JS_PUBLIC_API JSAtom; -class JS_PUBLIC_API JSFunction; -class JS_PUBLIC_API JSObject; -class JS_PUBLIC_API JSScript; -class JS_PUBLIC_API JSString; - -namespace JS { -class JS_PUBLIC_API BigInt; -struct JS_PUBLIC_API PropertyKey; -class JS_PUBLIC_API Symbol; -class JS_PUBLIC_API Value; -} // namespace JS - -// Expand the given macro D for each public GC pointer. -#define JS_FOR_EACH_PUBLIC_GC_POINTER_TYPE(D) \ - D(JS::Symbol*) \ - D(JS::BigInt*) \ - D(JSAtom*) \ - D(JSFunction*) \ - D(JSObject*) \ - D(JSScript*) \ - D(JSString*) - -// Expand the given macro D for each public tagged GC pointer type. -#define JS_FOR_EACH_PUBLIC_TAGGED_GC_POINTER_TYPE(D) \ - D(JS::Value) \ - D(JS::PropertyKey) // i.e. jsid - -#endif // GCTypeMacros_h Index: libraries/source/spidermonkey/include-win32-debug/js/GCVariant.h =================================================================== --- /dev/null +++ libraries/source/spidermonkey/include-win32-debug/js/GCVariant.h @@ -1,182 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- - * vim: set ts=8 sts=2 et sw=2 tw=80: - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef js_GCVariant_h -#define js_GCVariant_h - -#include "mozilla/Variant.h" - -#include - -#include "js/GCPolicyAPI.h" -#include "js/RootingAPI.h" -#include "js/TracingAPI.h" - -namespace JS { - -// These template specializations allow Variant to be used inside GC wrappers. -// -// When matching on GC wrappers around Variants, matching should be done on -// the wrapper itself. The matcher class's methods should take Handles or -// MutableHandles. For example, -// -// struct MyMatcher -// { -// using ReturnType = const char*; -// ReturnType match(HandleObject o) { return "object"; } -// ReturnType match(HandleScript s) { return "script"; } -// }; -// -// Rooted> v(cx, someScript); -// MyMatcher mm; -// v.match(mm); -// -// If you get compile errors about inability to upcast subclasses (e.g., from -// NativeObject* to JSObject*) and are inside js/src, be sure to also include -// "gc/Policy.h". - -namespace detail { - -template -struct GCVariantImplementation; - -// The base case. -template -struct GCVariantImplementation { - template - static void trace(JSTracer* trc, ConcreteVariant* v, const char* name) { - T& thing = v->template as(); - GCPolicy::trace(trc, &thing, name); - } - - template - static typename Matcher::ReturnType match(Matcher& matcher, - Handle v) { - const T& thing = v.get().template as(); - return matcher.match(Handle::fromMarkedLocation(&thing)); - } - - template - static typename Matcher::ReturnType match(Matcher& matcher, - MutableHandle v) { - T& thing = v.get().template as(); - return matcher.match(MutableHandle::fromMarkedLocation(&thing)); - } -}; - -// The inductive case. -template -struct GCVariantImplementation { - using Next = GCVariantImplementation; - - template - static void trace(JSTracer* trc, ConcreteVariant* v, const char* name) { - if (v->template is()) { - T& thing = v->template as(); - GCPolicy::trace(trc, &thing, name); - } else { - Next::trace(trc, v, name); - } - } - - template - static typename Matcher::ReturnType match(Matcher& matcher, - Handle v) { - if (v.get().template is()) { - const T& thing = v.get().template as(); - return matcher.match(Handle::fromMarkedLocation(&thing)); - } - return Next::match(matcher, v); - } - - template - static typename Matcher::ReturnType match(Matcher& matcher, - MutableHandle v) { - if (v.get().template is()) { - T& thing = v.get().template as(); - return matcher.match(MutableHandle::fromMarkedLocation(&thing)); - } - return Next::match(matcher, v); - } -}; - -} // namespace detail - -template -struct GCPolicy> { - using Impl = detail::GCVariantImplementation; - - static void trace(JSTracer* trc, mozilla::Variant* v, - const char* name) { - Impl::trace(trc, v, name); - } - - static bool isValid(const mozilla::Variant& v) { - return v.match([](auto& v) { - return GCPolicy>::isValid(v); - }); - } -}; - -} // namespace JS - -namespace js { - -template -class WrappedPtrOperations, Wrapper> { - using Impl = JS::detail::GCVariantImplementation; - using Variant = mozilla::Variant; - - const Variant& variant() const { - return static_cast(this)->get(); - } - - public: - template - bool is() const { - return variant().template is(); - } - - template - JS::Handle as() const { - return Handle::fromMarkedLocation(&variant().template as()); - } - - template - typename Matcher::ReturnType match(Matcher& matcher) const { - return Impl::match(matcher, - JS::Handle::fromMarkedLocation(&variant())); - } -}; - -template -class MutableWrappedPtrOperations, Wrapper> - : public WrappedPtrOperations, Wrapper> { - using Impl = JS::detail::GCVariantImplementation; - using Variant = mozilla::Variant; - - const Variant& variant() const { - return static_cast(this)->get(); - } - Variant& variant() { return static_cast(this)->get(); } - - public: - template - JS::MutableHandle as() { - return JS::MutableHandle::fromMarkedLocation( - &variant().template as()); - } - - template - typename Matcher::ReturnType match(Matcher& matcher) { - return Impl::match( - matcher, JS::MutableHandle::fromMarkedLocation(&variant())); - } -}; - -} // namespace js - -#endif // js_GCVariant_h Index: libraries/source/spidermonkey/include-win32-debug/js/GCVector.h =================================================================== --- /dev/null +++ libraries/source/spidermonkey/include-win32-debug/js/GCVector.h @@ -1,341 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- - * vim: set ts=8 sts=2 et sw=2 tw=80: - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef js_GCVector_h -#define js_GCVector_h - -#include "mozilla/Vector.h" - -#include "js/GCPolicyAPI.h" -#include "js/RootingAPI.h" -#include "js/TracingAPI.h" -#include "js/Vector.h" - -namespace JS { - -// A GCVector is a Vector with an additional trace method that knows how -// to visit all of the items stored in the Vector. For vectors that contain GC -// things, this is usually more convenient than manually iterating and marking -// the contents. -// -// Most types of GC pointers as keys and values can be traced with no extra -// infrastructure. For structs and non-gc-pointer members, ensure that there is -// a specialization of GCPolicy with an appropriate trace method available -// to handle the custom type. Generic helpers can be found in -// js/public/TracingAPI.h. -// -// Note that although this Vector's trace will deal correctly with moved items, -// it does not itself know when to barrier or trace items. To function properly -// it must either be used with Rooted, or barriered and traced manually. -template -class GCVector { - mozilla::Vector vector; - - public: - using ElementType = T; - - explicit GCVector(AllocPolicy alloc = AllocPolicy()) - : vector(std::move(alloc)) {} - - GCVector(GCVector&& vec) : vector(std::move(vec.vector)) {} - - GCVector& operator=(GCVector&& vec) { - vector = std::move(vec.vector); - return *this; - } - - size_t length() const { return vector.length(); } - bool empty() const { return vector.empty(); } - size_t capacity() const { return vector.capacity(); } - - T* begin() { return vector.begin(); } - const T* begin() const { return vector.begin(); } - - T* end() { return vector.end(); } - const T* end() const { return vector.end(); } - - T& operator[](size_t i) { return vector[i]; } - const T& operator[](size_t i) const { return vector[i]; } - - T& back() { return vector.back(); } - const T& back() const { return vector.back(); } - - bool initCapacity(size_t cap) { return vector.initCapacity(cap); } - MOZ_MUST_USE bool reserve(size_t req) { return vector.reserve(req); } - void shrinkBy(size_t amount) { return vector.shrinkBy(amount); } - MOZ_MUST_USE bool growBy(size_t amount) { return vector.growBy(amount); } - MOZ_MUST_USE bool resize(size_t newLen) { return vector.resize(newLen); } - - void clear() { return vector.clear(); } - void clearAndFree() { return vector.clearAndFree(); } - - template - bool append(U&& item) { - return vector.append(std::forward(item)); - } - - void erase(T* it) { vector.erase(it); } - void erase(T* begin, T* end) { vector.erase(begin, end); } - template - void eraseIf(Pred pred) { - vector.eraseIf(pred); - } - template - void eraseIfEqual(const U& u) { - vector.eraseIfEqual(u); - } - - template - MOZ_MUST_USE bool emplaceBack(Args&&... args) { - return vector.emplaceBack(std::forward(args)...); - } - - template - void infallibleAppend(U&& aU) { - return vector.infallibleAppend(std::forward(aU)); - } - void infallibleAppendN(const T& aT, size_t aN) { - return vector.infallibleAppendN(aT, aN); - } - template - void infallibleAppend(const U* aBegin, const U* aEnd) { - return vector.infallibleAppend(aBegin, aEnd); - } - template - void infallibleAppend(const U* aBegin, size_t aLength) { - return vector.infallibleAppend(aBegin, aLength); - } - - template - MOZ_MUST_USE bool appendAll(const U& aU) { - return vector.append(aU.begin(), aU.end()); - } - - MOZ_MUST_USE bool appendN(const T& val, size_t count) { - return vector.appendN(val, count); - } - - template - MOZ_MUST_USE bool append(const U* aBegin, const U* aEnd) { - return vector.append(aBegin, aEnd); - } - template - MOZ_MUST_USE bool append(const U* aBegin, size_t aLength) { - return vector.append(aBegin, aLength); - } - - void popBack() { return vector.popBack(); } - T popCopy() { return vector.popCopy(); } - - size_t sizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf) const { - return vector.sizeOfExcludingThis(mallocSizeOf); - } - - size_t sizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf) const { - return vector.sizeOfIncludingThis(mallocSizeOf); - } - - void trace(JSTracer* trc) { - for (auto& elem : vector) { - GCPolicy::trace(trc, &elem, "vector element"); - } - } - - bool needsSweep() const { return !this->empty(); } - - void sweep() { - T* src = begin(); - T* dst = begin(); - while (src != end()) { - if (!GCPolicy::needsSweep(src)) { - if (src != dst) { - *dst = std::move(*src); - } - dst++; - } - src++; - } - - MOZ_ASSERT(dst <= end()); - shrinkBy(end() - dst); - } -}; - -// AllocPolicy is optional. It has a default value declared in TypeDecls.h -template -class MOZ_STACK_CLASS StackGCVector : public GCVector { - public: - using Base = GCVector; - - private: - // Inherit constructor from GCVector. - using Base::Base; -}; - -} // namespace JS - -namespace js { - -template -class WrappedPtrOperations, Wrapper> { - using Vec = JS::GCVector; - const Vec& vec() const { return static_cast(this)->get(); } - - public: - const AllocPolicy& allocPolicy() const { return vec().allocPolicy(); } - size_t length() const { return vec().length(); } - bool empty() const { return vec().empty(); } - size_t capacity() const { return vec().capacity(); } - const T* begin() const { return vec().begin(); } - const T* end() const { return vec().end(); } - const T& back() const { return vec().back(); } - - JS::Handle operator[](size_t aIndex) const { - return JS::Handle::fromMarkedLocation(&vec().operator[](aIndex)); - } -}; - -template -class MutableWrappedPtrOperations, - Wrapper> - : public WrappedPtrOperations, - Wrapper> { - using Vec = JS::GCVector; - const Vec& vec() const { return static_cast(this)->get(); } - Vec& vec() { return static_cast(this)->get(); } - - public: - const AllocPolicy& allocPolicy() const { return vec().allocPolicy(); } - AllocPolicy& allocPolicy() { return vec().allocPolicy(); } - const T* begin() const { return vec().begin(); } - T* begin() { return vec().begin(); } - const T* end() const { return vec().end(); } - T* end() { return vec().end(); } - const T& back() const { return vec().back(); } - T& back() { return vec().back(); } - - JS::Handle operator[](size_t aIndex) const { - return JS::Handle::fromMarkedLocation(&vec().operator[](aIndex)); - } - JS::MutableHandle operator[](size_t aIndex) { - return JS::MutableHandle::fromMarkedLocation(&vec().operator[](aIndex)); - } - - MOZ_MUST_USE bool initCapacity(size_t aRequest) { - return vec().initCapacity(aRequest); - } - MOZ_MUST_USE bool reserve(size_t aRequest) { return vec().reserve(aRequest); } - void shrinkBy(size_t aIncr) { vec().shrinkBy(aIncr); } - MOZ_MUST_USE bool growBy(size_t aIncr) { return vec().growBy(aIncr); } - MOZ_MUST_USE bool resize(size_t aNewLength) { - return vec().resize(aNewLength); - } - MOZ_MUST_USE bool growByUninitialized(size_t aIncr) { - return vec().growByUninitialized(aIncr); - } - void infallibleGrowByUninitialized(size_t aIncr) { - vec().infallibleGrowByUninitialized(aIncr); - } - MOZ_MUST_USE bool resizeUninitialized(size_t aNewLength) { - return vec().resizeUninitialized(aNewLength); - } - void clear() { vec().clear(); } - void clearAndFree() { vec().clearAndFree(); } - template - MOZ_MUST_USE bool append(U&& aU) { - return vec().append(std::forward(aU)); - } - template - MOZ_MUST_USE bool emplaceBack(Args&&... aArgs) { - return vec().emplaceBack(std::forward(aArgs)...); - } - template - MOZ_MUST_USE bool appendAll(const U& aU) { - return vec().appendAll(aU); - } - MOZ_MUST_USE bool appendN(const T& aT, size_t aN) { - return vec().appendN(aT, aN); - } - template - MOZ_MUST_USE bool append(const U* aBegin, const U* aEnd) { - return vec().append(aBegin, aEnd); - } - template - MOZ_MUST_USE bool append(const U* aBegin, size_t aLength) { - return vec().append(aBegin, aLength); - } - template - void infallibleAppend(U&& aU) { - vec().infallibleAppend(std::forward(aU)); - } - void infallibleAppendN(const T& aT, size_t aN) { - vec().infallibleAppendN(aT, aN); - } - template - void infallibleAppend(const U* aBegin, const U* aEnd) { - vec().infallibleAppend(aBegin, aEnd); - } - template - void infallibleAppend(const U* aBegin, size_t aLength) { - vec().infallibleAppend(aBegin, aLength); - } - void popBack() { vec().popBack(); } - T popCopy() { return vec().popCopy(); } - template - T* insert(T* aP, U&& aVal) { - return vec().insert(aP, std::forward(aVal)); - } - void erase(T* aT) { vec().erase(aT); } - void erase(T* aBegin, T* aEnd) { vec().erase(aBegin, aEnd); } - template - void eraseIf(Pred pred) { - vec().eraseIf(pred); - } - template - void eraseIfEqual(const U& u) { - vec().eraseIfEqual(u); - } -}; - -template -class WrappedPtrOperations, Wrapper> - : public WrappedPtrOperations< - typename JS::StackGCVector::Base, Wrapper> {}; - -template -class MutableWrappedPtrOperations, Wrapper> - : public MutableWrappedPtrOperations< - typename JS::StackGCVector::Base, Wrapper> {}; - -} // namespace js - -namespace JS { - -// An automatically rooted GCVector for stack use. -template -class RootedVector : public Rooted> { - using Vec = StackGCVector; - using Base = Rooted; - - public: - explicit RootedVector(JSContext* cx) : Base(cx, Vec(cx)) {} -}; - -// For use in rust code, an analog to RootedVector that doesn't require -// instances to be destroyed in LIFO order. -template -class PersistentRootedVector : public PersistentRooted> { - using Vec = StackGCVector; - using Base = PersistentRooted; - - public: - explicit PersistentRootedVector(JSContext* cx) : Base(cx, Vec(cx)) {} -}; - -} // namespace JS - -#endif // js_GCVector_h Index: libraries/source/spidermonkey/include-win32-debug/js/HashTable.h =================================================================== --- /dev/null +++ libraries/source/spidermonkey/include-win32-debug/js/HashTable.h @@ -1,38 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- - * vim: set ts=8 sts=2 et sw=2 tw=80: - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef js_HashTable_h -#define js_HashTable_h - -#include "mozilla/HashTable.h" - -#include "jstypes.h" - -namespace js { - -using HashNumber = mozilla::HashNumber; -static const uint32_t kHashNumberBits = mozilla::kHashNumberBits; - -class JS_PUBLIC_API TempAllocPolicy; - -template -using DefaultHasher = mozilla::DefaultHasher; - -template -using PointerHasher = mozilla::PointerHasher; - -template , - class AllocPolicy = TempAllocPolicy> -using HashSet = mozilla::HashSet; - -template , - class AllocPolicy = TempAllocPolicy> -using HashMap = mozilla::HashMap; - -} // namespace js - -#endif /* js_HashTable_h */ Index: libraries/source/spidermonkey/include-win32-debug/js/HeapAPI.h =================================================================== --- /dev/null +++ libraries/source/spidermonkey/include-win32-debug/js/HeapAPI.h @@ -1,725 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- - * vim: set ts=8 sts=2 et sw=2 tw=80: - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef js_HeapAPI_h -#define js_HeapAPI_h - -#include -#include - -#include "jspubtd.h" - -#include "js/GCAnnotations.h" -#include "js/TraceKind.h" -#include "js/Utility.h" - -#ifndef JS_BITS_PER_WORD -# error \ - "JS_BITS_PER_WORD must be defined. Did you forget to include js-config.h?" -#endif - -struct JSExternalStringCallbacks; - -/* These values are private to the JS engine. */ -namespace js { - -JS_FRIEND_API bool CurrentThreadCanAccessZone(JS::Zone* zone); - -namespace gc { - -struct Cell; - -const size_t ArenaShift = 12; -const size_t ArenaSize = size_t(1) << ArenaShift; -const size_t ArenaMask = ArenaSize - 1; - -#ifdef JS_GC_SMALL_CHUNK_SIZE -const size_t ChunkShift = 18; -#else -const size_t ChunkShift = 20; -#endif -const size_t ChunkSize = size_t(1) << ChunkShift; -const size_t ChunkMask = ChunkSize - 1; - -const size_t CellAlignShift = 3; -const size_t CellAlignBytes = size_t(1) << CellAlignShift; -const size_t CellAlignMask = CellAlignBytes - 1; - -const size_t CellBytesPerMarkBit = CellAlignBytes; - -/* - * We sometimes use an index to refer to a cell in an arena. The index for a - * cell is found by dividing by the cell alignment so not all indicies refer to - * valid cells. - */ -const size_t ArenaCellIndexBytes = CellAlignBytes; -const size_t MaxArenaCellIndex = ArenaSize / CellAlignBytes; - -/* These are magic constants derived from actual offsets in gc/Heap.h. */ -#ifdef JS_GC_SMALL_CHUNK_SIZE -const size_t ChunkMarkBitmapOffset = 258104; -const size_t ChunkMarkBitmapBits = 31744; -#else -const size_t ChunkMarkBitmapOffset = 1032352; -const size_t ChunkMarkBitmapBits = 129024; -#endif -const size_t ChunkRuntimeOffset = ChunkSize - sizeof(void*); -const size_t ChunkTrailerSize = 2 * sizeof(uintptr_t) + sizeof(uint64_t); -const size_t ChunkLocationOffset = ChunkSize - ChunkTrailerSize; -const size_t ChunkStoreBufferOffset = - ChunkSize - ChunkTrailerSize + sizeof(uint64_t); -const size_t ArenaZoneOffset = sizeof(size_t); -const size_t ArenaHeaderSize = - sizeof(size_t) + 2 * sizeof(uintptr_t) + sizeof(size_t) + sizeof(uintptr_t); - -// The first word of a GC thing has certain requirements from the GC and is used -// to store flags in the low bits. -const size_t CellFlagBitsReservedForGC = 3; - -// The first word can be used to store JSClass pointers for some thing kinds, so -// these must be suitably aligned. -const size_t JSClassAlignBytes = size_t(1) << CellFlagBitsReservedForGC; - -/* - * Live objects are marked black or gray. Everything reachable from a JS root is - * marked black. Objects marked gray are eligible for cycle collection. - * - * BlackBit: GrayOrBlackBit: Color: - * 0 0 white - * 0 1 gray - * 1 0 black - * 1 1 black - */ -enum class ColorBit : uint32_t { BlackBit = 0, GrayOrBlackBit = 1 }; - -/* - * The "location" field in the Chunk trailer is a enum indicating various roles - * of the chunk. - */ -enum class ChunkLocation : uint32_t { - Invalid = 0, - Nursery = 1, - TenuredHeap = 2 -}; - -#ifdef JS_DEBUG -/* When downcasting, ensure we are actually the right type. */ -extern JS_FRIEND_API void AssertGCThingHasType(js::gc::Cell* cell, - JS::TraceKind kind); -#else -inline void AssertGCThingHasType(js::gc::Cell* cell, JS::TraceKind kind) {} -#endif - -MOZ_ALWAYS_INLINE bool IsInsideNursery(const js::gc::Cell* cell); - -} /* namespace gc */ -} /* namespace js */ - -namespace JS { - -enum class HeapState { - Idle, // doing nothing with the GC heap - Tracing, // tracing the GC heap without collecting, e.g. - // IterateCompartments() - MajorCollecting, // doing a GC of the major heap - MinorCollecting, // doing a GC of the minor heap (nursery) - CycleCollecting // in the "Unlink" phase of cycle collection -}; - -JS_PUBLIC_API HeapState RuntimeHeapState(); - -static inline bool RuntimeHeapIsBusy() { - return RuntimeHeapState() != HeapState::Idle; -} - -static inline bool RuntimeHeapIsTracing() { - return RuntimeHeapState() == HeapState::Tracing; -} - -static inline bool RuntimeHeapIsMajorCollecting() { - return RuntimeHeapState() == HeapState::MajorCollecting; -} - -static inline bool RuntimeHeapIsMinorCollecting() { - return RuntimeHeapState() == HeapState::MinorCollecting; -} - -static inline bool RuntimeHeapIsCollecting(HeapState state) { - return state == HeapState::MajorCollecting || - state == HeapState::MinorCollecting; -} - -static inline bool RuntimeHeapIsCollecting() { - return RuntimeHeapIsCollecting(RuntimeHeapState()); -} - -static inline bool RuntimeHeapIsCycleCollecting() { - return RuntimeHeapState() == HeapState::CycleCollecting; -} - -/* - * This list enumerates the different types of conceptual stacks we have in - * SpiderMonkey. In reality, they all share the C stack, but we allow different - * stack limits depending on the type of code running. - */ -enum StackKind { - StackForSystemCode, // C++, such as the GC, running on behalf of the VM. - StackForTrustedScript, // Script running with trusted principals. - StackForUntrustedScript, // Script running with untrusted principals. - StackKindCount -}; - -/* - * Default maximum size for the generational nursery in bytes. This is the - * initial value. In the browser this configured by the - * javascript.options.mem.nursery.max_kb pref. - */ -const uint32_t DefaultNurseryMaxBytes = 16 * js::gc::ChunkSize; - -/* Default maximum heap size in bytes to pass to JS_NewContext(). */ -const uint32_t DefaultHeapMaxBytes = 32 * 1024 * 1024; - -namespace shadow { - -struct Zone { - enum GCState : uint8_t { - NoGC, - MarkBlackOnly, - MarkBlackAndGray, - Sweep, - Finished, - Compact - }; - - protected: - JSRuntime* const runtime_; - JSTracer* const barrierTracer_; // A pointer to the JSRuntime's |gcMarker|. - uint32_t needsIncrementalBarrier_; - GCState gcState_; - - Zone(JSRuntime* runtime, JSTracer* barrierTracerArg) - : runtime_(runtime), - barrierTracer_(barrierTracerArg), - needsIncrementalBarrier_(0), - gcState_(NoGC) {} - - public: - bool needsIncrementalBarrier() const { return needsIncrementalBarrier_; } - - JSTracer* barrierTracer() { - MOZ_ASSERT(needsIncrementalBarrier_); - MOZ_ASSERT(js::CurrentThreadCanAccessRuntime(runtime_)); - return barrierTracer_; - } - - JSRuntime* runtimeFromMainThread() const { - MOZ_ASSERT(js::CurrentThreadCanAccessRuntime(runtime_)); - return runtime_; - } - - // Note: Unrestricted access to the zone's runtime from an arbitrary - // thread can easily lead to races. Use this method very carefully. - JSRuntime* runtimeFromAnyThread() const { return runtime_; } - - GCState gcState() const { return gcState_; } - bool wasGCStarted() const { return gcState_ != NoGC; } - bool isGCMarkingBlackOnly() const { return gcState_ == MarkBlackOnly; } - bool isGCMarkingBlackAndGray() const { return gcState_ == MarkBlackAndGray; } - bool isGCSweeping() const { return gcState_ == Sweep; } - bool isGCFinished() const { return gcState_ == Finished; } - bool isGCCompacting() const { return gcState_ == Compact; } - bool isGCMarking() const { - return isGCMarkingBlackOnly() || isGCMarkingBlackAndGray(); - } - bool isGCSweepingOrCompacting() const { - return gcState_ == Sweep || gcState_ == Compact; - } - - static MOZ_ALWAYS_INLINE JS::shadow::Zone* from(JS::Zone* zone) { - return reinterpret_cast(zone); - } -}; - -struct String { - static const uint32_t ATOM_BIT = js::Bit(3); - static const uint32_t LINEAR_BIT = js::Bit(4); - static const uint32_t INLINE_CHARS_BIT = js::Bit(6); - static const uint32_t LATIN1_CHARS_BIT = js::Bit(9); - static const uint32_t EXTERNAL_FLAGS = LINEAR_BIT | js::Bit(8); - static const uint32_t TYPE_FLAGS_MASK = js::BitMask(9) - js::BitMask(3); - static const uint32_t PERMANENT_ATOM_MASK = ATOM_BIT | js::Bit(8); - - uintptr_t flags_; -#if JS_BITS_PER_WORD == 32 - uint32_t length_; -#endif - - union { - const JS::Latin1Char* nonInlineCharsLatin1; - const char16_t* nonInlineCharsTwoByte; - JS::Latin1Char inlineStorageLatin1[1]; - char16_t inlineStorageTwoByte[1]; - }; - const JSExternalStringCallbacks* externalCallbacks; - - inline uint32_t flags() const { return uint32_t(flags_); } - inline uint32_t length() const { -#if JS_BITS_PER_WORD == 32 - return length_; -#else - return uint32_t(flags_ >> 32); -#endif - } - - static bool isPermanentAtom(const js::gc::Cell* cell) { - uint32_t flags = reinterpret_cast(cell)->flags(); - return (flags & PERMANENT_ATOM_MASK) == PERMANENT_ATOM_MASK; - } -}; - -struct Symbol { - void* _1; - uint32_t code_; - static const uint32_t WellKnownAPILimit = 0x80000000; - - static bool isWellKnownSymbol(const js::gc::Cell* cell) { - return reinterpret_cast(cell)->code_ < WellKnownAPILimit; - } -}; - -} /* namespace shadow */ - -/** - * A GC pointer, tagged with the trace kind. - * - * In general, a GC pointer should be stored with an exact type. This class - * is for use when that is not possible because a single pointer must point - * to several kinds of GC thing. - */ -class JS_FRIEND_API GCCellPtr { - public: - GCCellPtr() : GCCellPtr(nullptr) {} - - // Construction from a void* and trace kind. - GCCellPtr(void* gcthing, JS::TraceKind traceKind) - : ptr(checkedCast(gcthing, traceKind)) {} - - // Automatically construct a null GCCellPtr from nullptr. - MOZ_IMPLICIT GCCellPtr(decltype(nullptr)) - : ptr(checkedCast(nullptr, JS::TraceKind::Null)) {} - - // Construction from an explicit type. - template - explicit GCCellPtr(T* p) - : ptr(checkedCast(p, JS::MapTypeToTraceKind::kind)) {} - explicit GCCellPtr(JSFunction* p) - : ptr(checkedCast(p, JS::TraceKind::Object)) {} - explicit GCCellPtr(JSScript* p) - : ptr(checkedCast(p, JS::TraceKind::Script)) {} - explicit GCCellPtr(const Value& v); - - JS::TraceKind kind() const { - JS::TraceKind traceKind = JS::TraceKind(ptr & OutOfLineTraceKindMask); - if (uintptr_t(traceKind) != OutOfLineTraceKindMask) { - return traceKind; - } - return outOfLineKind(); - } - - // Allow GCCellPtr to be used in a boolean context. - explicit operator bool() const { - MOZ_ASSERT(bool(asCell()) == (kind() != JS::TraceKind::Null)); - return asCell(); - } - - // Simplify checks to the kind. - template >> - bool is() const { - return kind() == JS::MapTypeToTraceKind::kind; - } - - // Conversions to more specific types must match the kind. Access to - // further refined types is not allowed directly from a GCCellPtr. - template >> - T& as() const { - MOZ_ASSERT(kind() == JS::MapTypeToTraceKind::kind); - // We can't use static_cast here, because the fact that JSObject - // inherits from js::gc::Cell is not part of the public API. - return *reinterpret_cast(asCell()); - } - - // Return a pointer to the cell this |GCCellPtr| refers to, or |nullptr|. - // (It would be more symmetrical with |to| for this to return a |Cell&|, but - // the result can be |nullptr|, and null references are undefined behavior.) - js::gc::Cell* asCell() const { - return reinterpret_cast(ptr & ~OutOfLineTraceKindMask); - } - - // The CC's trace logger needs an identity that is XPIDL serializable. - uint64_t unsafeAsInteger() const { - return static_cast(unsafeAsUIntPtr()); - } - // Inline mark bitmap access requires direct pointer arithmetic. - uintptr_t unsafeAsUIntPtr() const { - MOZ_ASSERT(asCell()); - MOZ_ASSERT(!js::gc::IsInsideNursery(asCell())); - return reinterpret_cast(asCell()); - } - - MOZ_ALWAYS_INLINE bool mayBeOwnedByOtherRuntime() const { - if (!is() && !is()) { - return false; - } - if (is()) { - return JS::shadow::String::isPermanentAtom(asCell()); - } - MOZ_ASSERT(is()); - return JS::shadow::Symbol::isWellKnownSymbol(asCell()); - } - - private: - static uintptr_t checkedCast(void* p, JS::TraceKind traceKind) { - js::gc::Cell* cell = static_cast(p); - MOZ_ASSERT((uintptr_t(p) & OutOfLineTraceKindMask) == 0); - AssertGCThingHasType(cell, traceKind); - // Note: the OutOfLineTraceKindMask bits are set on all out-of-line kinds - // so that we can mask instead of branching. - MOZ_ASSERT_IF(uintptr_t(traceKind) >= OutOfLineTraceKindMask, - (uintptr_t(traceKind) & OutOfLineTraceKindMask) == - OutOfLineTraceKindMask); - return uintptr_t(p) | (uintptr_t(traceKind) & OutOfLineTraceKindMask); - } - - JS::TraceKind outOfLineKind() const; - - uintptr_t ptr; -} JS_HAZ_GC_POINTER; - -// Unwraps the given GCCellPtr, calls the functor |f| with a template argument -// of the actual type of the pointer, and returns the result. -template -auto MapGCThingTyped(GCCellPtr thing, F&& f) { - switch (thing.kind()) { -#define JS_EXPAND_DEF(name, type, _, _1) \ - case JS::TraceKind::name: \ - return f(&thing.as()); - JS_FOR_EACH_TRACEKIND(JS_EXPAND_DEF); -#undef JS_EXPAND_DEF - default: - MOZ_CRASH("Invalid trace kind in MapGCThingTyped for GCCellPtr."); - } -} - -// Unwraps the given GCCellPtr and calls the functor |f| with a template -// argument of the actual type of the pointer. Doesn't return anything. -template -void ApplyGCThingTyped(GCCellPtr thing, F&& f) { - // This function doesn't do anything but is supplied for symmetry with other - // MapGCThingTyped/ApplyGCThingTyped implementations that have to wrap the - // functor to return a dummy value that is ignored. - MapGCThingTyped(thing, f); -} - -} /* namespace JS */ - -// These are defined in the toplevel namespace instead of within JS so that -// they won't shadow other operator== overloads (see bug 1456512.) - -inline bool operator==(const JS::GCCellPtr& ptr1, const JS::GCCellPtr& ptr2) { - return ptr1.asCell() == ptr2.asCell(); -} - -inline bool operator!=(const JS::GCCellPtr& ptr1, const JS::GCCellPtr& ptr2) { - return !(ptr1 == ptr2); -} - -namespace js { -namespace gc { -namespace detail { - -static MOZ_ALWAYS_INLINE uintptr_t* GetGCThingMarkBitmap(const uintptr_t addr) { - // Note: the JIT pre-barrier trampolines inline this code. Update that - // code too when making changes here! - MOZ_ASSERT(addr); - const uintptr_t bmap_addr = (addr & ~ChunkMask) | ChunkMarkBitmapOffset; - return reinterpret_cast(bmap_addr); -} - -static MOZ_ALWAYS_INLINE void GetGCThingMarkWordAndMask(const uintptr_t addr, - ColorBit colorBit, - uintptr_t** wordp, - uintptr_t* maskp) { - // Note: the JIT pre-barrier trampolines inline this code. Update that - // code too when making changes here! - MOZ_ASSERT(addr); - const size_t bit = (addr & js::gc::ChunkMask) / js::gc::CellBytesPerMarkBit + - static_cast(colorBit); - MOZ_ASSERT(bit < js::gc::ChunkMarkBitmapBits); - uintptr_t* bitmap = GetGCThingMarkBitmap(addr); - const uintptr_t nbits = sizeof(*bitmap) * CHAR_BIT; - *maskp = uintptr_t(1) << (bit % nbits); - *wordp = &bitmap[bit / nbits]; -} - -static MOZ_ALWAYS_INLINE JS::Zone* GetTenuredGCThingZone(const uintptr_t addr) { - MOZ_ASSERT(addr); - const uintptr_t zone_addr = (addr & ~ArenaMask) | ArenaZoneOffset; - return *reinterpret_cast(zone_addr); -} - -static MOZ_ALWAYS_INLINE bool TenuredCellIsMarkedGray(const Cell* cell) { - // Return true if GrayOrBlackBit is set and BlackBit is not set. - MOZ_ASSERT(cell); - MOZ_ASSERT(!js::gc::IsInsideNursery(cell)); - - uintptr_t *grayWord, grayMask; - js::gc::detail::GetGCThingMarkWordAndMask( - uintptr_t(cell), js::gc::ColorBit::GrayOrBlackBit, &grayWord, &grayMask); - if (!(*grayWord & grayMask)) { - return false; - } - - uintptr_t *blackWord, blackMask; - js::gc::detail::GetGCThingMarkWordAndMask( - uintptr_t(cell), js::gc::ColorBit::BlackBit, &blackWord, &blackMask); - return !(*blackWord & blackMask); -} - -static MOZ_ALWAYS_INLINE bool CellIsMarkedGray(const Cell* cell) { - MOZ_ASSERT(cell); - if (js::gc::IsInsideNursery(cell)) { - return false; - } - return TenuredCellIsMarkedGray(cell); -} - -extern JS_PUBLIC_API bool CellIsMarkedGrayIfKnown(const Cell* cell); - -#ifdef DEBUG -extern JS_PUBLIC_API void AssertCellIsNotGray(const Cell* cell); - -extern JS_PUBLIC_API bool ObjectIsMarkedBlack(const JSObject* obj); -#endif - -MOZ_ALWAYS_INLINE ChunkLocation GetCellLocation(const void* cell) { - uintptr_t addr = uintptr_t(cell); - addr &= ~js::gc::ChunkMask; - addr |= js::gc::ChunkLocationOffset; - return *reinterpret_cast(addr); -} - -MOZ_ALWAYS_INLINE bool NurseryCellHasStoreBuffer(const void* cell) { - uintptr_t addr = uintptr_t(cell); - addr &= ~js::gc::ChunkMask; - addr |= js::gc::ChunkStoreBufferOffset; - return *reinterpret_cast(addr) != nullptr; -} - -} /* namespace detail */ - -MOZ_ALWAYS_INLINE bool IsInsideNursery(const Cell* cell) { - if (!cell) { - return false; - } - auto location = detail::GetCellLocation(cell); - MOZ_ASSERT(location == ChunkLocation::Nursery || - location == ChunkLocation::TenuredHeap); - return location == ChunkLocation::Nursery; -} - -// Allow use before the compiler knows the derivation of JSObject, JSString, and -// JS::BigInt. -MOZ_ALWAYS_INLINE bool IsInsideNursery(const JSObject* obj) { - return IsInsideNursery(reinterpret_cast(obj)); -} -MOZ_ALWAYS_INLINE bool IsInsideNursery(const JSString* str) { - return IsInsideNursery(reinterpret_cast(str)); -} -MOZ_ALWAYS_INLINE bool IsInsideNursery(const JS::BigInt* bi) { - return IsInsideNursery(reinterpret_cast(bi)); -} - -MOZ_ALWAYS_INLINE bool IsCellPointerValid(const void* cell) { - auto addr = uintptr_t(cell); - if (addr < ChunkSize || addr % CellAlignBytes != 0) { - return false; - } - auto location = detail::GetCellLocation(cell); - if (location == ChunkLocation::TenuredHeap) { - return !!detail::GetTenuredGCThingZone(addr); - } - if (location == ChunkLocation::Nursery) { - return detail::NurseryCellHasStoreBuffer(cell); - } - return false; -} - -MOZ_ALWAYS_INLINE bool IsCellPointerValidOrNull(const void* cell) { - if (!cell) { - return true; - } - return IsCellPointerValid(cell); -} - -} /* namespace gc */ -} /* namespace js */ - -namespace JS { - -static MOZ_ALWAYS_INLINE Zone* GetTenuredGCThingZone(GCCellPtr thing) { - MOZ_ASSERT(!js::gc::IsInsideNursery(thing.asCell())); - return js::gc::detail::GetTenuredGCThingZone(thing.unsafeAsUIntPtr()); -} - -extern JS_PUBLIC_API Zone* GetNurseryCellZone(js::gc::Cell* cell); - -static MOZ_ALWAYS_INLINE Zone* GetGCThingZone(GCCellPtr thing) { - if (!js::gc::IsInsideNursery(thing.asCell())) { - return js::gc::detail::GetTenuredGCThingZone(thing.unsafeAsUIntPtr()); - } - - return GetNurseryCellZone(thing.asCell()); -} - -static MOZ_ALWAYS_INLINE Zone* GetStringZone(JSString* str) { - if (!js::gc::IsInsideNursery(str)) { - return js::gc::detail::GetTenuredGCThingZone( - reinterpret_cast(str)); - } - return GetNurseryCellZone(reinterpret_cast(str)); -} - -extern JS_PUBLIC_API Zone* GetObjectZone(JSObject* obj); - -static MOZ_ALWAYS_INLINE bool GCThingIsMarkedGray(GCCellPtr thing) { - if (thing.mayBeOwnedByOtherRuntime()) { - return false; - } - return js::gc::detail::CellIsMarkedGrayIfKnown(thing.asCell()); -} - -extern JS_PUBLIC_API JS::TraceKind GCThingTraceKind(void* thing); - -extern JS_PUBLIC_API void EnableNurseryStrings(JSContext* cx); - -extern JS_PUBLIC_API void DisableNurseryStrings(JSContext* cx); - -extern JS_PUBLIC_API void EnableNurseryBigInts(JSContext* cx); - -extern JS_PUBLIC_API void DisableNurseryBigInts(JSContext* cx); - -/* - * Returns true when writes to GC thing pointers (and reads from weak pointers) - * must call an incremental barrier. This is generally only true when running - * mutator code in-between GC slices. At other times, the barrier may be elided - * for performance. - */ -extern JS_PUBLIC_API bool IsIncrementalBarrierNeeded(JSContext* cx); - -/* - * Notify the GC that a reference to a JSObject is about to be overwritten. - * This method must be called if IsIncrementalBarrierNeeded. - */ -extern JS_PUBLIC_API void IncrementalPreWriteBarrier(JSObject* obj); - -/* - * Notify the GC that a reference to a tenured GC cell is about to be - * overwritten. This method must be called if IsIncrementalBarrierNeeded. - */ -extern JS_PUBLIC_API void IncrementalPreWriteBarrier(GCCellPtr thing); - -/** - * Unsets the gray bit for anything reachable from |thing|. |kind| should not be - * JS::TraceKind::Shape. |thing| should be non-null. The return value indicates - * if anything was unmarked. - */ -extern JS_FRIEND_API bool UnmarkGrayGCThingRecursively(GCCellPtr thing); - -} // namespace JS - -namespace js { -namespace gc { - -extern JS_PUBLIC_API void PerformIncrementalReadBarrier(JS::GCCellPtr thing); - -static MOZ_ALWAYS_INLINE bool IsIncrementalBarrierNeededOnTenuredGCThing( - const JS::GCCellPtr thing) { - MOZ_ASSERT(thing); - MOZ_ASSERT(!js::gc::IsInsideNursery(thing.asCell())); - - // TODO: I'd like to assert !RuntimeHeapIsBusy() here but this gets - // called while we are tracing the heap, e.g. during memory reporting - // (see bug 1313318). - MOZ_ASSERT(!JS::RuntimeHeapIsCollecting()); - - JS::Zone* zone = JS::GetTenuredGCThingZone(thing); - return JS::shadow::Zone::from(zone)->needsIncrementalBarrier(); -} - -static MOZ_ALWAYS_INLINE void ExposeGCThingToActiveJS(JS::GCCellPtr thing) { - // GC things residing in the nursery cannot be gray: they have no mark bits. - // All live objects in the nursery are moved to tenured at the beginning of - // each GC slice, so the gray marker never sees nursery things. - if (IsInsideNursery(thing.asCell())) { - return; - } - - // There's nothing to do for permanent GC things that might be owned by - // another runtime. - if (thing.mayBeOwnedByOtherRuntime()) { - return; - } - - if (IsIncrementalBarrierNeededOnTenuredGCThing(thing)) { - PerformIncrementalReadBarrier(thing); - } else if (detail::TenuredCellIsMarkedGray(thing.asCell())) { - JS::UnmarkGrayGCThingRecursively(thing); - } - - MOZ_ASSERT(!detail::TenuredCellIsMarkedGray(thing.asCell())); -} - -template -extern JS_PUBLIC_API bool EdgeNeedsSweepUnbarrieredSlow(T* thingp); - -static MOZ_ALWAYS_INLINE bool EdgeNeedsSweepUnbarriered(JSObject** objp) { - // This function does not handle updating nursery pointers. Raw JSObject - // pointers should be updated separately or replaced with - // JS::Heap which handles this automatically. - MOZ_ASSERT(!JS::RuntimeHeapIsMinorCollecting()); - if (IsInsideNursery(*objp)) { - return false; - } - - auto zone = - JS::shadow::Zone::from(detail::GetTenuredGCThingZone(uintptr_t(*objp))); - if (!zone->isGCSweepingOrCompacting()) { - return false; - } - - return EdgeNeedsSweepUnbarrieredSlow(objp); -} - -} // namespace gc -} // namespace js - -namespace JS { - -/* - * This should be called when an object that is marked gray is exposed to the JS - * engine (by handing it to running JS code or writing it into live JS - * data). During incremental GC, since the gray bits haven't been computed yet, - * we conservatively mark the object black. - */ -static MOZ_ALWAYS_INLINE void ExposeObjectToActiveJS(JSObject* obj) { - MOZ_ASSERT(obj); - MOZ_ASSERT(!js::gc::EdgeNeedsSweepUnbarrieredSlow(&obj)); - js::gc::ExposeGCThingToActiveJS(GCCellPtr(obj)); -} - -} /* namespace JS */ - -#endif /* js_HeapAPI_h */ Index: libraries/source/spidermonkey/include-win32-debug/js/Id.h =================================================================== --- /dev/null +++ libraries/source/spidermonkey/include-win32-debug/js/Id.h @@ -1,313 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- - * vim: set ts=8 sts=2 et sw=2 tw=80: - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef js_Id_h -#define js_Id_h - -// [SMDOC] Property Key / JSID -// -// A jsid is an identifier for a property or method of an object which is -// either a 31-bit unsigned integer, interned string or symbol. -// -// Also, there is an additional jsid value, JSID_VOID, which does not occur in -// JS scripts but may be used to indicate the absence of a valid jsid. A void -// jsid is not a valid id and only arises as an exceptional API return value, -// such as in JS_NextProperty. Embeddings must not pass JSID_VOID into JSAPI -// entry points expecting a jsid and do not need to handle JSID_VOID in hooks -// receiving a jsid except when explicitly noted in the API contract. -// -// A jsid is not implicitly convertible to or from a Value; JS_ValueToId or -// JS_IdToValue must be used instead. - -#include "mozilla/Maybe.h" - -#include "jstypes.h" - -#include "js/HeapAPI.h" -#include "js/RootingAPI.h" -#include "js/TypeDecls.h" -#include "js/Utility.h" - -// All jsids with the low bit set are integer ids. This means the other type -// tags must all be even. -#define JSID_TYPE_INT_BIT 0x1 - -// Use 0 for JSID_TYPE_STRING to avoid a bitwise op for atom <-> id conversions. -#define JSID_TYPE_STRING 0x0 -#define JSID_TYPE_VOID 0x2 -#define JSID_TYPE_SYMBOL 0x4 -#define JSID_TYPE_EMPTY 0x6 -#define JSID_TYPE_MASK 0x7 - -namespace JS { - -enum class SymbolCode : uint32_t; - -struct PropertyKey { - size_t asBits; - - constexpr PropertyKey() : asBits(JSID_TYPE_VOID) {} - - static constexpr MOZ_ALWAYS_INLINE PropertyKey fromRawBits(size_t bits) { - PropertyKey id; - id.asBits = bits; - return id; - } - - bool operator==(const PropertyKey& rhs) const { return asBits == rhs.asBits; } - bool operator!=(const PropertyKey& rhs) const { return asBits != rhs.asBits; } - - MOZ_ALWAYS_INLINE bool isInt() const { - return !!(asBits & JSID_TYPE_INT_BIT); - } - - MOZ_ALWAYS_INLINE bool isString() const { - return (asBits & JSID_TYPE_MASK) == JSID_TYPE_STRING; - } - - MOZ_ALWAYS_INLINE bool isSymbol() const { - return (asBits & JSID_TYPE_MASK) == JSID_TYPE_SYMBOL; - } - - MOZ_ALWAYS_INLINE bool isGCThing() const { return isString() || isSymbol(); } - - MOZ_ALWAYS_INLINE int32_t toInt() const { - MOZ_ASSERT(isInt()); - uint32_t bits = static_cast(asBits) >> 1; - return static_cast(bits); - } - - MOZ_ALWAYS_INLINE JSString* toString() const { - MOZ_ASSERT(isString()); - // Use XOR instead of `& ~JSID_TYPE_MASK` because small immediates can be - // encoded more efficiently on some platorms. - return reinterpret_cast(asBits ^ JSID_TYPE_STRING); - } - - MOZ_ALWAYS_INLINE JS::Symbol* toSymbol() const { - MOZ_ASSERT(isSymbol()); - return reinterpret_cast(asBits ^ JSID_TYPE_SYMBOL); - } - - GCCellPtr toGCCellPtr() const { - void* thing = (void*)(asBits & ~(size_t)JSID_TYPE_MASK); - if (isString()) { - return JS::GCCellPtr(thing, JS::TraceKind::String); - } - MOZ_ASSERT(isSymbol()); - return JS::GCCellPtr(thing, JS::TraceKind::Symbol); - } - - bool isWellKnownSymbol(JS::SymbolCode code) const; - - // This API can be used by embedders to convert pinned (aka interned) strings, - // as created by JS_AtomizeAndPinJSString, into PropertyKeys. - // This means the string does not have to be explicitly rooted. - // - // Only use this API when absolutely necessary, otherwise use JS_StringToId. - static PropertyKey fromPinnedString(JSString* str); - - // Must not be used on atoms that are representable as integer PropertyKey. - // Prefer NameToId or AtomToId over this function: - // - // A PropertyName is an atom that does not contain an integer in the range - // [0, UINT32_MAX]. However, PropertyKey can only hold an integer in the range - // [0, JSID_INT_MAX] (where JSID_INT_MAX == 2^31-1). Thus, for the range of - // integers (JSID_INT_MAX, UINT32_MAX], to represent as a 'id', it must be - // the case id.isString() and id.toString()->isIndex(). In most - // cases when creating a PropertyKey, code does not have to care about - // this corner case because: - // - // - When given an arbitrary JSAtom*, AtomToId must be used, which checks for - // integer atoms representable as integer PropertyKey, and does this - // conversion. - // - // - When given a PropertyName*, NameToId can be used which does not need - // to do any dynamic checks. - // - // Thus, it is only the rare third case which needs this function, which - // handles any JSAtom* that is known not to be representable with an int - // PropertyKey. - static PropertyKey fromNonIntAtom(JSAtom* atom) { - MOZ_ASSERT((size_t(atom) & JSID_TYPE_MASK) == 0); - MOZ_ASSERT(PropertyKey::isNonIntAtom(atom)); - return PropertyKey::fromRawBits(size_t(atom) | JSID_TYPE_STRING); - } - - // The JSAtom/JSString type exposed to embedders is opaque. - static PropertyKey fromNonIntAtom(JSString* str) { - MOZ_ASSERT((size_t(str) & JSID_TYPE_MASK) == 0); - MOZ_ASSERT(PropertyKey::isNonIntAtom(str)); - return PropertyKey::fromRawBits(size_t(str) | JSID_TYPE_STRING); - } - - private: - static bool isNonIntAtom(JSAtom* atom); - static bool isNonIntAtom(JSString* atom); -} JS_HAZ_GC_POINTER; - -} // namespace JS - -using jsid = JS::PropertyKey; - -#define JSID_BITS(id) (id.asBits) - -static MOZ_ALWAYS_INLINE bool JSID_IS_STRING(jsid id) { return id.isString(); } - -static MOZ_ALWAYS_INLINE JSString* JSID_TO_STRING(jsid id) { - return id.toString(); -} - -static MOZ_ALWAYS_INLINE bool JSID_IS_INT(jsid id) { return id.isInt(); } - -static MOZ_ALWAYS_INLINE int32_t JSID_TO_INT(jsid id) { return id.toInt(); } - -#define JSID_INT_MIN 0 -#define JSID_INT_MAX INT32_MAX - -static MOZ_ALWAYS_INLINE bool INT_FITS_IN_JSID(int32_t i) { return i >= 0; } - -static MOZ_ALWAYS_INLINE jsid INT_TO_JSID(int32_t i) { - jsid id; - MOZ_ASSERT(INT_FITS_IN_JSID(i)); - uint32_t bits = (static_cast(i) << 1) | JSID_TYPE_INT_BIT; - JSID_BITS(id) = static_cast(bits); - return id; -} - -static MOZ_ALWAYS_INLINE bool JSID_IS_SYMBOL(jsid id) { return id.isSymbol(); } - -static MOZ_ALWAYS_INLINE JS::Symbol* JSID_TO_SYMBOL(jsid id) { - return id.toSymbol(); -} - -static MOZ_ALWAYS_INLINE jsid SYMBOL_TO_JSID(JS::Symbol* sym) { - jsid id; - MOZ_ASSERT(sym != nullptr); - MOZ_ASSERT((size_t(sym) & JSID_TYPE_MASK) == 0); - MOZ_ASSERT(!js::gc::IsInsideNursery(reinterpret_cast(sym))); - JSID_BITS(id) = (size_t(sym) | JSID_TYPE_SYMBOL); - return id; -} - -static MOZ_ALWAYS_INLINE bool JSID_IS_VOID(const jsid id) { - MOZ_ASSERT_IF((JSID_BITS(id) & JSID_TYPE_MASK) == JSID_TYPE_VOID, - JSID_BITS(id) == JSID_TYPE_VOID); - return JSID_BITS(id) == JSID_TYPE_VOID; -} - -static MOZ_ALWAYS_INLINE bool JSID_IS_EMPTY(const jsid id) { - MOZ_ASSERT_IF((JSID_BITS(id) & JSID_TYPE_MASK) == JSID_TYPE_EMPTY, - JSID_BITS(id) == JSID_TYPE_EMPTY); - return JSID_BITS(id) == JSID_TYPE_EMPTY; -} - -constexpr const jsid JSID_VOID; -constexpr const jsid JSID_EMPTY = jsid::fromRawBits(JSID_TYPE_EMPTY); - -extern JS_PUBLIC_DATA const JS::HandleId JSID_VOIDHANDLE; -extern JS_PUBLIC_DATA const JS::HandleId JSID_EMPTYHANDLE; - -namespace JS { - -template <> -struct GCPolicy { - static void trace(JSTracer* trc, jsid* idp, const char* name) { - // It's not safe to trace unbarriered pointers except as part of root - // marking. - UnsafeTraceRoot(trc, idp, name); - } - static bool isValid(jsid id) { - return !id.isGCThing() || - js::gc::IsCellPointerValid(id.toGCCellPtr().asCell()); - } -}; - -#ifdef DEBUG -MOZ_ALWAYS_INLINE void AssertIdIsNotGray(jsid id) { - if (id.isGCThing()) { - AssertCellIsNotGray(id.toGCCellPtr().asCell()); - } -} -#endif - -} // namespace JS - -namespace js { - -template <> -struct BarrierMethods { - static gc::Cell* asGCThingOrNull(jsid id) { - if (JSID_IS_STRING(id)) { - return reinterpret_cast(JSID_TO_STRING(id)); - } - if (JSID_IS_SYMBOL(id)) { - return reinterpret_cast(JSID_TO_SYMBOL(id)); - } - return nullptr; - } - static void postWriteBarrier(jsid* idp, jsid prev, jsid next) { - MOZ_ASSERT_IF(JSID_IS_STRING(next), - !gc::IsInsideNursery(JSID_TO_STRING(next))); - } - static void exposeToJS(jsid id) { - if (id.isGCThing()) { - js::gc::ExposeGCThingToActiveJS(id.toGCCellPtr()); - } - } -}; - -// If the jsid is a GC pointer type, convert to that type and call |f| with the -// pointer and return the result wrapped in a Maybe, otherwise return None(). -template -auto MapGCThingTyped(const jsid& id, F&& f) { - if (JSID_IS_STRING(id)) { - return mozilla::Some(f(JSID_TO_STRING(id))); - } - if (JSID_IS_SYMBOL(id)) { - return mozilla::Some(f(JSID_TO_SYMBOL(id))); - } - MOZ_ASSERT(!id.isGCThing()); - using ReturnType = decltype(f(static_cast(nullptr))); - return mozilla::Maybe(); -} - -// If the jsid is a GC pointer type, convert to that type and call |f| with the -// pointer. Return whether this happened. -template -bool ApplyGCThingTyped(const jsid& id, F&& f) { - return MapGCThingTyped(id, - [&f](auto t) { - f(t); - return true; - }) - .isSome(); -} - -template -class WrappedPtrOperations { - const JS::PropertyKey& id() const { - return static_cast(this)->get(); - } - - public: - bool isInt() const { return id().isInt(); } - bool isString() const { return id().isString(); } - bool isSymbol() const { return id().isSymbol(); } - bool isGCThing() const { return id().isGCThing(); } - - int32_t toInt() const { return id().toInt(); } - JSString* toString() const { return id().toString(); } - JS::Symbol* toSymbol() const { return id().toSymbol(); } - - bool isWellKnownSymbol(JS::SymbolCode code) const { - return id().isWellKnownSymbol(code); - } -}; - -} // namespace js - -#endif /* js_Id_h */ Index: libraries/source/spidermonkey/include-win32-debug/js/Initialization.h =================================================================== --- /dev/null +++ libraries/source/spidermonkey/include-win32-debug/js/Initialization.h @@ -1,115 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* SpiderMonkey initialization and shutdown APIs. */ - -#ifndef js_Initialization_h -#define js_Initialization_h - -#include "jstypes.h" - -namespace JS { -namespace detail { - -enum class InitState { Uninitialized = 0, Initializing, Running, ShutDown }; - -/** - * SpiderMonkey's initialization status is tracked here, and it controls things - * that should happen only once across all runtimes. It's an API requirement - * that JS_Init (and JS_ShutDown, if called) be called in a thread-aware - * manner, so this (internal -- embedders, don't use!) variable doesn't need to - * be atomic. - */ -extern JS_PUBLIC_DATA InitState libraryInitState; - -extern JS_PUBLIC_API const char* InitWithFailureDiagnostic(bool isDebugBuild); - -} // namespace detail -} // namespace JS - -// These are equivalent to ICU's |UMemAllocFn|, |UMemReallocFn|, and -// |UMemFreeFn| types. The first argument (called |context| in the ICU docs) -// will always be nullptr and should be ignored. -typedef void* (*JS_ICUAllocFn)(const void*, size_t size); -typedef void* (*JS_ICUReallocFn)(const void*, void* p, size_t size); -typedef void (*JS_ICUFreeFn)(const void*, void* p); - -/** - * This function can be used to track memory used by ICU. If it is called, it - * *must* be called before JS_Init. Don't use it unless you know what you're - * doing! - */ -extern JS_PUBLIC_API bool JS_SetICUMemoryFunctions(JS_ICUAllocFn allocFn, - JS_ICUReallocFn reallocFn, - JS_ICUFreeFn freeFn); - -/** - * Initialize SpiderMonkey, returning true only if initialization succeeded. - * Once this method has succeeded, it is safe to call JS_NewContext and other - * JSAPI methods. - * - * This method must be called before any other JSAPI method is used on any - * thread. Once it has been used, it is safe to call any JSAPI method, and it - * remains safe to do so until JS_ShutDown is correctly called. - * - * It is currently not possible to initialize SpiderMonkey multiple times (that - * is, calling JS_Init/JSAPI methods/JS_ShutDown in that order, then doing so - * again). This restriction may eventually be lifted. - */ -inline bool JS_Init(void) { -#ifdef DEBUG - return !JS::detail::InitWithFailureDiagnostic(true); -#else - return !JS::detail::InitWithFailureDiagnostic(false); -#endif -} - -/** - * A variant of JS_Init. On success it returns nullptr. On failure it returns a - * pointer to a string literal that describes how initialization failed, which - * can be useful for debugging purposes. - */ -inline const char* JS_InitWithFailureDiagnostic(void) { -#ifdef DEBUG - return JS::detail::InitWithFailureDiagnostic(true); -#else - return JS::detail::InitWithFailureDiagnostic(false); -#endif -} - -/* - * Returns true if SpiderMonkey has been initialized successfully, even if it - * has possibly been shut down. - * - * Note that it is the responsibility of the embedder to call JS_Init() and - * JS_ShutDown() at the correct times, and therefore this API should ideally not - * be necessary to use. This is only intended to be used in cases where the - * embedder isn't in full control of deciding whether to initialize SpiderMonkey - * or hand off the task to another consumer. - */ -inline bool JS_IsInitialized(void) { - return JS::detail::libraryInitState >= JS::detail::InitState::Running; -} - -/** - * Destroy free-standing resources allocated by SpiderMonkey, not associated - * with any runtime, context, or other structure. - * - * This method should be called after all other JSAPI data has been properly - * cleaned up: every new runtime must have been destroyed, every new context - * must have been destroyed, and so on. Calling this method before all other - * resources have been destroyed has undefined behavior. - * - * Failure to call this method, at present, has no adverse effects other than - * leaking memory. This may not always be the case; it's recommended that all - * embedders call this method when all other JSAPI operations have completed. - * - * It is currently not possible to initialize SpiderMonkey multiple times (that - * is, calling JS_Init/JSAPI methods/JS_ShutDown in that order, then doing so - * again). This restriction may eventually be lifted. - */ -extern JS_PUBLIC_API void JS_ShutDown(void); - -#endif /* js_Initialization_h */ Index: libraries/source/spidermonkey/include-win32-debug/js/JSON.h =================================================================== --- /dev/null +++ libraries/source/spidermonkey/include-win32-debug/js/JSON.h @@ -1,95 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* - * JSON serialization and deserialization operations. - */ - -#ifndef js_JSON_h -#define js_JSON_h - -#include // uint32_t - -#include "jstypes.h" // JS_PUBLIC_API - -#include "js/RootingAPI.h" // JS::Handle, JS::MutableHandle -#include "js/Value.h" // JS::Value - -struct JS_PUBLIC_API JSContext; -class JS_PUBLIC_API JSObject; -class JS_PUBLIC_API JSString; - -using JSONWriteCallback = bool (*)(const char16_t* buf, uint32_t len, - void* data); - -/** - * Performs the JSON.stringify operation, as specified by ECMAScript, except - * writing stringified data by repeated calls of |callback|, with each such - * call passed |data| as argument. - */ -extern JS_PUBLIC_API bool JS_Stringify(JSContext* cx, - JS::MutableHandle value, - JS::Handle replacer, - JS::Handle space, - JSONWriteCallback callback, void* data); - -namespace JS { - -/** - * An API akin to JS_Stringify but with the goal of not having observable - * side-effects when the stringification is performed. This means it does not - * allow a replacer or a custom space and has the following constraints on its - * input: - * - * 1) The input must be a plain object or array, not an abitrary value. - * 2) Every value in the graph reached by the algorithm starting with this - * object must be one of the following: null, undefined, a string (NOT a - * string object!), a boolean, a finite number (i.e. no NaN or Infinity or - * -Infinity), a plain object with no accessor properties, or an Array with - * no holes. - * - * The actual behavior differs from JS_Stringify only in asserting the above and - * NOT attempting to get the "toJSON" property from things, since that could - * clearly have side-effects. - */ -extern JS_PUBLIC_API bool ToJSONMaybeSafely(JSContext* cx, - JS::Handle input, - JSONWriteCallback callback, - void* data); - -} /* namespace JS */ - -/** - * Performs the JSON.parse operation as specified by ECMAScript. - */ -extern JS_PUBLIC_API bool JS_ParseJSON(JSContext* cx, const char16_t* chars, - uint32_t len, - JS::MutableHandle vp); - -/** - * Performs the JSON.parse operation as specified by ECMAScript. - */ -extern JS_PUBLIC_API bool JS_ParseJSON(JSContext* cx, JS::Handle str, - JS::MutableHandle vp); - -/** - * Performs the JSON.parse operation as specified by ECMAScript, using the - * given |reviver| argument as the corresponding optional argument to that - * function. - */ -extern JS_PUBLIC_API bool JS_ParseJSONWithReviver( - JSContext* cx, const char16_t* chars, uint32_t len, - JS::Handle reviver, JS::MutableHandle vp); - -/** - * Performs the JSON.parse operation as specified by ECMAScript, using the - * given |reviver| argument as the corresponding optional argument to that - * function. - */ -extern JS_PUBLIC_API bool JS_ParseJSONWithReviver( - JSContext* cx, JS::Handle str, JS::Handle reviver, - JS::MutableHandle vp); - -#endif /* js_JSON_h */ Index: libraries/source/spidermonkey/include-win32-debug/js/LocaleSensitive.h =================================================================== --- /dev/null +++ libraries/source/spidermonkey/include-win32-debug/js/LocaleSensitive.h @@ -1,95 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* - * Functions and structures related to locale-sensitive behavior, including - * exposure of the default locale (used by operations like toLocaleString). - */ - -#ifndef js_LocaleSensitive_h -#define js_LocaleSensitive_h - -#include "jstypes.h" // JS_PUBLIC_API - -#include "js/RootingAPI.h" // JS::Handle, JS::MutableHandle -#include "js/Utility.h" // JS::UniqueChars -#include "js/Value.h" // JS::Value - -struct JS_PUBLIC_API JSContext; -struct JS_PUBLIC_API JSRuntime; -class JS_PUBLIC_API JSString; - -/** - * Set the default locale for the ECMAScript Internationalization API - * (Intl.Collator, Intl.NumberFormat, Intl.DateTimeFormat, and others that will - * arise as time passes). (Note that the Internationalization API encourages - * clients to specify their own locales; this default locale is only used when - * no locale is specified, e.g. calling a toLocaleString function without - * passing a locale argument to it.) - * - * The locale string remains owned by the caller. - */ -extern JS_PUBLIC_API bool JS_SetDefaultLocale(JSRuntime* rt, - const char* locale); - -/** - * Return a copy of the default locale for the ECMAScript Internationalization - * API (and for various ECMAScript functions that will invoke it). The locale - * is retrieved from the |JSRuntime| that corresponds to |cx|. - * - * XXX Bug 1483961 means it's difficult to interpret the meaning of a null - * return value for the time being, and we should fix this! - */ -extern JS_PUBLIC_API JS::UniqueChars JS_GetDefaultLocale(JSContext* cx); - -/** Reset the default locale to OS defaults. */ -extern JS_PUBLIC_API void JS_ResetDefaultLocale(JSRuntime* rt); - -using JSLocaleToUpperCase = bool (*)(JSContext* cx, JS::Handle src, - JS::MutableHandle rval); - -using JSLocaleToLowerCase = bool (*)(JSContext* cx, JS::Handle src, - JS::MutableHandle rval); - -using JSLocaleCompare = bool (*)(JSContext* cx, JS::Handle src1, - JS::Handle src2, - JS::MutableHandle rval); - -using JSLocaleToUnicode = bool (*)(JSContext* cx, const char* src, - JS::MutableHandle rval); - -/** - * A suite of locale-specific string conversion and error message callbacks - * used to implement locale-sensitive behaviors (such as those performed by - * the various toLocaleString and toLocale{Date,Time}String functions). - * - * If SpiderMonkey is compiled --with-intl-api, then #if JS_HAS_INTL_API. In - * this case, SpiderMonkey itself will implement ECMA-402-compliant behavior by - * calling on ICU, and none of the fields in this struct will ever be used. - * (You'll still be able to call the get/set-callbacks functions; they just - * won't affect JavaScript semantics.) - */ -struct JSLocaleCallbacks { - JSLocaleToUpperCase localeToUpperCase; - JSLocaleToLowerCase localeToLowerCase; - JSLocaleCompare localeCompare; - JSLocaleToUnicode localeToUnicode; -}; - -/** - * Set locale callbacks to be used in builds not compiled --with-intl-api. - * |callbacks| must persist as long as the |JSRuntime|. Pass |nullptr| to - * restore default behavior. - */ -extern JS_PUBLIC_API void JS_SetLocaleCallbacks( - JSRuntime* rt, const JSLocaleCallbacks* callbacks); - -/** - * Return the current locale callbacks, which may be nullptr. - */ -extern JS_PUBLIC_API const JSLocaleCallbacks* JS_GetLocaleCallbacks( - JSRuntime* rt); - -#endif /* js_LocaleSensitive_h */ Index: libraries/source/spidermonkey/include-win32-debug/js/MemoryFunctions.h =================================================================== --- /dev/null +++ libraries/source/spidermonkey/include-win32-debug/js/MemoryFunctions.h @@ -1,100 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* Low-level memory-allocation functions. */ - -#ifndef js_MemoryFunctions_h -#define js_MemoryFunctions_h - -#include "mozilla/Assertions.h" // MOZ_ASSERT -#include "mozilla/Attributes.h" // MOZ_MUST_USE - -#include // size_t - -#include "jstypes.h" // JS_PUBLIC_API - -struct JS_PUBLIC_API JSContext; -class JS_PUBLIC_API JSFreeOp; -class JS_PUBLIC_API JSObject; -struct JS_PUBLIC_API JSRuntime; - -extern JS_PUBLIC_API void* JS_malloc(JSContext* cx, size_t nbytes); - -extern JS_PUBLIC_API void* JS_realloc(JSContext* cx, void* p, size_t oldBytes, - size_t newBytes); - -/** - * A wrapper for |js_free(p)| that may delay |js_free(p)| invocation as a - * performance optimization. |cx| may be nullptr. - */ -extern JS_PUBLIC_API void JS_free(JSContext* cx, void* p); - -/** - * Same as above, but for buffers that will be used with the BYOB - * (Bring Your Own Buffer) JSString creation functions, such as - * JS_NewLatin1String and JS_NewUCString - */ -extern JS_PUBLIC_API void* JS_string_malloc(JSContext* cx, size_t nbytes); - -extern JS_PUBLIC_API void* JS_string_realloc(JSContext* cx, void* p, - size_t oldBytes, size_t newBytes); - -extern JS_PUBLIC_API void JS_string_free(JSContext* cx, void* p); - -/** - * A wrapper for |js_free(p)| that may delay |js_free(p)| invocation as a - * performance optimization as specified by the given JSFreeOp instance. - */ -extern JS_PUBLIC_API void JS_freeop(JSFreeOp* fop, void* p); - -namespace JS { - -/** - * The different possible memory uses to pass to Add/RemoveAssociatedMemory. - */ -#define JS_FOR_EACH_PUBLIC_MEMORY_USE(_) \ - _(XPCWrappedNative) \ - _(DOMBinding) \ - _(CTypeFFIType) \ - _(CTypeFFITypeElements) \ - _(CTypeFunctionInfo) \ - _(CTypeFieldInfo) \ - _(CDataBufferPtr) \ - _(CDataBuffer) \ - _(CClosureInfo) \ - _(CTypesInt64) \ - _(PerfMeasurement) \ - _(Embedding1) \ - _(Embedding2) \ - _(Embedding3) \ - _(Embedding4) \ - _(Embedding5) - -enum class MemoryUse : uint8_t { -#define DEFINE_MEMORY_USE(Name) Name, - JS_FOR_EACH_PUBLIC_MEMORY_USE(DEFINE_MEMORY_USE) -#undef DEFINE_MEMORY_USE -}; - -/** - * Advise the GC of external memory owned by a JSObject. This is used to - * determine when to collect zones. Calls must be matched by calls to - * RemoveAssociatedMemory() when the memory is deallocated or no longer owned by - * the object. - */ -extern JS_PUBLIC_API void AddAssociatedMemory(JSObject* obj, size_t nbytes, - MemoryUse use); - -/** - * Advise the GC that external memory reported by JS::AddAssociatedMemory() is - * no longer owned by a JSObject. Calls must match those to - * AddAssociatedMemory(). - */ -extern JS_PUBLIC_API void RemoveAssociatedMemory(JSObject* obj, size_t nbytes, - MemoryUse use); - -} // namespace JS - -#endif /* js_MemoryFunctions_h */ Index: libraries/source/spidermonkey/include-win32-debug/js/MemoryMetrics.h =================================================================== --- /dev/null +++ libraries/source/spidermonkey/include-win32-debug/js/MemoryMetrics.h @@ -1,904 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- - * vim: set ts=8 sts=2 et sw=2 tw=80: - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef js_MemoryMetrics_h -#define js_MemoryMetrics_h - -// These declarations are highly likely to change in the future. Depend on them -// at your own risk. - -#include "mozilla/Maybe.h" -#include "mozilla/MemoryReporting.h" - -#include -#include - -#include "jspubtd.h" - -#include "js/AllocPolicy.h" -#include "js/HashTable.h" -#include "js/TracingAPI.h" -#include "js/Utility.h" -#include "js/Vector.h" - -class nsISupports; // Needed for ObjectPrivateVisitor. - -namespace JS { - -struct TabSizes { - TabSizes() = default; - - enum Kind { Objects, Strings, Private, Other }; - - void add(Kind kind, size_t n) { - switch (kind) { - case Objects: - objects_ += n; - break; - case Strings: - strings_ += n; - break; - case Private: - private_ += n; - break; - case Other: - other_ += n; - break; - default: - MOZ_CRASH("bad TabSizes kind"); - } - } - - size_t objects_ = 0; - size_t strings_ = 0; - size_t private_ = 0; - size_t other_ = 0; -}; - -/** These are the measurements used by Servo. */ -struct ServoSizes { - ServoSizes() = default; - - enum Kind { - GCHeapUsed, - GCHeapUnused, - GCHeapAdmin, - GCHeapDecommitted, - MallocHeap, - NonHeap, - Ignore - }; - - void add(Kind kind, size_t n) { - switch (kind) { - case GCHeapUsed: - gcHeapUsed += n; - break; - case GCHeapUnused: - gcHeapUnused += n; - break; - case GCHeapAdmin: - gcHeapAdmin += n; - break; - case GCHeapDecommitted: - gcHeapDecommitted += n; - break; - case MallocHeap: - mallocHeap += n; - break; - case NonHeap: - nonHeap += n; - break; - case Ignore: /* do nothing */ - break; - default: - MOZ_CRASH("bad ServoSizes kind"); - } - } - - size_t gcHeapUsed = 0; - size_t gcHeapUnused = 0; - size_t gcHeapAdmin = 0; - size_t gcHeapDecommitted = 0; - size_t mallocHeap = 0; - size_t nonHeap = 0; -}; - -} // namespace JS - -namespace js { - -/** - * In memory reporting, we have concept of "sundries", line items which are too - * small to be worth reporting individually. Under some circumstances, a memory - * reporter gets tossed into the sundries bucket if it's smaller than - * MemoryReportingSundriesThreshold() bytes. - * - * We need to define this value here, rather than in the code which actually - * generates the memory reports, because NotableStringInfo uses this value. - */ -JS_FRIEND_API size_t MemoryReportingSundriesThreshold(); - -/** - * This hash policy avoids flattening ropes (which perturbs the site being - * measured and requires a JSContext) at the expense of doing a FULL ROPE COPY - * on every hash and match! Beware. - */ -struct InefficientNonFlatteningStringHashPolicy { - typedef JSString* Lookup; - static HashNumber hash(const Lookup& l); - static bool match(const JSString* const& k, const Lookup& l); -}; - -// This file features many classes with numerous size_t fields, and each such -// class has one or more methods that need to operate on all of these fields. -// Writing these individually is error-prone -- it's easy to add a new field -// without updating all the required methods. So we define a single macro list -// in each class to name the fields (and notable characteristics of them), and -// then use the following macros to transform those lists into the required -// methods. -// -// - The |tabKind| value is used when measuring TabSizes. -// -// - The |servoKind| value is used when measuring ServoSizes and also for -// the various sizeOfLiveGCThings() methods. -// -// In some classes, one or more of the macro arguments aren't used. We use '_' -// for those. -// -#define DECL_SIZE_ZERO(tabKind, servoKind, mSize) size_t mSize = 0; -#define ADD_OTHER_SIZE(tabKind, servoKind, mSize) mSize += other.mSize; -#define SUB_OTHER_SIZE(tabKind, servoKind, mSize) \ - MOZ_ASSERT(mSize >= other.mSize); \ - mSize -= other.mSize; -#define ADD_SIZE_TO_N(tabKind, servoKind, mSize) n += mSize; -#define ADD_SIZE_TO_N_IF_LIVE_GC_THING(tabKind, servoKind, mSize) \ - /* Avoid self-comparison warnings by comparing enums indirectly. */ \ - n += (std::is_same_v) \ - ? mSize \ - : 0; -#define ADD_TO_TAB_SIZES(tabKind, servoKind, mSize) \ - sizes->add(JS::TabSizes::tabKind, mSize); -#define ADD_TO_SERVO_SIZES(tabKind, servoKind, mSize) \ - sizes->add(JS::ServoSizes::servoKind, mSize); - -} // namespace js - -namespace JS { - -struct ClassInfo { -#define FOR_EACH_SIZE(MACRO) \ - MACRO(Objects, GCHeapUsed, objectsGCHeap) \ - MACRO(Objects, MallocHeap, objectsMallocHeapSlots) \ - MACRO(Objects, MallocHeap, objectsMallocHeapElementsNormal) \ - MACRO(Objects, MallocHeap, objectsMallocHeapElementsAsmJS) \ - MACRO(Objects, MallocHeap, objectsMallocHeapMisc) \ - MACRO(Objects, NonHeap, objectsNonHeapElementsNormal) \ - MACRO(Objects, NonHeap, objectsNonHeapElementsShared) \ - MACRO(Objects, NonHeap, objectsNonHeapElementsWasm) \ - MACRO(Objects, NonHeap, objectsNonHeapCodeWasm) - - ClassInfo() = default; - - void add(const ClassInfo& other) { FOR_EACH_SIZE(ADD_OTHER_SIZE); } - - void subtract(const ClassInfo& other) { FOR_EACH_SIZE(SUB_OTHER_SIZE); } - - size_t sizeOfAllThings() const { - size_t n = 0; - FOR_EACH_SIZE(ADD_SIZE_TO_N); - return n; - } - - bool isNotable() const { - static const size_t NotabilityThreshold = 16 * 1024; - return sizeOfAllThings() >= NotabilityThreshold; - } - - size_t sizeOfLiveGCThings() const { - size_t n = 0; - FOR_EACH_SIZE(ADD_SIZE_TO_N_IF_LIVE_GC_THING); - return n; - } - - void addToTabSizes(TabSizes* sizes) const { FOR_EACH_SIZE(ADD_TO_TAB_SIZES); } - - void addToServoSizes(ServoSizes* sizes) const { - FOR_EACH_SIZE(ADD_TO_SERVO_SIZES); - } - - FOR_EACH_SIZE(DECL_SIZE_ZERO); - - size_t wasmGuardPages = 0; - -#undef FOR_EACH_SIZE -}; - -struct ShapeInfo { -#define FOR_EACH_SIZE(MACRO) \ - MACRO(Other, GCHeapUsed, shapesGCHeapTree) \ - MACRO(Other, GCHeapUsed, shapesGCHeapDict) \ - MACRO(Other, GCHeapUsed, shapesGCHeapBase) \ - MACRO(Other, MallocHeap, shapesMallocHeapTreeTables) \ - MACRO(Other, MallocHeap, shapesMallocHeapDictTables) \ - MACRO(Other, MallocHeap, shapesMallocHeapTreeChildren) - - ShapeInfo() = default; - - void add(const ShapeInfo& other) { FOR_EACH_SIZE(ADD_OTHER_SIZE); } - - void subtract(const ShapeInfo& other) { FOR_EACH_SIZE(SUB_OTHER_SIZE); } - - size_t sizeOfAllThings() const { - size_t n = 0; - FOR_EACH_SIZE(ADD_SIZE_TO_N); - return n; - } - - size_t sizeOfLiveGCThings() const { - size_t n = 0; - FOR_EACH_SIZE(ADD_SIZE_TO_N_IF_LIVE_GC_THING); - return n; - } - - void addToTabSizes(TabSizes* sizes) const { FOR_EACH_SIZE(ADD_TO_TAB_SIZES); } - - void addToServoSizes(ServoSizes* sizes) const { - FOR_EACH_SIZE(ADD_TO_SERVO_SIZES); - } - - FOR_EACH_SIZE(DECL_SIZE_ZERO); - -#undef FOR_EACH_SIZE -}; - -/** - * Holds data about a notable class (one whose combined object and shape - * instances use more than a certain amount of memory) so we can report it - * individually. - * - * The only difference between this class and ClassInfo is that this class - * holds a copy of the filename. - */ -struct NotableClassInfo : public ClassInfo { - NotableClassInfo() = default; - NotableClassInfo(NotableClassInfo&&) = default; - NotableClassInfo(const NotableClassInfo& info) = delete; - - NotableClassInfo(const char* className, const ClassInfo& info); - - UniqueChars className_ = nullptr; -}; - -/** Data for tracking JIT-code memory usage. */ -struct CodeSizes { -#define FOR_EACH_SIZE(MACRO) \ - MACRO(_, NonHeap, ion) \ - MACRO(_, NonHeap, baseline) \ - MACRO(_, NonHeap, regexp) \ - MACRO(_, NonHeap, other) \ - MACRO(_, NonHeap, unused) - - CodeSizes() = default; - - void addToServoSizes(ServoSizes* sizes) const { - FOR_EACH_SIZE(ADD_TO_SERVO_SIZES); - } - - FOR_EACH_SIZE(DECL_SIZE_ZERO); - -#undef FOR_EACH_SIZE -}; - -/** Data for tracking GC memory usage. */ -struct GCSizes { - // |nurseryDecommitted| is marked as NonHeap rather than GCHeapDecommitted - // because we don't consider the nursery to be part of the GC heap. -#define FOR_EACH_SIZE(MACRO) \ - MACRO(_, MallocHeap, marker) \ - MACRO(_, NonHeap, nurseryCommitted) \ - MACRO(_, MallocHeap, nurseryMallocedBuffers) \ - MACRO(_, MallocHeap, storeBufferVals) \ - MACRO(_, MallocHeap, storeBufferCells) \ - MACRO(_, MallocHeap, storeBufferSlots) \ - MACRO(_, MallocHeap, storeBufferWholeCells) \ - MACRO(_, MallocHeap, storeBufferGenerics) - - GCSizes() = default; - - void addToServoSizes(ServoSizes* sizes) const { - FOR_EACH_SIZE(ADD_TO_SERVO_SIZES); - } - - FOR_EACH_SIZE(DECL_SIZE_ZERO); - -#undef FOR_EACH_SIZE -}; - -/** - * This class holds information about the memory taken up by identical copies of - * a particular string. Multiple JSStrings may have their sizes aggregated - * together into one StringInfo object. Note that two strings with identical - * chars will not be aggregated together if one is a short string and the other - * is not. - */ -struct StringInfo { -#define FOR_EACH_SIZE(MACRO) \ - MACRO(Strings, GCHeapUsed, gcHeapLatin1) \ - MACRO(Strings, GCHeapUsed, gcHeapTwoByte) \ - MACRO(Strings, MallocHeap, mallocHeapLatin1) \ - MACRO(Strings, MallocHeap, mallocHeapTwoByte) - - StringInfo() = default; - - void add(const StringInfo& other) { - FOR_EACH_SIZE(ADD_OTHER_SIZE); - numCopies++; - } - - void subtract(const StringInfo& other) { - FOR_EACH_SIZE(SUB_OTHER_SIZE); - numCopies--; - } - - bool isNotable() const { - static const size_t NotabilityThreshold = 16 * 1024; - size_t n = 0; - FOR_EACH_SIZE(ADD_SIZE_TO_N); - return n >= NotabilityThreshold; - } - - size_t sizeOfLiveGCThings() const { - size_t n = 0; - FOR_EACH_SIZE(ADD_SIZE_TO_N_IF_LIVE_GC_THING); - return n; - } - - void addToTabSizes(TabSizes* sizes) const { FOR_EACH_SIZE(ADD_TO_TAB_SIZES); } - - void addToServoSizes(ServoSizes* sizes) const { - FOR_EACH_SIZE(ADD_TO_SERVO_SIZES); - } - - FOR_EACH_SIZE(DECL_SIZE_ZERO); - - uint32_t numCopies = 0; // How many copies of the string have we seen? - -#undef FOR_EACH_SIZE -}; - -/** - * Holds data about a notable string (one which, counting all duplicates, uses - * more than a certain amount of memory) so we can report it individually. - * - * The only difference between this class and StringInfo is that - * NotableStringInfo holds a copy of some or all of the string's chars. - */ -struct NotableStringInfo : public StringInfo { - static const size_t MAX_SAVED_CHARS = 1024; - - NotableStringInfo() = default; - NotableStringInfo(NotableStringInfo&&) = default; - NotableStringInfo(const NotableStringInfo&) = delete; - - NotableStringInfo(JSString* str, const StringInfo& info); - - UniqueChars buffer = nullptr; - size_t length = 0; -}; - -/** - * This class holds information about the memory taken up by script sources - * from a particular file. - */ -struct ScriptSourceInfo { -#define FOR_EACH_SIZE(MACRO) MACRO(_, MallocHeap, misc) - - ScriptSourceInfo() = default; - - void add(const ScriptSourceInfo& other) { - FOR_EACH_SIZE(ADD_OTHER_SIZE); - numScripts++; - } - - void subtract(const ScriptSourceInfo& other) { - FOR_EACH_SIZE(SUB_OTHER_SIZE); - numScripts--; - } - - void addToServoSizes(ServoSizes* sizes) const { - FOR_EACH_SIZE(ADD_TO_SERVO_SIZES); - } - - bool isNotable() const { - static const size_t NotabilityThreshold = 16 * 1024; - size_t n = 0; - FOR_EACH_SIZE(ADD_SIZE_TO_N); - return n >= NotabilityThreshold; - } - - FOR_EACH_SIZE(DECL_SIZE_ZERO); - - uint32_t numScripts = 0; // How many ScriptSources come from this file? (It - // can be more than one in XML files that have - // multiple scripts in CDATA sections.) -#undef FOR_EACH_SIZE -}; - -/** - * Holds data about a notable script source file (one whose combined - * script sources use more than a certain amount of memory) so we can report it - * individually. - * - * The only difference between this class and ScriptSourceInfo is that this - * class holds a copy of the filename. - */ -struct NotableScriptSourceInfo : public ScriptSourceInfo { - NotableScriptSourceInfo() = default; - NotableScriptSourceInfo(NotableScriptSourceInfo&&) = default; - NotableScriptSourceInfo(const NotableScriptSourceInfo&) = delete; - - NotableScriptSourceInfo(const char* filename, const ScriptSourceInfo& info); - - UniqueChars filename_ = nullptr; -}; - -struct HelperThreadStats { -#define FOR_EACH_SIZE(MACRO) \ - MACRO(_, MallocHeap, stateData) \ - MACRO(_, MallocHeap, parseTask) \ - MACRO(_, MallocHeap, ionCompileTask) \ - MACRO(_, MallocHeap, wasmCompile) - - HelperThreadStats() = default; - - FOR_EACH_SIZE(DECL_SIZE_ZERO); - - unsigned idleThreadCount = 0; - unsigned activeThreadCount = 0; - -#undef FOR_EACH_SIZE -}; - -/** - * Measurements that not associated with any individual runtime. - */ -struct GlobalStats { -#define FOR_EACH_SIZE(MACRO) MACRO(_, MallocHeap, tracelogger) - - explicit GlobalStats(mozilla::MallocSizeOf mallocSizeOf) - : mallocSizeOf_(mallocSizeOf) {} - - FOR_EACH_SIZE(DECL_SIZE_ZERO); - - HelperThreadStats helperThread; - - mozilla::MallocSizeOf mallocSizeOf_; - -#undef FOR_EACH_SIZE -}; - -/** - * These measurements relate directly to the JSRuntime, and not to zones, - * compartments, and realms within it. - */ -struct RuntimeSizes { -#define FOR_EACH_SIZE(MACRO) \ - MACRO(_, MallocHeap, object) \ - MACRO(_, MallocHeap, atomsTable) \ - MACRO(_, MallocHeap, atomsMarkBitmaps) \ - MACRO(_, MallocHeap, contexts) \ - MACRO(_, MallocHeap, temporary) \ - MACRO(_, MallocHeap, interpreterStack) \ - MACRO(_, MallocHeap, sharedImmutableStringsCache) \ - MACRO(_, MallocHeap, sharedIntlData) \ - MACRO(_, MallocHeap, uncompressedSourceCache) \ - MACRO(_, MallocHeap, scriptData) \ - MACRO(_, MallocHeap, tracelogger) \ - MACRO(_, MallocHeap, wasmRuntime) \ - MACRO(_, MallocHeap, jitLazyLink) - - RuntimeSizes() { allScriptSources.emplace(); } - - void addToServoSizes(ServoSizes* sizes) const { - FOR_EACH_SIZE(ADD_TO_SERVO_SIZES); - scriptSourceInfo.addToServoSizes(sizes); - gc.addToServoSizes(sizes); - } - - FOR_EACH_SIZE(DECL_SIZE_ZERO); - - // The script source measurements in |scriptSourceInfo| are initially for - // all script sources. At the end, if the measurement granularity is - // FineGrained, we subtract the measurements of the notable script sources - // and move them into |notableScriptSources|. - ScriptSourceInfo scriptSourceInfo; - GCSizes gc; - - typedef js::HashMap - ScriptSourcesHashMap; - - // |allScriptSources| is only used transiently. During the reporting phase - // it is filled with info about every script source in the runtime. It's - // then used to fill in |notableScriptSources| (which actually gets - // reported), and immediately discarded afterwards. - mozilla::Maybe allScriptSources; - js::Vector - notableScriptSources; - -#undef FOR_EACH_SIZE -}; - -struct UnusedGCThingSizes { -#define FOR_EACH_SIZE(MACRO) \ - MACRO(Other, GCHeapUnused, object) \ - MACRO(Other, GCHeapUnused, script) \ - MACRO(Other, GCHeapUnused, shape) \ - MACRO(Other, GCHeapUnused, baseShape) \ - MACRO(Other, GCHeapUnused, objectGroup) \ - MACRO(Other, GCHeapUnused, string) \ - MACRO(Other, GCHeapUnused, symbol) \ - MACRO(Other, GCHeapUnused, bigInt) \ - MACRO(Other, GCHeapUnused, jitcode) \ - MACRO(Other, GCHeapUnused, scope) \ - MACRO(Other, GCHeapUnused, regExpShared) - - UnusedGCThingSizes() = default; - UnusedGCThingSizes(UnusedGCThingSizes&& other) = default; - - void addToKind(JS::TraceKind kind, intptr_t n) { - switch (kind) { - case JS::TraceKind::Object: - object += n; - break; - case JS::TraceKind::String: - string += n; - break; - case JS::TraceKind::Symbol: - symbol += n; - break; - case JS::TraceKind::BigInt: - bigInt += n; - break; - case JS::TraceKind::Script: - script += n; - break; - case JS::TraceKind::Shape: - shape += n; - break; - case JS::TraceKind::BaseShape: - baseShape += n; - break; - case JS::TraceKind::JitCode: - jitcode += n; - break; - case JS::TraceKind::ObjectGroup: - objectGroup += n; - break; - case JS::TraceKind::Scope: - scope += n; - break; - case JS::TraceKind::RegExpShared: - regExpShared += n; - break; - default: - MOZ_CRASH("Bad trace kind for UnusedGCThingSizes"); - } - } - - void addSizes(const UnusedGCThingSizes& other) { - FOR_EACH_SIZE(ADD_OTHER_SIZE); - } - - size_t totalSize() const { - size_t n = 0; - FOR_EACH_SIZE(ADD_SIZE_TO_N); - return n; - } - - void addToTabSizes(JS::TabSizes* sizes) const { - FOR_EACH_SIZE(ADD_TO_TAB_SIZES); - } - - void addToServoSizes(JS::ServoSizes* sizes) const { - FOR_EACH_SIZE(ADD_TO_SERVO_SIZES); - } - - FOR_EACH_SIZE(DECL_SIZE_ZERO); - -#undef FOR_EACH_SIZE -}; - -struct ZoneStats { -#define FOR_EACH_SIZE(MACRO) \ - MACRO(Other, GCHeapUsed, symbolsGCHeap) \ - MACRO(Other, GCHeapUsed, bigIntsGCHeap) \ - MACRO(Other, MallocHeap, bigIntsMallocHeap) \ - MACRO(Other, GCHeapAdmin, gcHeapArenaAdmin) \ - MACRO(Other, GCHeapUsed, jitCodesGCHeap) \ - MACRO(Other, GCHeapUsed, objectGroupsGCHeap) \ - MACRO(Other, MallocHeap, objectGroupsMallocHeap) \ - MACRO(Other, GCHeapUsed, scopesGCHeap) \ - MACRO(Other, MallocHeap, scopesMallocHeap) \ - MACRO(Other, GCHeapUsed, regExpSharedsGCHeap) \ - MACRO(Other, MallocHeap, regExpSharedsMallocHeap) \ - MACRO(Other, MallocHeap, typePool) \ - MACRO(Other, MallocHeap, regexpZone) \ - MACRO(Other, MallocHeap, jitZone) \ - MACRO(Other, MallocHeap, baselineStubsOptimized) \ - MACRO(Other, MallocHeap, uniqueIdMap) \ - MACRO(Other, MallocHeap, shapeTables) \ - MACRO(Other, MallocHeap, compartmentObjects) \ - MACRO(Other, MallocHeap, crossCompartmentWrappersTables) \ - MACRO(Other, MallocHeap, compartmentsPrivateData) \ - MACRO(Other, MallocHeap, scriptCountsMap) - - ZoneStats() = default; - ZoneStats(ZoneStats&& other) = default; - - void initStrings(); - - void addSizes(const ZoneStats& other) { - MOZ_ASSERT(isTotals); - FOR_EACH_SIZE(ADD_OTHER_SIZE); - unusedGCThings.addSizes(other.unusedGCThings); - stringInfo.add(other.stringInfo); - shapeInfo.add(other.shapeInfo); - } - - size_t sizeOfLiveGCThings() const { - MOZ_ASSERT(isTotals); - size_t n = 0; - FOR_EACH_SIZE(ADD_SIZE_TO_N_IF_LIVE_GC_THING); - n += stringInfo.sizeOfLiveGCThings(); - n += shapeInfo.sizeOfLiveGCThings(); - return n; - } - - void addToTabSizes(JS::TabSizes* sizes) const { - MOZ_ASSERT(isTotals); - FOR_EACH_SIZE(ADD_TO_TAB_SIZES); - unusedGCThings.addToTabSizes(sizes); - stringInfo.addToTabSizes(sizes); - shapeInfo.addToTabSizes(sizes); - } - - void addToServoSizes(JS::ServoSizes* sizes) const { - MOZ_ASSERT(isTotals); - FOR_EACH_SIZE(ADD_TO_SERVO_SIZES); - unusedGCThings.addToServoSizes(sizes); - stringInfo.addToServoSizes(sizes); - shapeInfo.addToServoSizes(sizes); - code.addToServoSizes(sizes); - } - - FOR_EACH_SIZE(DECL_SIZE_ZERO); - - // These string measurements are initially for all strings. At the end, - // if the measurement granularity is FineGrained, we subtract the - // measurements of the notable script sources and move them into - // |notableStrings|. - UnusedGCThingSizes unusedGCThings; - StringInfo stringInfo; - ShapeInfo shapeInfo; - CodeSizes code; - void* extra = nullptr; // This field can be used by embedders. - - typedef js::HashMap - StringsHashMap; - - // |allStrings| is only used transiently. During the zone traversal it is - // filled with info about every string in the zone. It's then used to fill - // in |notableStrings| (which actually gets reported), and immediately - // discarded afterwards. - mozilla::Maybe allStrings; - js::Vector notableStrings; - bool isTotals = true; - -#undef FOR_EACH_SIZE -}; - -struct RealmStats { - // We assume that |objectsPrivate| is on the malloc heap, but it's not - // actually guaranteed. But for Servo, at least, it's a moot point because - // it doesn't provide an ObjectPrivateVisitor so the value will always be - // zero. -#define FOR_EACH_SIZE(MACRO) \ - MACRO(Private, MallocHeap, objectsPrivate) \ - MACRO(Other, GCHeapUsed, scriptsGCHeap) \ - MACRO(Other, MallocHeap, scriptsMallocHeapData) \ - MACRO(Other, MallocHeap, baselineData) \ - MACRO(Other, MallocHeap, baselineStubsFallback) \ - MACRO(Other, MallocHeap, ionData) \ - MACRO(Other, MallocHeap, jitScripts) \ - MACRO(Other, MallocHeap, typeInferenceAllocationSiteTables) \ - MACRO(Other, MallocHeap, typeInferenceArrayTypeTables) \ - MACRO(Other, MallocHeap, typeInferenceObjectTypeTables) \ - MACRO(Other, MallocHeap, realmObject) \ - MACRO(Other, MallocHeap, realmTables) \ - MACRO(Other, MallocHeap, innerViewsTable) \ - MACRO(Other, MallocHeap, objectMetadataTable) \ - MACRO(Other, MallocHeap, savedStacksSet) \ - MACRO(Other, MallocHeap, varNamesSet) \ - MACRO(Other, MallocHeap, nonSyntacticLexicalScopesTable) \ - MACRO(Other, MallocHeap, jitRealm) - - RealmStats() = default; - RealmStats(RealmStats&& other) = default; - - RealmStats(const RealmStats&) = delete; // disallow copying - - void initClasses(); - - void addSizes(const RealmStats& other) { - MOZ_ASSERT(isTotals); - FOR_EACH_SIZE(ADD_OTHER_SIZE); - classInfo.add(other.classInfo); - } - - size_t sizeOfLiveGCThings() const { - MOZ_ASSERT(isTotals); - size_t n = 0; - FOR_EACH_SIZE(ADD_SIZE_TO_N_IF_LIVE_GC_THING); - n += classInfo.sizeOfLiveGCThings(); - return n; - } - - void addToTabSizes(TabSizes* sizes) const { - MOZ_ASSERT(isTotals); - FOR_EACH_SIZE(ADD_TO_TAB_SIZES); - classInfo.addToTabSizes(sizes); - } - - void addToServoSizes(ServoSizes* sizes) const { - MOZ_ASSERT(isTotals); - FOR_EACH_SIZE(ADD_TO_SERVO_SIZES); - classInfo.addToServoSizes(sizes); - } - - FOR_EACH_SIZE(DECL_SIZE_ZERO); - - // The class measurements in |classInfo| are initially for all classes. At - // the end, if the measurement granularity is FineGrained, we subtract the - // measurements of the notable classes and move them into |notableClasses|. - ClassInfo classInfo; - void* extra = nullptr; // This field can be used by embedders. - - typedef js::HashMap - ClassesHashMap; - - // These are similar to |allStrings| and |notableStrings| in ZoneStats. - mozilla::Maybe allClasses; - js::Vector notableClasses; - bool isTotals = true; - -#undef FOR_EACH_SIZE -}; - -typedef js::Vector RealmStatsVector; -typedef js::Vector ZoneStatsVector; - -struct RuntimeStats { - // |gcHeapChunkTotal| is ignored because it's the sum of all the other - // values. |gcHeapGCThings| is ignored because it's the sum of some of the - // values from the zones and compartments. Both of those values are not - // reported directly, but are just present for sanity-checking other - // values. -#define FOR_EACH_SIZE(MACRO) \ - MACRO(_, Ignore, gcHeapChunkTotal) \ - MACRO(_, GCHeapDecommitted, gcHeapDecommittedArenas) \ - MACRO(_, GCHeapUnused, gcHeapUnusedChunks) \ - MACRO(_, GCHeapUnused, gcHeapUnusedArenas) \ - MACRO(_, GCHeapAdmin, gcHeapChunkAdmin) \ - MACRO(_, Ignore, gcHeapGCThings) - - explicit RuntimeStats(mozilla::MallocSizeOf mallocSizeOf) - : mallocSizeOf_(mallocSizeOf) {} - - // Here's a useful breakdown of the GC heap. - // - // - rtStats.gcHeapChunkTotal - // - decommitted bytes - // - rtStats.gcHeapDecommittedArenas - // (decommitted arenas in non-empty chunks) - // - unused bytes - // - rtStats.gcHeapUnusedChunks (empty chunks) - // - rtStats.gcHeapUnusedArenas (empty arenas within non-empty chunks) - // - rtStats.zTotals.unusedGCThings.totalSize() - // (empty GC thing slots within non-empty arenas) - // - used bytes - // - rtStats.gcHeapChunkAdmin - // - rtStats.zTotals.gcHeapArenaAdmin - // - rtStats.gcHeapGCThings (in-use GC things) - // == (rtStats.zTotals.sizeOfLiveGCThings() + - // rtStats.cTotals.sizeOfLiveGCThings()) - // - // It's possible that some arenas in empty chunks may be decommitted, but - // we don't count those under rtStats.gcHeapDecommittedArenas because (a) - // it's rare, and (b) this means that rtStats.gcHeapUnusedChunks is a - // multiple of the chunk size, which is good. - - void addToServoSizes(ServoSizes* sizes) const { - FOR_EACH_SIZE(ADD_TO_SERVO_SIZES); - runtime.addToServoSizes(sizes); - } - - FOR_EACH_SIZE(DECL_SIZE_ZERO); - - RuntimeSizes runtime; - - RealmStats realmTotals; // The sum of this runtime's realms' measurements. - ZoneStats zTotals; // The sum of this runtime's zones' measurements. - - RealmStatsVector realmStatsVector; - ZoneStatsVector zoneStatsVector; - - ZoneStats* currZoneStats = nullptr; - - mozilla::MallocSizeOf mallocSizeOf_; - - virtual void initExtraRealmStats(JS::Handle realm, - RealmStats* rstats) = 0; - virtual void initExtraZoneStats(JS::Zone* zone, ZoneStats* zstats) = 0; - -#undef FOR_EACH_SIZE -}; - -class ObjectPrivateVisitor { - public: - // Within CollectRuntimeStats, this method is called for each JS object - // that has an nsISupports pointer. - virtual size_t sizeOfIncludingThis(nsISupports* aSupports) = 0; - - // A callback that gets a JSObject's nsISupports pointer, if it has one. - // Note: this function does *not* addref |iface|. - typedef bool (*GetISupportsFun)(JSObject* obj, nsISupports** iface); - GetISupportsFun getISupports_; - - explicit ObjectPrivateVisitor(GetISupportsFun getISupports) - : getISupports_(getISupports) {} -}; - -extern JS_PUBLIC_API bool CollectGlobalStats(GlobalStats* gStats); - -extern JS_PUBLIC_API bool CollectRuntimeStats(JSContext* cx, - RuntimeStats* rtStats, - ObjectPrivateVisitor* opv, - bool anonymize); - -extern JS_PUBLIC_API size_t SystemCompartmentCount(JSContext* cx); -extern JS_PUBLIC_API size_t UserCompartmentCount(JSContext* cx); - -extern JS_PUBLIC_API size_t SystemRealmCount(JSContext* cx); -extern JS_PUBLIC_API size_t UserRealmCount(JSContext* cx); - -extern JS_PUBLIC_API size_t PeakSizeOfTemporary(const JSContext* cx); - -extern JS_PUBLIC_API bool AddSizeOfTab(JSContext* cx, JS::HandleObject obj, - mozilla::MallocSizeOf mallocSizeOf, - ObjectPrivateVisitor* opv, - TabSizes* sizes); - -extern JS_PUBLIC_API bool AddServoSizeOf(JSContext* cx, - mozilla::MallocSizeOf mallocSizeOf, - ObjectPrivateVisitor* opv, - ServoSizes* sizes); - -} // namespace JS - -#undef DECL_SIZE_ZERO -#undef ADD_OTHER_SIZE -#undef SUB_OTHER_SIZE -#undef ADD_SIZE_TO_N -#undef ADD_SIZE_TO_N_IF_LIVE_GC_THING -#undef ADD_TO_TAB_SIZES - -#endif /* js_MemoryMetrics_h */ Index: libraries/source/spidermonkey/include-win32-debug/js/Modules.h =================================================================== --- /dev/null +++ libraries/source/spidermonkey/include-win32-debug/js/Modules.h @@ -1,172 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- - * vim: set ts=8 sts=2 et sw=2 tw=80: - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* JavaScript module (as in, the syntactic construct) operations. */ - -#ifndef js_Modules_h -#define js_Modules_h - -#include "mozilla/Utf8.h" // mozilla::Utf8Unit - -#include // uint32_t - -#include "jstypes.h" // JS_PUBLIC_API - -#include "js/CompileOptions.h" // JS::ReadOnlyCompileOptions -#include "js/RootingAPI.h" // JS::{Mutable,}Handle -#include "js/Value.h" // JS::Value - -struct JS_PUBLIC_API JSContext; -class JS_PUBLIC_API JSObject; -struct JS_PUBLIC_API JSRuntime; -class JS_PUBLIC_API JSString; - -namespace JS { -template -class SourceText; -} // namespace JS - -namespace JS { - -using ModuleResolveHook = JSObject* (*)(JSContext*, Handle, - Handle); - -/** - * Get the HostResolveImportedModule hook for the runtime. - */ -extern JS_PUBLIC_API ModuleResolveHook GetModuleResolveHook(JSRuntime* rt); - -/** - * Set the HostResolveImportedModule hook for the runtime to the given function. - */ -extern JS_PUBLIC_API void SetModuleResolveHook(JSRuntime* rt, - ModuleResolveHook func); - -using ModuleMetadataHook = bool (*)(JSContext*, Handle, - Handle); - -/** - * Get the hook for populating the import.meta metadata object. - */ -extern JS_PUBLIC_API ModuleMetadataHook GetModuleMetadataHook(JSRuntime* rt); - -/** - * Set the hook for populating the import.meta metadata object to the given - * function. - */ -extern JS_PUBLIC_API void SetModuleMetadataHook(JSRuntime* rt, - ModuleMetadataHook func); - -using ModuleDynamicImportHook = bool (*)(JSContext* cx, - Handle referencingPrivate, - Handle specifier, - Handle promise); - -/** - * Get the HostImportModuleDynamically hook for the runtime. - */ -extern JS_PUBLIC_API ModuleDynamicImportHook -GetModuleDynamicImportHook(JSRuntime* rt); - -/** - * Set the HostImportModuleDynamically hook for the runtime to the given - * function. - * - * If this hook is not set (or set to nullptr) then the JS engine will throw an - * exception if dynamic module import is attempted. - */ -extern JS_PUBLIC_API void SetModuleDynamicImportHook( - JSRuntime* rt, ModuleDynamicImportHook func); - -extern JS_PUBLIC_API bool FinishDynamicModuleImport( - JSContext* cx, Handle referencingPrivate, - Handle specifier, Handle promise); - -/** - * Parse the given source buffer as a module in the scope of the current global - * of cx and return a source text module record. - */ -extern JS_PUBLIC_API JSObject* CompileModule( - JSContext* cx, const ReadOnlyCompileOptions& options, - SourceText& srcBuf); - -/** - * Parse the given source buffer as a module in the scope of the current global - * of cx and return a source text module record. An error is reported if a - * UTF-8 encoding error is encountered. - */ -extern JS_PUBLIC_API JSObject* CompileModule( - JSContext* cx, const ReadOnlyCompileOptions& options, - SourceText& srcBuf); - -/** - * Set a private value associated with a source text module record. - */ -extern JS_PUBLIC_API void SetModulePrivate(JSObject* module, - const Value& value); - -/** - * Get the private value associated with a source text module record. - */ -extern JS_PUBLIC_API Value GetModulePrivate(JSObject* module); - -/* - * Perform the ModuleInstantiate operation on the given source text module - * record. - * - * This transitively resolves all module dependencies (calling the - * HostResolveImportedModule hook) and initializes the environment record for - * the module. - */ -extern JS_PUBLIC_API bool ModuleInstantiate(JSContext* cx, - Handle moduleRecord); - -/* - * Perform the ModuleEvaluate operation on the given source text module record. - * - * This does nothing if this module has already been evaluated. Otherwise, it - * transitively evaluates all dependences of this module and then evaluates this - * module. - * - * ModuleInstantiate must have completed prior to calling this. - */ -extern JS_PUBLIC_API bool ModuleEvaluate(JSContext* cx, - Handle moduleRecord); - -/* - * Get a list of the module specifiers used by a source text module - * record to request importation of modules. - * - * The result is a JavaScript array of object values. To extract the individual - * values use only JS::GetArrayLength and JS_GetElement with indices 0 to length - * - 1. - * - * The element values are objects with the following properties: - * - moduleSpecifier: the module specifier string - * - lineNumber: the line number of the import in the source text - * - columnNumber: the column number of the import in the source text - * - * These property values can be extracted with GetRequestedModuleSpecifier() and - * GetRequestedModuleSourcePos() - */ -extern JS_PUBLIC_API JSObject* GetRequestedModules( - JSContext* cx, Handle moduleRecord); - -extern JS_PUBLIC_API JSString* GetRequestedModuleSpecifier( - JSContext* cx, Handle requestedModuleObject); - -extern JS_PUBLIC_API void GetRequestedModuleSourcePos( - JSContext* cx, Handle requestedModuleObject, uint32_t* lineNumber, - uint32_t* columnNumber); - -/* - * Get the top-level script for a module which has not yet been executed. - */ -extern JS_PUBLIC_API JSScript* GetModuleScript(Handle moduleRecord); - -} // namespace JS - -#endif // js_Modules_h Index: libraries/source/spidermonkey/include-win32-debug/js/OffThreadScriptCompilation.h =================================================================== --- /dev/null +++ libraries/source/spidermonkey/include-win32-debug/js/OffThreadScriptCompilation.h @@ -1,151 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* - * Types and functions related to the compilation of JavaScript off the - * direct JSAPI-using thread. - */ - -#ifndef js_OffThreadScriptCompilation_h -#define js_OffThreadScriptCompilation_h - -#include "mozilla/Range.h" // mozilla::Range -#include "mozilla/Utf8.h" // mozilla::Utf8Unit -#include "mozilla/Vector.h" // mozilla::Vector - -#include // size_t - -#include "jstypes.h" // JS_PUBLIC_API - -#include "js/BinASTFormat.h" // JS::BinASTFormat -#include "js/CompileOptions.h" // JS::ReadOnlyCompileOptions -#include "js/GCVector.h" // JS::GCVector -#include "js/Transcoding.h" // JS::TranscodeSource - -struct JS_PUBLIC_API JSContext; -class JS_PUBLIC_API JSScript; - -namespace JS { - -template -class SourceText; - -} // namespace JS - -namespace JS { - -class OffThreadToken; - -using OffThreadCompileCallback = void (*)(OffThreadToken* token, - void* callbackData); - -/* - * Off thread compilation control flow. - * - * After successfully triggering an off thread compile of a script, the - * callback will eventually be invoked with the specified data and a token - * for the compilation. The callback will be invoked while off thread, - * so must ensure that its operations are thread safe. Afterwards, one of the - * following functions must be invoked on the runtime's main thread: - * - * - FinishOffThreadScript, to get the result script (or nullptr on failure). - * - CancelOffThreadScript, to free the resources without creating a script. - * - * The characters passed in to CompileOffThread must remain live until the - * callback is invoked, and the resulting script will be rooted until the call - * to FinishOffThreadScript. - */ - -extern JS_PUBLIC_API bool CanCompileOffThread( - JSContext* cx, const ReadOnlyCompileOptions& options, size_t length); - -extern JS_PUBLIC_API bool CompileOffThread( - JSContext* cx, const ReadOnlyCompileOptions& options, - SourceText& srcBuf, OffThreadCompileCallback callback, - void* callbackData); - -// NOTE: Unlike for the normal sync compilation functions, this function NEVER -// INFLATES TO UTF-16. Therefore, it is ALWAYS invoking experimental -// UTF-8 support. Inflate to UTF-16 yourself and use the other overload -// if you're unable to take a risk using unstable functionality. -extern JS_PUBLIC_API bool CompileOffThread( - JSContext* cx, const ReadOnlyCompileOptions& options, - SourceText& srcBuf, OffThreadCompileCallback callback, - void* callbackData); - -extern JS_PUBLIC_API JSScript* FinishOffThreadScript(JSContext* cx, - OffThreadToken* token); - -extern JS_PUBLIC_API void CancelOffThreadScript(JSContext* cx, - OffThreadToken* token); - -extern JS_PUBLIC_API bool CompileOffThreadModule( - JSContext* cx, const ReadOnlyCompileOptions& options, - SourceText& srcBuf, OffThreadCompileCallback callback, - void* callbackData); - -// NOTE: Unlike for the normal sync compilation functions, this function NEVER -// INFLATES TO UTF-16. Therefore, it is ALWAYS invoking experimental -// UTF-8 support. Inflate to UTF-16 yourself and use the other overload -// if you're unable to take a risk using unstable functionality. -extern JS_PUBLIC_API bool CompileOffThreadModule( - JSContext* cx, const ReadOnlyCompileOptions& options, - SourceText& srcBuf, OffThreadCompileCallback callback, - void* callbackData); - -extern JS_PUBLIC_API JSObject* FinishOffThreadModule(JSContext* cx, - OffThreadToken* token); - -extern JS_PUBLIC_API void CancelOffThreadModule(JSContext* cx, - OffThreadToken* token); - -extern JS_PUBLIC_API bool CanDecodeOffThread( - JSContext* cx, const ReadOnlyCompileOptions& options, size_t length); - -extern JS_PUBLIC_API bool DecodeOffThreadScript( - JSContext* cx, const ReadOnlyCompileOptions& options, - mozilla::Vector& buffer /* TranscodeBuffer& */, size_t cursor, - OffThreadCompileCallback callback, void* callbackData); - -extern JS_PUBLIC_API bool DecodeOffThreadScript( - JSContext* cx, const ReadOnlyCompileOptions& options, - const mozilla::Range& range /* TranscodeRange& */, - OffThreadCompileCallback callback, void* callbackData); - -extern JS_PUBLIC_API JSScript* FinishOffThreadScriptDecoder( - JSContext* cx, OffThreadToken* token); - -extern JS_PUBLIC_API void CancelOffThreadScriptDecoder(JSContext* cx, - OffThreadToken* token); - -extern JS_PUBLIC_API bool DecodeMultiOffThreadScripts( - JSContext* cx, const ReadOnlyCompileOptions& options, - mozilla::Vector& sources, - OffThreadCompileCallback callback, void* callbackData); - -extern JS_PUBLIC_API bool FinishMultiOffThreadScriptsDecoder( - JSContext* cx, OffThreadToken* token, - MutableHandle> scripts); - -extern JS_PUBLIC_API void CancelMultiOffThreadScriptsDecoder( - JSContext* cx, OffThreadToken* token); - -// This returns false if built without JS_BUILD_BINAST. -extern JS_PUBLIC_API bool CanDecodeBinASTOffThread( - JSContext* cx, const ReadOnlyCompileOptions& options, size_t length); - -// This throws an exception if built without JS_BUILD_BINAST. -extern JS_PUBLIC_API bool DecodeBinASTOffThread( - JSContext* cx, const ReadOnlyCompileOptions& options, const uint8_t* buf, - size_t length, JS::BinASTFormat format, OffThreadCompileCallback callback, - void* callbackData); - -// This throws an exception if built without JS_BUILD_BINAST. -extern JS_PUBLIC_API JSScript* FinishOffThreadBinASTDecode( - JSContext* cx, OffThreadToken* token); - -} // namespace JS - -#endif /* js_OffThreadScriptCompilation_h */ Index: libraries/source/spidermonkey/include-win32-debug/js/Principals.h =================================================================== --- /dev/null +++ libraries/source/spidermonkey/include-win32-debug/js/Principals.h @@ -1,160 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- - * vim: set ts=8 sts=2 et sw=2 tw=80: - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* JSPrincipals and related interfaces. */ - -#ifndef js_Principals_h -#define js_Principals_h - -#include "mozilla/Atomics.h" - -#include - -#include "jspubtd.h" - -struct JSStructuredCloneReader; -struct JSStructuredCloneWriter; - -struct JSPrincipals { - /* Don't call "destroy"; use reference counting macros below. */ - mozilla::Atomic refcount{0}; - -#ifdef JS_DEBUG - /* A helper to facilitate principals debugging. */ - uint32_t debugToken; -#endif - - JSPrincipals() = default; - - void setDebugToken(uint32_t token) { -#ifdef JS_DEBUG - debugToken = token; -#endif - } - - /* - * Write the principals with the given |writer|. Return false on failure, - * true on success. - */ - virtual bool write(JSContext* cx, JSStructuredCloneWriter* writer) = 0; - - /* - * Whether the principal corresponds to a System or AddOn Principal. - * Technically this also checks for an ExpandedAddonPrincipal. - */ - virtual bool isSystemOrAddonPrincipal() = 0; - - /* - * This is not defined by the JS engine but should be provided by the - * embedding. - */ - JS_PUBLIC_API void dump(); -}; - -extern JS_PUBLIC_API void JS_HoldPrincipals(JSPrincipals* principals); - -extern JS_PUBLIC_API void JS_DropPrincipals(JSContext* cx, - JSPrincipals* principals); - -// Return whether the first principal subsumes the second. The exact meaning of -// 'subsumes' is left up to the browser. Subsumption is checked inside the JS -// engine when determining, e.g., which stack frames to display in a backtrace. -typedef bool (*JSSubsumesOp)(JSPrincipals* first, JSPrincipals* second); - -/* - * Used to check if a CSP instance wants to disable eval() and friends. - * See GlobalObject::isRuntimeCodeGenEnabled() in vm/GlobalObject.cpp. - */ -typedef bool (*JSCSPEvalChecker)(JSContext* cx, JS::HandleString code); - -struct JSSecurityCallbacks { - JSCSPEvalChecker contentSecurityPolicyAllows; - JSSubsumesOp subsumes; -}; - -extern JS_PUBLIC_API void JS_SetSecurityCallbacks( - JSContext* cx, const JSSecurityCallbacks* callbacks); - -extern JS_PUBLIC_API const JSSecurityCallbacks* JS_GetSecurityCallbacks( - JSContext* cx); - -/* - * Code running with "trusted" principals will be given a deeper stack - * allocation than ordinary scripts. This allows trusted script to run after - * untrusted script has exhausted the stack. This function sets the - * runtime-wide trusted principal. - * - * This principals is not held (via JS_HoldPrincipals/JS_DropPrincipals). - * Instead, the caller must ensure that the given principals stays valid for as - * long as 'cx' may point to it. If the principals would be destroyed before - * 'cx', JS_SetTrustedPrincipals must be called again, passing nullptr for - * 'prin'. - */ -extern JS_PUBLIC_API void JS_SetTrustedPrincipals(JSContext* cx, - JSPrincipals* prin); - -typedef void (*JSDestroyPrincipalsOp)(JSPrincipals* principals); - -/* - * Initialize the callback that is called to destroy JSPrincipals instance - * when its reference counter drops to zero. The initialization can be done - * only once per JS runtime. - */ -extern JS_PUBLIC_API void JS_InitDestroyPrincipalsCallback( - JSContext* cx, JSDestroyPrincipalsOp destroyPrincipals); - -/* - * Read a JSPrincipals instance from the given |reader| and initialize the out - * paratemer |outPrincipals| to the JSPrincipals instance read. - * - * Return false on failure, true on success. The |outPrincipals| parameter - * should not be modified if false is returned. - * - * The caller is not responsible for calling JS_HoldPrincipals on the resulting - * JSPrincipals instance, the JSReadPrincipalsOp must increment the refcount of - * the resulting JSPrincipals on behalf of the caller. - */ -using JSReadPrincipalsOp = bool (*)(JSContext* cx, - JSStructuredCloneReader* reader, - JSPrincipals** outPrincipals); - -/* - * Initialize the callback that is called to read JSPrincipals instances from a - * buffer. The initialization can be done only once per JS runtime. - */ -extern JS_PUBLIC_API void JS_InitReadPrincipalsCallback( - JSContext* cx, JSReadPrincipalsOp read); - -namespace JS { - -class MOZ_RAII AutoHoldPrincipals { - JSContext* cx_; - JSPrincipals* principals_ = nullptr; - - public: - explicit AutoHoldPrincipals(JSContext* cx, JSPrincipals* principals = nullptr) - : cx_(cx) { - reset(principals); - } - - ~AutoHoldPrincipals() { reset(nullptr); } - - void reset(JSPrincipals* principals) { - if (principals) { - JS_HoldPrincipals(principals); - } - if (principals_) { - JS_DropPrincipals(cx_, principals_); - } - principals_ = principals; - } - - JSPrincipals* get() const { return principals_; } -}; - -} // namespace JS - -#endif /* js_Principals_h */ Index: libraries/source/spidermonkey/include-win32-debug/js/Printf.h =================================================================== --- /dev/null +++ libraries/source/spidermonkey/include-win32-debug/js/Printf.h @@ -1,34 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- - * vim: set ts=8 sts=2 et sw=2 tw=80: - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef js_Printf_h -#define js_Printf_h - -#include "mozilla/Printf.h" - -#include - -#include "jstypes.h" -#include "js/Utility.h" - -/* Wrappers for mozilla::Smprintf and friends that are used throughout - JS. */ - -extern JS_PUBLIC_API JS::UniqueChars JS_smprintf(const char* fmt, ...) - MOZ_FORMAT_PRINTF(1, 2); - -extern JS_PUBLIC_API JS::UniqueChars JS_sprintf_append(JS::UniqueChars&& last, - const char* fmt, ...) - MOZ_FORMAT_PRINTF(2, 3); - -extern JS_PUBLIC_API JS::UniqueChars JS_vsmprintf(const char* fmt, va_list ap) - MOZ_FORMAT_PRINTF(1, 0); -extern JS_PUBLIC_API JS::UniqueChars JS_vsprintf_append(JS::UniqueChars&& last, - const char* fmt, - va_list ap) - MOZ_FORMAT_PRINTF(2, 0); - -#endif /* js_Printf_h */ Index: libraries/source/spidermonkey/include-win32-debug/js/ProfilingCategory.h =================================================================== --- /dev/null +++ libraries/source/spidermonkey/include-win32-debug/js/ProfilingCategory.h @@ -1,149 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=8 sts=4 et sw=4 tw=99: - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef js_ProfilingCategory_h -#define js_ProfilingCategory_h - -#include "jstypes.h" // JS_FRIEND_API - -// clang-format off - -// This higher-order macro lists all categories with their subcategories. -// -// PROFILING_CATEGORY_LIST(BEGIN_CATEGORY, SUBCATEGORY, END_CATEGORY) -// BEGIN_CATEGORY(name, labelAsString, colorAsString) -// SUBCATEGORY(category, name, labelAsString) -// END_CATEGORY -// -// The list of available color names for categories is: -// transparent, grey, purple, yellow, orange, lightblue, green, blue, magenta -// -// Categories and subcategories are used for stack-based instrumentation. They -// are specified in label frames in the profiling stack, see ProfilingStack.h. -// At any point, the category pair of the topmost profiler label frame in the -// label stack determines the category pair of that stack. -// Each category describes a type of workload that the CPU can be busy with. -// Categories should be non-overlapping: the list of categories should be -// chosen in such a way that every possible stack can be mapped to a single -// category unambiguously. - -#define PROFILING_CATEGORY_LIST(BEGIN_CATEGORY, SUBCATEGORY, END_CATEGORY) \ - BEGIN_CATEGORY(IDLE, "Idle", "transparent") \ - SUBCATEGORY(IDLE, IDLE, "Other") \ - END_CATEGORY \ - BEGIN_CATEGORY(OTHER, "Other", "grey") \ - SUBCATEGORY(OTHER, OTHER_PreferenceRead, "Preference Read") \ - SUBCATEGORY(OTHER, OTHER, "Other") \ - END_CATEGORY \ - BEGIN_CATEGORY(LAYOUT, "Layout", "purple") \ - SUBCATEGORY(LAYOUT, LAYOUT, "Other") \ - SUBCATEGORY(LAYOUT, LAYOUT_FrameConstruction, "Frame construction") \ - SUBCATEGORY(LAYOUT, LAYOUT_Reflow, "Reflow") \ - SUBCATEGORY(LAYOUT, LAYOUT_CSSParsing, "CSS parsing") \ - SUBCATEGORY(LAYOUT, LAYOUT_SelectorQuery, "Selector query") \ - SUBCATEGORY(LAYOUT, LAYOUT_StyleComputation, "Style computation") \ - END_CATEGORY \ - BEGIN_CATEGORY(JS, "JavaScript", "yellow") \ - SUBCATEGORY(JS, JS, "Other") \ - SUBCATEGORY(JS, JS_Parsing, "JS Parsing") \ - SUBCATEGORY(JS, JS_IonCompilation, "Ion JIT Compilation") \ - SUBCATEGORY(JS, JS_BaselineCompilation, "Baseline JIT Compilation") \ - END_CATEGORY \ - BEGIN_CATEGORY(GCCC, "GC / CC", "orange") \ - SUBCATEGORY(GCCC, GCCC, "Other") \ - END_CATEGORY \ - BEGIN_CATEGORY(NETWORK, "Network", "lightblue") \ - SUBCATEGORY(NETWORK, NETWORK, "Other") \ - END_CATEGORY \ - BEGIN_CATEGORY(GRAPHICS, "Graphics", "green") \ - SUBCATEGORY(GRAPHICS, GRAPHICS, "Other") \ - SUBCATEGORY(GRAPHICS, GRAPHICS_DisplayListBuilding, "DisplayList building") \ - SUBCATEGORY(GRAPHICS, GRAPHICS_DisplayListMerging, "DisplayList merging") \ - SUBCATEGORY(GRAPHICS, GRAPHICS_LayerBuilding, "Layer building") \ - SUBCATEGORY(GRAPHICS, GRAPHICS_TileAllocation, "Tile allocation") \ - SUBCATEGORY(GRAPHICS, GRAPHICS_WRDisplayList, "WebRender display list") \ - SUBCATEGORY(GRAPHICS, GRAPHICS_Rasterization, "Rasterization") \ - SUBCATEGORY(GRAPHICS, GRAPHICS_FlushingAsyncPaints, "Flushing async paints") \ - SUBCATEGORY(GRAPHICS, GRAPHICS_ImageDecoding, "Image decoding") \ - END_CATEGORY \ - BEGIN_CATEGORY(DOM, "DOM", "blue") \ - SUBCATEGORY(DOM, DOM, "Other") \ - END_CATEGORY \ - BEGIN_CATEGORY(JAVA_ANDROID, "Android", "yellow") \ - SUBCATEGORY(JAVA_ANDROID, JAVA_ANDROID, "Other") \ - END_CATEGORY \ - BEGIN_CATEGORY(JAVA_ANDROIDX, "AndroidX", "orange") \ - SUBCATEGORY(JAVA_ANDROIDX, JAVA_ANDROIDX, "Other") \ - END_CATEGORY \ - BEGIN_CATEGORY(JAVA_LANGUAGE, "Java", "blue") \ - SUBCATEGORY(JAVA_LANGUAGE, JAVA_LANGUAGE, "Other") \ - END_CATEGORY \ - BEGIN_CATEGORY(JAVA_MOZILLA, "Mozilla", "green") \ - SUBCATEGORY(JAVA_MOZILLA, JAVA_MOZILLA, "Other") \ - END_CATEGORY \ - BEGIN_CATEGORY(JAVA_KOTLIN, "Kotlin", "purple") \ - SUBCATEGORY(JAVA_KOTLIN, JAVA_KOTLIN, "Other") \ - END_CATEGORY \ - BEGIN_CATEGORY(JAVA_BLOCKED, "Blocked", "lightblue") \ - SUBCATEGORY(JAVA_BLOCKED, JAVA_BLOCKED, "Other") \ - END_CATEGORY \ - BEGIN_CATEGORY(IPC, "IPC", "lightgreen") \ - SUBCATEGORY(IPC, IPC, "Other") \ - END_CATEGORY \ - BEGIN_CATEGORY(MEDIA, "Media", "orange") \ - SUBCATEGORY(MEDIA, MEDIA_CUBEB, "Cubeb") \ - SUBCATEGORY(MEDIA, MEDIA_PLAYBACK, "Playback") \ - END_CATEGORY - -namespace JS { - -// An enum that lists all possible category pairs in one list. -// This is the enum that is used in profiler stack labels. Having one list that -// includes subcategories from all categories in one list allows assigning the -// category pair to a stack label with just one number. -#define CATEGORY_ENUM_BEGIN_CATEGORY(name, labelAsString, color) -#define CATEGORY_ENUM_SUBCATEGORY(supercategory, name, labelAsString) name, -#define CATEGORY_ENUM_END_CATEGORY -enum class ProfilingCategoryPair : uint32_t { - PROFILING_CATEGORY_LIST(CATEGORY_ENUM_BEGIN_CATEGORY, - CATEGORY_ENUM_SUBCATEGORY, - CATEGORY_ENUM_END_CATEGORY) - COUNT, - LAST = COUNT - 1, -}; -#undef CATEGORY_ENUM_BEGIN_CATEGORY -#undef CATEGORY_ENUM_SUBCATEGORY -#undef CATEGORY_ENUM_END_CATEGORY - -// An enum that lists just the categories without their subcategories. -#define SUPERCATEGORY_ENUM_BEGIN_CATEGORY(name, labelAsString, color) name, -#define SUPERCATEGORY_ENUM_SUBCATEGORY(supercategory, name, labelAsString) -#define SUPERCATEGORY_ENUM_END_CATEGORY -enum class ProfilingCategory : uint32_t { - PROFILING_CATEGORY_LIST(SUPERCATEGORY_ENUM_BEGIN_CATEGORY, - SUPERCATEGORY_ENUM_SUBCATEGORY, - SUPERCATEGORY_ENUM_END_CATEGORY) - COUNT, - LAST = COUNT - 1, -}; -#undef SUPERCATEGORY_ENUM_BEGIN_CATEGORY -#undef SUPERCATEGORY_ENUM_SUBCATEGORY -#undef SUPERCATEGORY_ENUM_END_CATEGORY - -// clang-format on - -struct ProfilingCategoryPairInfo { - ProfilingCategory mCategory; - uint32_t mSubcategoryIndex; - const char* mLabel; -}; - -JS_FRIEND_API const ProfilingCategoryPairInfo& GetProfilingCategoryPairInfo( - ProfilingCategoryPair aCategoryPair); - -} // namespace JS - -#endif /* js_ProfilingCategory_h */ Index: libraries/source/spidermonkey/include-win32-debug/js/ProfilingFrameIterator.h =================================================================== --- /dev/null +++ libraries/source/spidermonkey/include-win32-debug/js/ProfilingFrameIterator.h @@ -1,240 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- - * vim: set ts=8 sts=2 et sw=2 tw=80: - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef js_ProfilingFrameIterator_h -#define js_ProfilingFrameIterator_h - -#include "mozilla/Attributes.h" -#include "mozilla/Maybe.h" - -#include "js/GCAPI.h" -#include "js/TypeDecls.h" -#include "js/Utility.h" - -namespace js { -class Activation; -namespace jit { -class JitActivation; -class JSJitProfilingFrameIterator; -class JitcodeGlobalEntry; -} // namespace jit -namespace wasm { -class ProfilingFrameIterator; -} // namespace wasm -} // namespace js - -namespace JS { - -// This iterator can be used to walk the stack of a thread suspended at an -// arbitrary pc. To provide accurate results, profiling must have been enabled -// (via EnableRuntimeProfilingStack) before executing the callstack being -// unwound. -// -// Note that the caller must not do anything that could cause GC to happen while -// the iterator is alive, since this could invalidate Ion code and cause its -// contents to become out of date. -class MOZ_NON_PARAM JS_PUBLIC_API ProfilingFrameIterator { - public: - enum class Kind : bool { JSJit, Wasm }; - - private: - JSContext* cx_; - mozilla::Maybe samplePositionInProfilerBuffer_; - js::Activation* activation_; - Kind kind_; - - static const unsigned StorageSpace = 8 * sizeof(void*); - alignas(void*) unsigned char storage_[StorageSpace]; - - void* storage() { return storage_; } - const void* storage() const { return storage_; } - - js::wasm::ProfilingFrameIterator& wasmIter() { - MOZ_ASSERT(!done()); - MOZ_ASSERT(isWasm()); - return *static_cast(storage()); - } - const js::wasm::ProfilingFrameIterator& wasmIter() const { - MOZ_ASSERT(!done()); - MOZ_ASSERT(isWasm()); - return *static_cast(storage()); - } - - js::jit::JSJitProfilingFrameIterator& jsJitIter() { - MOZ_ASSERT(!done()); - MOZ_ASSERT(isJSJit()); - return *static_cast(storage()); - } - - const js::jit::JSJitProfilingFrameIterator& jsJitIter() const { - MOZ_ASSERT(!done()); - MOZ_ASSERT(isJSJit()); - return *static_cast(storage()); - } - - void settleFrames(); - void settle(); - - public: - struct RegisterState { - RegisterState() : pc(nullptr), sp(nullptr), fp(nullptr), lr(nullptr) {} - void* pc; - void* sp; - void* fp; - void* lr; - }; - - ProfilingFrameIterator( - JSContext* cx, const RegisterState& state, - const mozilla::Maybe& samplePositionInProfilerBuffer = - mozilla::Nothing()); - ~ProfilingFrameIterator(); - void operator++(); - bool done() const { return !activation_; } - - // Assuming the stack grows down (we do), the return value: - // - always points into the stack - // - is weakly monotonically increasing (may be equal for successive frames) - // - will compare greater than newer native and psuedo-stack frame addresses - // and less than older native and psuedo-stack frame addresses - void* stackAddress() const; - - enum FrameKind { - Frame_BaselineInterpreter, - Frame_Baseline, - Frame_Ion, - Frame_Wasm - }; - - struct Frame { - FrameKind kind; - void* stackAddress; - union { - void* returnAddress_; - jsbytecode* interpreterPC_; - }; - void* activation; - void* endStackAddress; - const char* label; - JSScript* interpreterScript; - uint64_t realmID; - - public: - void* returnAddress() const { - MOZ_ASSERT(kind != Frame_BaselineInterpreter); - return returnAddress_; - } - jsbytecode* interpreterPC() const { - MOZ_ASSERT(kind == Frame_BaselineInterpreter); - return interpreterPC_; - } - } JS_HAZ_GC_INVALIDATED; - - bool isWasm() const; - bool isJSJit() const; - - uint32_t extractStack(Frame* frames, uint32_t offset, uint32_t end) const; - - mozilla::Maybe getPhysicalFrameWithoutLabel() const; - - private: - mozilla::Maybe getPhysicalFrameAndEntry( - js::jit::JitcodeGlobalEntry* entry) const; - - void iteratorConstruct(const RegisterState& state); - void iteratorConstruct(); - void iteratorDestroy(); - bool iteratorDone(); -} JS_HAZ_GC_INVALIDATED; - -JS_FRIEND_API bool IsProfilingEnabledForContext(JSContext* cx); - -/** - * After each sample run, this method should be called with the current buffer - * position at which the buffer contents start. This will update the - * corresponding field on the JSRuntime. - * - * See the field |profilerSampleBufferRangeStart| on JSRuntime for documentation - * about what this value is used for. - */ -JS_FRIEND_API void SetJSContextProfilerSampleBufferRangeStart( - JSContext* cx, uint64_t rangeStart); - -class ProfiledFrameRange; - -// A handle to the underlying JitcodeGlobalEntry, so as to avoid repeated -// lookups on JitcodeGlobalTable. -class MOZ_STACK_CLASS ProfiledFrameHandle { - friend class ProfiledFrameRange; - - JSRuntime* rt_; - js::jit::JitcodeGlobalEntry& entry_; - void* addr_; - void* canonicalAddr_; - const char* label_; - uint32_t depth_; - - ProfiledFrameHandle(JSRuntime* rt, js::jit::JitcodeGlobalEntry& entry, - void* addr, const char* label, uint32_t depth); - - public: - const char* label() const { return label_; } - uint32_t depth() const { return depth_; } - void* canonicalAddress() const { return canonicalAddr_; } - - JS_PUBLIC_API ProfilingFrameIterator::FrameKind frameKind() const; - - JS_PUBLIC_API uint64_t realmID() const; -}; - -class ProfiledFrameRange { - public: - class Iter final { - public: - Iter(const ProfiledFrameRange& range, uint32_t index) - : range_(range), index_(index) {} - - JS_PUBLIC_API ProfiledFrameHandle operator*() const; - - // Provide the bare minimum of iterator methods that are needed for - // C++ ranged for loops. - Iter& operator++() { - ++index_; - return *this; - } - bool operator==(const Iter& rhs) { return index_ == rhs.index_; } - bool operator!=(const Iter& rhs) { return !(*this == rhs); } - - private: - const ProfiledFrameRange& range_; - uint32_t index_; - }; - - Iter begin() const { return Iter(*this, 0); } - Iter end() const { return Iter(*this, depth_); } - - private: - friend JS_PUBLIC_API ProfiledFrameRange GetProfiledFrames(JSContext* cx, - void* addr); - - ProfiledFrameRange(JSRuntime* rt, void* addr, - js::jit::JitcodeGlobalEntry* entry) - : rt_(rt), addr_(addr), entry_(entry), depth_(0) {} - - JSRuntime* rt_; - void* addr_; - js::jit::JitcodeGlobalEntry* entry_; - // Assume maximum inlining depth is <64 - const char* labels_[64]; - uint32_t depth_; -}; - -// Returns a range that can be iterated over using C++ ranged for loops. -JS_PUBLIC_API ProfiledFrameRange GetProfiledFrames(JSContext* cx, void* addr); - -} // namespace JS - -#endif /* js_ProfilingFrameIterator_h */ Index: libraries/source/spidermonkey/include-win32-debug/js/ProfilingStack.h =================================================================== --- /dev/null +++ libraries/source/spidermonkey/include-win32-debug/js/ProfilingStack.h @@ -1,560 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- - * vim: set ts=8 sts=2 et sw=2 tw=80: - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef js_ProfilingStack_h -#define js_ProfilingStack_h - -#include -#include - -#include "jstypes.h" - -#include "js/ProfilingCategory.h" -#include "js/TypeDecls.h" -#include "js/Utility.h" - -class JS_PUBLIC_API JSTracer; -class JS_FRIEND_API ProfilingStack; - -// This file defines the classes ProfilingStack and ProfilingStackFrame. -// The ProfilingStack manages an array of ProfilingStackFrames. -// It keeps track of the "label stack" and the JS interpreter stack. -// The two stack types are interleaved. -// -// Usage: -// -// ProfilingStack* profilingStack = ...; -// -// // For label frames: -// profilingStack->pushLabelFrame(...); -// // Execute some code. When finished, pop the frame: -// profilingStack->pop(); -// -// // For JS stack frames: -// profilingStack->pushJSFrame(...); -// // Execute some code. When finished, pop the frame: -// profilingStack->pop(); -// -// -// Concurrency considerations -// -// A thread's profiling stack (and the frames inside it) is only modified by -// that thread. However, the profiling stack can be *read* by a different -// thread, the sampler thread: Whenever the profiler wants to sample a given -// thread A, the following happens: -// (1) Thread A is suspended. -// (2) The sampler thread (thread S) reads the ProfilingStack of thread A, -// including all ProfilingStackFrames that are currently in that stack -// (profilingStack->frames[0..profilingStack->stackSize()]). -// (3) Thread A is resumed. -// -// Thread suspension is achieved using platform-specific APIs; refer to each -// platform's Sampler::SuspendAndSampleAndResumeThread implementation in -// platform-*.cpp for details. -// -// When the thread is suspended, the values in profilingStack->stackPointer and -// in the stack frame range -// profilingStack->frames[0..profilingStack->stackPointer] need to be in a -// consistent state, so that thread S does not read partially- constructed stack -// frames. More specifically, we have two requirements: -// (1) When adding a new frame at the top of the stack, its ProfilingStackFrame -// data needs to be put in place *before* the stackPointer is incremented, -// and the compiler + CPU need to know that this order matters. -// (2) When popping an frame from the stack and then preparing the -// ProfilingStackFrame data for the next frame that is about to be pushed, -// the decrement of the stackPointer in pop() needs to happen *before* the -// ProfilingStackFrame for the new frame is being popuplated, and the -// compiler + CPU need to know that this order matters. -// -// We can express the relevance of these orderings in multiple ways. -// Option A is to make stackPointer an atomic with SequentiallyConsistent -// memory ordering. This would ensure that no writes in thread A would be -// reordered across any writes to stackPointer, which satisfies requirements -// (1) and (2) at the same time. Option A is the simplest. -// Option B is to use ReleaseAcquire memory ordering both for writes to -// stackPointer *and* for writes to ProfilingStackFrame fields. Release-stores -// ensure that all writes that happened *before this write in program order* are -// not reordered to happen after this write. ReleaseAcquire ordering places no -// requirements on the ordering of writes that happen *after* this write in -// program order. -// Using release-stores for writes to stackPointer expresses requirement (1), -// and using release-stores for writes to the ProfilingStackFrame fields -// expresses requirement (2). -// -// Option B is more complicated than option A, but has much better performance -// on x86/64: In a microbenchmark run on a Macbook Pro from 2017, switching -// from option A to option B reduced the overhead of pushing+popping a -// ProfilingStackFrame by 10 nanoseconds. -// On x86/64, release-stores require no explicit hardware barriers or lock -// instructions. -// On ARM/64, option B may be slower than option A, because the compiler will -// generate hardware barriers for every single release-store instead of just -// for the writes to stackPointer. However, the actual performance impact of -// this has not yet been measured on ARM, so we're currently using option B -// everywhere. This is something that we may want to change in the future once -// we've done measurements. - -namespace js { - -// A call stack can be specified to the JS engine such that all JS entry/exits -// to functions push/pop a stack frame to/from the specified stack. -// -// For more detailed information, see vm/GeckoProfiler.h. -// -class ProfilingStackFrame { - // A ProfilingStackFrame represents either a label frame or a JS frame. - - // WARNING WARNING WARNING - // - // All the fields below are Atomic<...,ReleaseAcquire>. This is needed so - // that writes to these fields are release-writes, which ensures that - // earlier writes in this thread don't get reordered after the writes to - // these fields. In particular, the decrement of the stack pointer in - // ProfilingStack::pop() is a write that *must* happen before the values in - // this ProfilingStackFrame are changed. Otherwise, the sampler thread might - // see an inconsistent state where the stack pointer still points to a - // ProfilingStackFrame which has already been popped off the stack and whose - // fields have now been partially repopulated with new values. - // See the "Concurrency considerations" paragraph at the top of this file - // for more details. - - // Descriptive label for this stack frame. Must be a static string! Can be - // an empty string, but not a null pointer. - mozilla::Atomic label_; - - // An additional descriptive string of this frame which is combined with - // |label_| in profiler output. Need not be (and usually isn't) static. Can - // be null. - mozilla::Atomic dynamicString_; - - // Stack pointer for non-JS stack frames, the script pointer otherwise. - mozilla::Atomic spOrScript; - - // The bytecode offset for JS stack frames. - // Must not be used on non-JS frames; it'll contain either the default 0, - // or a leftover value from a previous JS stack frame that was using this - // ProfilingStackFrame object. - mozilla::Atomic pcOffsetIfJS_; - - // ID of the JS Realm for JS stack frames. - // Must not be used on non-JS frames; it'll contain either the default 0, - // or a leftover value from a previous JS stack frame that was using this - // ProfilingStackFrame object. - mozilla::Atomic realmID_; - - // Bits 0...8 hold the Flags. Bits 9...31 hold the category pair. - mozilla::Atomic flagsAndCategoryPair_; - - static int32_t pcToOffset(JSScript* aScript, jsbytecode* aPc); - - public: - ProfilingStackFrame() = default; - ProfilingStackFrame& operator=(const ProfilingStackFrame& other) { - label_ = other.label(); - dynamicString_ = other.dynamicString(); - void* spScript = other.spOrScript; - spOrScript = spScript; - int32_t offsetIfJS = other.pcOffsetIfJS_; - pcOffsetIfJS_ = offsetIfJS; - uint64_t realmID = other.realmID_; - realmID_ = realmID; - uint32_t flagsAndCategory = other.flagsAndCategoryPair_; - flagsAndCategoryPair_ = flagsAndCategory; - return *this; - } - - // 9 bits for the flags. - // That leaves 32 - 9 = 23 bits for the category pair. - enum class Flags : uint32_t { - // The first three flags describe the kind of the frame and are - // mutually exclusive. (We still give them individual bits for - // simplicity.) - - // A regular label frame. These usually come from AutoProfilerLabel. - IS_LABEL_FRAME = 1 << 0, - - // A special frame indicating the start of a run of JS profiling stack - // frames. IS_SP_MARKER_FRAME frames are ignored, except for the sp - // field. These frames are needed to get correct ordering between JS - // and LABEL frames because JS frames don't carry sp information. - // SP is short for "stack pointer". - IS_SP_MARKER_FRAME = 1 << 1, - - // A JS frame. - IS_JS_FRAME = 1 << 2, - - // An interpreter JS frame that has OSR-ed into baseline. IS_JS_FRAME - // frames can have this flag set and unset during their lifetime. - // JS_OSR frames are ignored. - JS_OSR = 1 << 3, - - // The next three are mutually exclusive. - // By default, for profiling stack frames that have both a label and a - // dynamic string, the two strings are combined into one string of the - // form "